Skip to content

Commit

Permalink
feat!: force iOS project name to App
Browse files Browse the repository at this point in the history
  • Loading branch information
erisu committed Aug 23, 2024
1 parent ab78439 commit ed161c4
Show file tree
Hide file tree
Showing 36 changed files with 119 additions and 205 deletions.
67 changes: 34 additions & 33 deletions lib/Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const {
PluginManager
} = require('cordova-common');

const APP_NAME = 'App';

function setupEvents (externalEventEmitter) {
if (externalEventEmitter) {
// This will make the platform internal events visible outside
Expand Down Expand Up @@ -81,39 +83,43 @@ class Api {

setupEvents(events);

let xcodeProjDir;
let xcodeCordovaProj;

try {
const xcodeProjDir_array = fs.readdirSync(this.root).filter(e => e.match(/\.xcodeproj$/i));
if (xcodeProjDir_array.length > 1) {
for (let x = 0; x < xcodeProjDir_array.length; x++) {
if (xcodeProjDir_array[x].substring(0, 2) === '._') {
xcodeProjDir_array.splice(x, 1);
}
}
}
xcodeProjDir = xcodeProjDir_array[0];
const xcodeProjDir = path.join(this.root, 'App.xcodeproj');
const xcworkspaceDir = path.join(this.root, 'App.xcworkspace');
const appDir = path.join(this.root, APP_NAME);

if (!xcodeProjDir) {
throw new CordovaError(`The provided path "${this.root}" is not a Cordova iOS project.`);
}

const cordovaProjName = xcodeProjDir.substring(xcodeProjDir.lastIndexOf(path.sep) + 1, xcodeProjDir.indexOf('.xcodeproj'));
xcodeCordovaProj = path.join(this.root, cordovaProjName);
} catch (e) {
if (
!fs.existsSync(this.root) ||
!fs.existsSync(xcodeProjDir) ||
!fs.existsSync(xcworkspaceDir) ||
!fs.existsSync(appDir)
) {
throw new CordovaError(`The provided path "${this.root}" is not a Cordova iOS project.`);
}

this.locations = {
/**
* New paths
*/
appDir,
xcworkspaceDir,
buildDir: path.join(this.root, 'build'),
cordovaDir: path.join(this.root, 'cordova'),

/**
* Old paths but still active
*/
root: this.root,
www: path.join(this.root, 'www'),
platformWww: path.join(this.root, 'platform_www'),
configXml: path.join(xcodeCordovaProj, 'config.xml'),
configXml: path.join(appDir, 'config.xml'),
pbxproj: path.join(xcodeProjDir, 'project.pbxproj'),
xcodeProjDir,

/**
* deprecated paths
*/
defaultConfigXml: path.join(this.root, 'cordova', 'defaults.xml'),
pbxproj: path.join(this.root, xcodeProjDir, 'project.pbxproj'),
xcodeProjDir: path.join(this.root, xcodeProjDir),
xcodeCordovaProj
xcodeCordovaProj: appDir
};
}

Expand Down Expand Up @@ -261,9 +267,8 @@ class Api {
const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader');
if (bridgingHeaders.length > 0) {
const project_dir = this.locations.root;
const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop();
const BridgingHeader = require('./BridgingHeader').BridgingHeader;
const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, project_name, 'Bridging-Header.h'));
const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, APP_NAME, 'Bridging-Header.h'));
events.emit('verbose', 'Adding Bridging-Headers since the plugin contained <header-file> with type="BridgingHeader"');
bridgingHeaders.forEach(obj => {
const bridgingHeaderPath = path.basename(obj.src);
Expand Down Expand Up @@ -307,9 +312,8 @@ class Api {
const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader');
if (bridgingHeaders.length > 0) {
const project_dir = this.locations.root;
const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop();
const BridgingHeader = require('./BridgingHeader').BridgingHeader;
const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, project_name, 'Bridging-Header.h'));
const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, APP_NAME, 'Bridging-Header.h'));
events.emit('verbose', 'Removing Bridging-Headers since the plugin contained <header-file> with type="BridgingHeader"');
bridgingHeaders.forEach(obj => {
const bridgingHeaderPath = path.basename(obj.src);
Expand Down Expand Up @@ -343,13 +347,12 @@ class Api {
}

const project_dir = this.locations.root;
const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop();
const minDeploymentTarget = this.getPlatformInfo().projectConfig.getPreference('deployment-target', 'ios');

const Podfile = require('./Podfile').Podfile;
const PodsJson = require('./PodsJson').PodsJson;
const podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name, minDeploymentTarget);
const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), APP_NAME, minDeploymentTarget);

events.emit('verbose', 'Adding pods since the plugin contained <podspecs>');
podSpecs.forEach(obj => {
Expand Down Expand Up @@ -435,12 +438,10 @@ class Api {

removePodSpecs (plugin, podSpecs, uninstallOptions) {
const project_dir = this.locations.root;
const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop();

const Podfile = require('./Podfile').Podfile;
const PodsJson = require('./PodsJson').PodsJson;
const podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name);
const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), APP_NAME);

if (podSpecs.length) {
events.emit('verbose', 'Adding pods since the plugin contained <podspecs>');
Expand Down
79 changes: 30 additions & 49 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const plist = require('plist');
const check_reqs = require('./check_reqs');
const projectFile = require('./projectFile');

const APP_NAME = 'App';

const buildConfigProperties = [
'codeSignIdentity',
'provisioningProfile',
Expand Down Expand Up @@ -57,19 +59,13 @@ const buildFlagMatchers = {
/* eslint-enable no-useless-escape */

/**
* Creates a project object (see projectFile.js/parseProjectFile) from
* a project path and name
*
* @param {*} projectPath
* @param {*} projectName
* Creates a project object (see projectFile.js/parseProjectFile) from a project path and name
*/
function createProjectObject (projectPath, projectName) {
const locations = {
root: projectPath,
pbxproj: path.join(projectPath, `${projectName}.xcodeproj`, 'project.pbxproj')
};

return projectFile.parse(locations);
function createProjectObject () {
return projectFile.parse({
root: this.locations.root,
pbxproj: this.locations.pbxproj
});
}

/**
Expand Down Expand Up @@ -101,9 +97,9 @@ function getDefaultSimulatorTarget () {

/** @returns {Promise<void>} */
module.exports.run = function (buildOpts) {
const projectPath = this.root;
console.log('BUILD RUN', this.locations);
const projectPath = this.locations.root;
let emulatorTarget = '';
let projectName = '';

buildOpts = buildOpts || {};

Expand Down Expand Up @@ -169,9 +165,7 @@ module.exports.run = function (buildOpts) {
}
})
.then(() => check_reqs.run())
.then(() => findXCodeProjectIn(projectPath))
.then(name => {
projectName = name;
.then(_ => {
let extraConfig = '';
if (buildOpts.codeSignIdentity) {
extraConfig += `CODE_SIGN_IDENTITY = ${buildOpts.codeSignIdentity}\n`;
Expand All @@ -190,7 +184,7 @@ module.exports.run = function (buildOpts) {
}

function writeCodeSignStyle (value) {
const project = createProjectObject(projectPath, projectName);
const project = createProjectObject();

events.emit('verbose', `Set CODE_SIGN_STYLE Build Property to ${value}.`);
project.xcode.updateBuildProperty('CODE_SIGN_STYLE', value);
Expand All @@ -208,28 +202,28 @@ module.exports.run = function (buildOpts) {
writeCodeSignStyle('Automatic');
}

return fsp.writeFile(path.join(projectPath, 'cordova', 'build-extras.xcconfig'), extraConfig, 'utf-8');
return fsp.writeFile(path.join(this.locations.cordovaDir, 'build-extras.xcconfig'), extraConfig, 'utf-8');
}).then(() => {
const configuration = buildOpts.release ? 'Release' : 'Debug';

events.emit('log', `Building project: ${path.join(projectPath, `${projectName}.xcworkspace`)}`);
events.emit('log', `Building project: ${this.locations.xcworkspaceDir}`);
events.emit('log', `\tConfiguration: ${configuration}`);
events.emit('log', `\tPlatform: ${buildOpts.device ? 'device' : 'emulator'}`);
events.emit('log', `\tTarget: ${emulatorTarget}`);

const buildOutputDir = path.join(projectPath, 'build', `${configuration}-${(buildOpts.device ? 'iphoneos' : 'iphonesimulator')}`);
const buildOutputDir = path.join(this.locations.buildDir, `${configuration}-${(buildOpts.device ? 'iphoneos' : 'iphonesimulator')}`);

// remove the build output folder before building
fs.rmSync(buildOutputDir, { recursive: true, force: true });

const xcodebuildArgs = getXcodeBuildArgs(projectName, projectPath, configuration, emulatorTarget, buildOpts);
const xcodebuildArgs = getXcodeBuildArgs(this.locations.buildDir, configuration, emulatorTarget, buildOpts);
return execa('xcodebuild', xcodebuildArgs, { cwd: projectPath, stdio: 'inherit' });
}).then(() => {
if (!buildOpts.device || buildOpts.noSign) {
return;
}

const project = createProjectObject(projectPath, projectName);
const project = createProjectObject();
const bundleIdentifier = project.getPackageName();
const exportOptions = { ...buildOpts.exportOptions, compileBitcode: false, method: 'development' };

Expand Down Expand Up @@ -276,7 +270,7 @@ module.exports.run = function (buildOpts) {
}

function packageArchive () {
const xcodearchiveArgs = getXcodeArchiveArgs(projectName, projectPath, buildOutputDir, exportOptionsPath, buildOpts);
const xcodearchiveArgs = getXcodeArchiveArgs(buildOutputDir, exportOptionsPath, buildOpts);
return execa('xcodebuild', xcodearchiveArgs, { cwd: projectPath, stdio: 'inherit' });
}

Expand All @@ -293,32 +287,21 @@ module.exports.run = function (buildOpts) {
* @return {Promise} Promise either fulfilled with project name or rejected
*/
function findXCodeProjectIn (projectPath) {
// 'Searching for Xcode project in ' + projectPath);
const xcodeProjFiles = fs.readdirSync(projectPath).filter(name => path.extname(name) === '.xcodeproj');

if (xcodeProjFiles.length === 0) {
return Promise.reject(new CordovaError(`No Xcode project found in ${projectPath}`));
}
if (xcodeProjFiles.length > 1) {
events.emit('warn', `Found multiple .xcodeproj directories in \n${projectPath}\nUsing first one`);
}

const projectName = path.basename(xcodeProjFiles[0], '.xcodeproj');
return Promise.resolve(projectName);
console.warn('findXCodeProjectIn is deprecated. App name in a Cordova-iOS 8.x project is always "App"');
return Promise.resolve(APP_NAME);
}

module.exports.findXCodeProjectIn = findXCodeProjectIn;

/**
* Returns array of arguments for xcodebuild
* @param {String} projectName Name of xcode project
* @param {String} projectPath Path to project file. Will be used to set CWD for xcodebuild
* @param {String} buildDir build directory
* @param {String} configuration Configuration name: debug|release
* @param {String} emulatorTarget Target for emulator (rather than default)
* @param {Object} buildConfig The build configuration options
* @return {Array} Array of arguments that could be passed directly to spawn method
*/
function getXcodeBuildArgs (projectName, projectPath, configuration, emulatorTarget, buildConfig = {}) {
function getXcodeBuildArgs (buildDir, configuration, emulatorTarget, buildConfig = {}) {
let options;
let buildActions;
let settings;
Expand All @@ -338,11 +321,11 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, emulatorTar

if (buildConfig.device) {
options = [
'-workspace', customArgs.workspace || `${projectName}.xcworkspace`,
'-scheme', customArgs.scheme || projectName,
'-workspace', customArgs.workspace || 'App.xcworkspace',
'-scheme', customArgs.scheme || APP_NAME,
'-configuration', customArgs.configuration || configuration,
'-destination', customArgs.destination || 'generic/platform=iOS',
'-archivePath', customArgs.archivePath || `${projectName}.xcarchive`
'-archivePath', customArgs.archivePath || 'App.xcarchive'
];
buildActions = ['archive'];
settings = [];
Expand Down Expand Up @@ -375,14 +358,14 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, emulatorTar
}
} else { // emulator
options = [
'-workspace', customArgs.workspace || `${projectName}.xcworkspace`,
'-scheme', customArgs.scheme || projectName,
'-workspace', customArgs.workspace || 'App.xcworkspace',
'-scheme', customArgs.scheme || APP_NAME,
'-configuration', customArgs.configuration || configuration,
'-sdk', customArgs.sdk || 'iphonesimulator',
'-destination', customArgs.destination || `platform=iOS Simulator,name=${emulatorTarget}`
];
buildActions = ['build'];
settings = [`SYMROOT=${path.join(projectPath, 'build')}`];
settings = [`SYMROOT=${buildDir}`];

if (customArgs.configuration_build_dir) {
settings.push(customArgs.configuration_build_dir);
Expand All @@ -404,14 +387,12 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, emulatorTar

/**
* Returns array of arguments for xcodebuild
* @param {String} projectName Name of xcode project
* @param {String} projectPath Path to project file. Will be used to set CWD for xcodebuild
* @param {String} outputPath Output directory to contain the IPA
* @param {String} exportOptionsPath Path to the exportOptions.plist file
* @param {Object} buildConfig Build configuration options
* @return {Array} Array of arguments that could be passed directly to spawn method
*/
function getXcodeArchiveArgs (projectName, projectPath, outputPath, exportOptionsPath, buildConfig = {}) {
function getXcodeArchiveArgs (outputPath, exportOptionsPath, buildConfig = {}) {
const options = [];

if (buildConfig.automaticProvisioning) {
Expand All @@ -429,7 +410,7 @@ function getXcodeArchiveArgs (projectName, projectPath, outputPath, exportOption

return [
'-exportArchive',
'-archivePath', `${projectName}.xcarchive`,
'-archivePath', 'App.xcarchive',
'-exportOptionsPlist', exportOptionsPath,
'-exportPath', outputPath
].concat(options);
Expand Down
Loading

0 comments on commit ed161c4

Please sign in to comment.