From c6028271635dac56372a6f3e65aa7f731a775339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 12:11:43 +0200 Subject: [PATCH 1/7] fix: use new provisioning profile directory for lookup --- index.js | 2 +- lib/provisioning.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 7e31c4b..c66b04c 100644 --- a/index.js +++ b/index.js @@ -34,7 +34,7 @@ exports.findValidDeviceCertProfileCombos = findValidDeviceCertProfileCombos; * @param {Boolean} [options.bypassCache=false] - When true, re-detects the all iOS information. * @param {String} [options.minIosVersion] - The minimum iOS SDK to detect. * @param {String} [options.minWatchosVersion] - The minimum WatchOS SDK to detect. - * @param {String} [options.profileDir=~/Library/MobileDevice/Provisioning Profiles] - The path to search for provisioning profiles. + * @param {String} [options.profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to search for provisioning profiles. * @param {String} [options.security] - Path to the security executable * @param {String} [options.supportedVersions] - A string with a version number or range to check if an Xcode install is supported. * @param {String} [options.type] - The type of emulators to return. Can be either "iphone" or "ipad". Defaults to all types. diff --git a/lib/provisioning.js b/lib/provisioning.js index 28b09de..000cce4 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -20,7 +20,7 @@ const fs = require('fs'), path = require('path'), __ = appc.i18n(__dirname).__, - defaultProfileDir = '~/Library/MobileDevice/Provisioning Profiles'; + defaultProfileDir = '~/Library/Developer/Xcode/UserData/Provisioning Profiles'; var cache = null, watchers = {}; @@ -48,7 +48,7 @@ exports.unwatch = unwatch; * * @param {Object} [options] - An object containing various settings. * @param {Boolean} [options.bypassCache=false] - When true, re-detects all provisioning profiles. - * @param {String} [options.profileDir=~/Library/MobileDevice/Provisioning Profiles] - The path to search for provisioning profiles. + * @param {String} [options.profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to search for provisioning profiles. * @param {Boolean} [options.unmanaged] - When true, excludes managed provisioning profiles. * @param {Boolean} [options.validOnly=true] - When true, only returns non-expired, valid provisioning profiles. * @param {Boolean} [options.watch=false] - If true, watches the specified provisioning profile directory for updates. @@ -332,7 +332,7 @@ function find(options, callback) { * Watches a provisioning profile directory for file changes. * * @param {Object} [options] - An object containing various settings. - * @param {String} [options.profileDir=~/Library/MobileDevice/Provisioning Profiles] - The path to search for provisioning profiles. + * @param {String} [options.profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to search for provisioning profiles. * @param {Function} [callback(err, results)] - A function to call with the provisioning profile information. * * @returns {Function} A function that unwatches changes. @@ -358,7 +358,7 @@ function watch(options, callback) { /** * Stops watching the specified provisioning profile directory. * - * @param {String} [profileDir=~/Library/MobileDevice/Provisioning Profiles] - The path to the provisioning profile directory. + * @param {String} [profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to the provisioning profile directory. */ function unwatch(profileDir) { var profileDir = appc.fs.resolvePath(profileDir || defaultProfileDir); From 9915ac8088c49523c1d510eea69675a6c7366a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 12:40:27 +0200 Subject: [PATCH 2/7] chore: handle multiple directories --- lib/provisioning.js | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/provisioning.js b/lib/provisioning.js index 000cce4..eff6df4 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -20,7 +20,10 @@ const fs = require('fs'), path = require('path'), __ = appc.i18n(__dirname).__, - defaultProfileDir = '~/Library/Developer/Xcode/UserData/Provisioning Profiles'; + provisioningProfilesDirectories = [ + '~/Library/Developer/Xcode/UserData/Provisioning Profiles', + '~/Library/MobileDevice/Provisioning Profiles' + ] var cache = null, watchers = {}; @@ -37,7 +40,7 @@ var cache = null, * @type {Error} */ -exports.defaultProfileDir = defaultProfileDir; +exports.provisioningProfilesDirectories = provisioningProfilesDirectories; exports.detect = detect; exports.find = find; exports.watch = watch; @@ -63,7 +66,7 @@ function detect(options, callback) { return magik(options, callback, function (emitter, options, callback) { var files = {}, validOnly = options.validOnly === undefined || options.validOnly === true, - profileDir = appc.fs.resolvePath(options.profileDir || defaultProfileDir), + profileDir = getPrimaryProvisioningProfileDirectory(options.profileDir), results = { provisioning: { profileDir: profileDir, @@ -361,7 +364,7 @@ function watch(options, callback) { * @param {String} [profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to the provisioning profile directory. */ function unwatch(profileDir) { - var profileDir = appc.fs.resolvePath(profileDir || defaultProfileDir); + var profileDir = getPrimaryProvisioningProfileDirectory(profileDir); if (!watchers[profileDir]) return; @@ -371,6 +374,29 @@ function unwatch(profileDir) { } }; +/** + * Searches for existing provisioning profile directories. + * + * @throws + * @param {string | undefined} profileDir A custom directory set by the developer. + * @returns {string | undefined} Either a matching directory or `undefined`, if directory could be found. + */ +function getPrimaryProvisioningProfileDirectory(profileDir) { + if (profileDir) { + return appc.fs.resolvePath(profileDir); + } + + for (const directory of provisioningProfilesDirectories) { + const resolvedDirectory = appc.fs.resolvePath(directory); + + if (fs.existsSync(resolvedDirectory)) { + return resolvedDirectory; + } + } + + return undefined; +} + /* * If the app exits, close all filesystem watchers. */ From 2fb812cf4d18cc19cfadbc006167b5a0c9728fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 23:15:30 +0200 Subject: [PATCH 3/7] refactor: be able to grab profiles from multiple destinations --- lib/provisioning.js | 111 ++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/lib/provisioning.js b/lib/provisioning.js index eff6df4..c8160be 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -40,7 +40,6 @@ var cache = null, * @type {Error} */ -exports.provisioningProfilesDirectories = provisioningProfilesDirectories; exports.detect = detect; exports.find = find; exports.watch = watch; @@ -66,7 +65,7 @@ function detect(options, callback) { return magik(options, callback, function (emitter, options, callback) { var files = {}, validOnly = options.validOnly === undefined || options.validOnly === true, - profileDir = getPrimaryProvisioningProfileDirectory(options.profileDir), + profileDirs = getExistingProvisioningProfileDirectories(options.profileDir), results = { provisioning: { profileDir: profileDir, @@ -90,46 +89,48 @@ function detect(options, callback) { if (options.watch) { var throttleTimer = null; - if (!watchers[profileDir]) { - watchers[profileDir] = { - handle: fs.watch(profileDir, { persistent: false }, function (event, filename) { - if (!ppRegExp.test(filename)) { - // if it's not a provisioning profile, we don't care about it - return; - } - - var file = path.join(profileDir, filename); - - if (event === 'rename') { - if (files[file]) { - if (fs.existsSync(file)) { - // change, reload the provisioning profile - parseProfile(file); + for (const profileDir of profileDirs) { + if (!watchers[profileDir]) { + watchers[profileDir] = { + handle: fs.watch(profileDir, { persistent: false }, function (event, filename) { + if (!ppRegExp.test(filename)) { + // if it's not a provisioning profile, we don't care about it + return; + } + + var file = path.join(profileDir, filename); + + if (event === 'rename') { + if (files[file]) { + if (fs.existsSync(file)) { + // change, reload the provisioning profile + parseProfile(file); + } else { + // delete + removeProfile(file); + } } else { - // delete - removeProfile(file); + // add + parseProfile(file); } - } else { - // add + } else if (event === 'change') { + // updated parseProfile(file); } - } else if (event === 'change') { - // updated - parseProfile(file); - } - - clearTimeout(throttleTimer); - - throttleTimer = setTimeout(function () { - detectIssues(); - emitter.emit('detected', results); - }, 250); - }), - count: 0 - }; + + clearTimeout(throttleTimer); + + throttleTimer = setTimeout(function () { + detectIssues(); + emitter.emit('detected', results); + }, 250); + }), + count: 0 + }; + } + + watchers[profileDir].count++; } - - watchers[profileDir].count++; } if (cache && !options.bypassCache) { @@ -248,8 +249,8 @@ function detect(options, callback) { } } - fs.exists(profileDir, function (exists) { - exists && fs.readdirSync(profileDir).forEach(function (name) { + for (const profileDir of profileDirs) { + fs.readdirSync(profileDir).forEach(function (name) { ppRegExp.test(name) && parseProfile(path.join(profileDir, name)); }); @@ -257,7 +258,7 @@ function detect(options, callback) { cache = results; emitter.emit('detected', results); return callback(null, results); - }); + } }); }; @@ -364,13 +365,15 @@ function watch(options, callback) { * @param {String} [profileDir=~/Library/Developer/Xcode/UserData/Provisioning Profiles] - The path to the provisioning profile directory. */ function unwatch(profileDir) { - var profileDir = getPrimaryProvisioningProfileDirectory(profileDir); - - if (!watchers[profileDir]) return; - - if (--watchers[profileDir].count <= 0) { - watchers[profileDir].handle.close(); - delete watchers[profileDir]; + var profileDirs = getExistingProvisioningProfileDirectories(profileDir); + + for (const profileDir of profileDirs) { + if (!watchers[profileDir]) return; + + if (--watchers[profileDir].count <= 0) { + watchers[profileDir].handle.close(); + delete watchers[profileDir]; + } } }; @@ -379,22 +382,20 @@ function unwatch(profileDir) { * * @throws * @param {string | undefined} profileDir A custom directory set by the developer. - * @returns {string | undefined} Either a matching directory or `undefined`, if directory could be found. + * @returns {string[]} The directories that exist on the filesystem. */ -function getPrimaryProvisioningProfileDirectory(profileDir) { - if (profileDir) { - return appc.fs.resolvePath(profileDir); - } +function getExistingProvisioningProfileDirectories(profileDir) { + const profileDirectories = []; - for (const directory of provisioningProfilesDirectories) { + for (const directory of [profileDir, ...provisioningProfilesDirectories]) { const resolvedDirectory = appc.fs.resolvePath(directory); if (fs.existsSync(resolvedDirectory)) { - return resolvedDirectory; + profileDirectories.push(resolvedDirectory); } } - return undefined; + return profileDirectories; } /* From e1ba42d8ba9f93c7118aec704ee9017f5daf0523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 23:24:41 +0200 Subject: [PATCH 4/7] fix: fix some testing issues --- lib/provisioning.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/provisioning.js b/lib/provisioning.js index c8160be..682033c 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -68,7 +68,7 @@ function detect(options, callback) { profileDirs = getExistingProvisioningProfileDirectories(options.profileDir), results = { provisioning: { - profileDir: profileDir, + profileDir: profileDirs[0], development: [], adhoc: [], enterprise: [], @@ -253,12 +253,12 @@ function detect(options, callback) { fs.readdirSync(profileDir).forEach(function (name) { ppRegExp.test(name) && parseProfile(path.join(profileDir, name)); }); + } detectIssues(); cache = results; emitter.emit('detected', results); return callback(null, results); - } }); }; @@ -388,6 +388,10 @@ function getExistingProvisioningProfileDirectories(profileDir) { const profileDirectories = []; for (const directory of [profileDir, ...provisioningProfilesDirectories]) { + if (!directory) { + continue; + } + const resolvedDirectory = appc.fs.resolvePath(directory); if (fs.existsSync(resolvedDirectory)) { From e665411ffb2bf3c70d8e84302410044c2f6c6972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 23:24:55 +0200 Subject: [PATCH 5/7] chore: only warn about missing profiles if there are any --- lib/provisioning.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/provisioning.js b/lib/provisioning.js index 682033c..0ab2e8e 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -83,8 +83,8 @@ function detect(options, callback) { distribution: 0 }, - ppRegExp = /.*\.(mobileprovision|provisionprofile)$/; - + ppRegExp = /.*\.(mobileprovision|provisionprofile)$/; + if (options.watch) { var throttleTimer = null; @@ -141,7 +141,7 @@ function detect(options, callback) { function detectIssues() { results.issues = []; - if (!results.provisioning.development.length || !valid.development) { + if (results.provisioning.development.length >0 && !valid.development) { results.issues.push({ id: 'IOS_NO_VALID_DEVELOPMENT_PROVISIONING_PROFILES', type: 'warning', @@ -150,7 +150,7 @@ function detect(options, callback) { }); } - if (!results.provisioning.adhoc.length || !valid.adhoc) { + if (results.provisioning.adhoc.length > 0 && !valid.adhoc) { results.issues.push({ id: 'IOS_NO_VALID_ADHOC_PROVISIONING_PROFILES', type: 'warning', @@ -159,7 +159,7 @@ function detect(options, callback) { }); } - if (!results.provisioning.distribution.length || !valid.distribution) { + if (results.provisioning.distribution.length > 0 && !valid.distribution) { results.issues.push({ id: 'IOS_NO_VALID_DISTRIBUTION_PROVISIONING_PROFILES', type: 'warning', @@ -255,10 +255,10 @@ function detect(options, callback) { }); } - detectIssues(); - cache = results; - emitter.emit('detected', results); - return callback(null, results); + detectIssues(); + cache = results; + emitter.emit('detected', results); + return callback(null, results); }); }; From 3731ca3a29b789824ca511e9bd42a07c3db6938e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Sat, 28 Sep 2024 23:29:33 +0200 Subject: [PATCH 6/7] chore: bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d609d99..5388758 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ioslib", - "version": "1.7.38", + "version": "1.7.39", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ioslib", - "version": "1.7.38", + "version": "1.7.39", "license": "Apache-2.0", "dependencies": { "always-tail": "0.2.0", diff --git a/package.json b/package.json index ad7f05d..79991cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ioslib", - "version": "1.7.38", + "version": "1.7.39", "description": "iOS Utility Library", "keywords": [ "appcelerator", From 9f60cf4f3a7c65cb0d8b361b83b1ac392c3d6de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Kn=C3=B6chel?= Date: Mon, 30 Sep 2024 09:51:12 +0200 Subject: [PATCH 7/7] fix: fix review comments --- lib/provisioning.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/provisioning.js b/lib/provisioning.js index 0ab2e8e..41c0011 100644 --- a/lib/provisioning.js +++ b/lib/provisioning.js @@ -83,7 +83,7 @@ function detect(options, callback) { distribution: 0 }, - ppRegExp = /.*\.(mobileprovision|provisionprofile)$/; + ppRegExp = /.*\.(mobileprovision|provisionprofile)$/; if (options.watch) { @@ -141,7 +141,7 @@ function detect(options, callback) { function detectIssues() { results.issues = []; - if (results.provisioning.development.length >0 && !valid.development) { + if (results.provisioning.development.length > 0 && !valid.development) { results.issues.push({ id: 'IOS_NO_VALID_DEVELOPMENT_PROVISIONING_PROFILES', type: 'warning', @@ -368,8 +368,8 @@ function unwatch(profileDir) { var profileDirs = getExistingProvisioningProfileDirectories(profileDir); for (const profileDir of profileDirs) { - if (!watchers[profileDir]) return; - + if (!watchers[profileDir]) continue; + if (--watchers[profileDir].count <= 0) { watchers[profileDir].handle.close(); delete watchers[profileDir];