Skip to content

Commit 12aeeb4

Browse files
authored
refactor(template): Copy CordovaLib into a packages folder (#1522)
Pointing a relative path to CordovaLib in the node_modules folder means that the Xcode project is no longer self-contained, which is significant change in terms of assumptions people can make about the project files in CI environments (i.e., preparing all platforms once, then copying just the platform folders to different runners to build). So we now copy the CordovaLib folder into a platforms/ios/packages directory and point to it there. As a side effect, it seemed worth bringing back the `--link` option to continue pointing to node_modules for easier development.
1 parent 7fa0b8c commit 12aeeb4

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

lib/Api.js

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class Api {
107107
* @param {Object} [options] An options object. The most common options are:
108108
* @param {String} [options.customTemplate] A path to custom template, that
109109
* should override the default one from platform.
110+
* @param {Boolean} [options.link] Flag that indicates that platform's
111+
* sources will be linked to installed platform instead of copying.
110112
* @param {EventEmitter} [events] An EventEmitter instance that will be used for
111113
* logging purposes. If no EventEmitter provided, all events will be logged to
112114
* console

lib/create.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const ROOT = path.join(__dirname, '..');
3131
* @param {string} project_path Path to your new Cordova iOS project
3232
* @param {string} package_name Package name, following reverse-domain style convention
3333
* @param {string} project_name Project name
34-
* @param {{ customTemplate: string }} opts Project creation options
34+
* @param {{ link: boolean, customTemplate: string }} opts Project creation options
3535
* @param {ConfigParser} root_config The application config.xml
3636
* @returns {Promise<void>} resolves when the project has been created
3737
*/
@@ -57,6 +57,7 @@ exports.createProject = async (project_path, package_name, project_name, opts, r
5757
},
5858
options: {
5959
templatePath: opts.customTemplate || path.join(ROOT, 'templates', 'project'),
60+
linkLib: !!opts.link,
6061
rootConfig: root_config
6162
}
6263
}).create();
@@ -84,6 +85,13 @@ class ProjectCreator {
8485
const r = this.projectPath('App');
8586
fs.renameSync(path.join(r, 'gitignore'), path.join(r, '.gitignore'));
8687
fs.cpSync(path.join(r, '.gitignore'), this.projectPath('.gitignore'));
88+
89+
if (!this.options.linkLib) {
90+
// Copy CordovaLib into the packages folder
91+
fs.mkdirSync(this.projectPath('packages', 'cordova-ios'), { recursive: true });
92+
fs.cpSync(path.join(ROOT, 'CordovaLib'), this.projectPath('packages', 'cordova-ios', 'CordovaLib'), { recursive: true });
93+
fs.cpSync(path.join(ROOT, 'Package.swift'), this.projectPath('packages', 'cordova-ios', 'Package.swift'));
94+
}
8795
}
8896

8997
provideCordovaJs () {
@@ -133,7 +141,14 @@ class ProjectCreator {
133141
}
134142

135143
if (ref.relativePath?.match(/\/cordova-ios/)) {
136-
ref.relativePath = `"${path.relative(this.project.path, ROOT).replaceAll(path.sep, path.posix.sep)}"`;
144+
let relPath = path.relative(this.project.path, this.projectPath('packages', 'cordova-ios'));
145+
146+
if (this.options.linkLib) {
147+
// Point to CordovaLib in node_modules
148+
relPath = path.relative(this.project.path, ROOT);
149+
}
150+
151+
ref.relativePath = `"${relPath.replaceAll(path.sep, path.posix.sep)}"`;
137152
break;
138153
}
139154
}

tests/spec/unit/create.spec.js

+18-7
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const templateConfigXmlPath = path.join(__dirname, '..', '..', '..', 'templates'
4040
* @param {String} tmpDir
4141
* @param {String} projectName
4242
*/
43-
function verifyProjectFiles (tmpDir, projectName) {
43+
function verifyProjectFiles (tmpDir, projectName, linked) {
4444
expect(fs.existsSync(path.join(tmpDir, 'App'))).toBe(true);
4545
expect(fs.existsSync(path.join(tmpDir, 'App.xcodeproj'))).toBe(true);
4646
expect(fs.existsSync(path.join(tmpDir, 'App.xcworkspace'))).toBe(true);
@@ -50,7 +50,8 @@ function verifyProjectFiles (tmpDir, projectName) {
5050
xcodeproj.parseSync();
5151

5252
const packageLoc = path.dirname(require.resolve('../../../package.json'));
53-
const relativePath = path.relative(tmpDir, packageLoc).replaceAll(path.sep, path.posix.sep);
53+
const relativeLink = path.relative(tmpDir, packageLoc).replaceAll(path.sep, path.posix.sep);
54+
const relativePath = path.posix.join('packages', 'cordova-ios');
5455

5556
let foundRef = false;
5657
const pkgRefs = xcodeproj.hash.project.objects.XCLocalSwiftPackageReference;
@@ -61,7 +62,11 @@ function verifyProjectFiles (tmpDir, projectName) {
6162

6263
if (ref.relativePath.match(/\/cordova-ios/)) {
6364
foundRef = true;
64-
expect(ref.relativePath).toMatch(relativePath);
65+
if (linked) {
66+
expect(ref.relativePath).toMatch(relativeLink);
67+
} else {
68+
expect(ref.relativePath).toMatch(relativePath);
69+
}
6570
break;
6671
}
6772
}
@@ -104,11 +109,11 @@ function verifyProjectDeploymentTarget (tmpDir, expectedTarget) {
104109
* @param {String} projectName
105110
* @returns {Promise}
106111
*/
107-
async function verifyCreatedProject (tmpDir, packageName, projectName, configFile = templateConfigXmlPath) {
112+
async function verifyCreatedProject (tmpDir, packageName, projectName, link = false, configFile = templateConfigXmlPath) {
108113
const configXml = new ConfigParser(configFile);
109114

110-
await create.createProject(tmpDir, packageName, projectName, {}, configXml)
111-
.then(() => verifyProjectFiles(tmpDir, projectName))
115+
await create.createProject(tmpDir, packageName, projectName, { link }, configXml)
116+
.then(() => verifyProjectFiles(tmpDir, projectName, link))
112117
.then(() => verifyProjectBundleIdentifier(tmpDir, projectName, packageName));
113118
}
114119

@@ -135,12 +140,18 @@ describe('create', () => {
135140
return verifyCreatedProject(tmpDir, packageName, projectName);
136141
});
137142

143+
it('should create project with linked CordovaLib', () => {
144+
const packageName = 'com.test.app3';
145+
const projectName = 'testcreatelink';
146+
return verifyCreatedProject(tmpDir, packageName, projectName, true);
147+
});
148+
138149
it('should copy config.xml into the newly created project', () => {
139150
const configPath = path.join(__dirname, 'fixtures', 'test-config-3.xml');
140151
const packageName = 'io.cordova.hellocordova.ios';
141152
const projectName = 'Hello Cordova';
142153

143-
return verifyCreatedProject(tmpDir, packageName, projectName, configPath)
154+
return verifyCreatedProject(tmpDir, packageName, projectName, false, configPath)
144155
.then(() => verifyProjectDeploymentTarget(tmpDir, '15.0'));
145156
});
146157
});

0 commit comments

Comments
 (0)