Skip to content

Use xcproj if needed to fix .pbxproject format #1690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions lib/services/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
private $devicesService: Mobile.IDevicesService,
private $mobileHelper: Mobile.IMobileHelper,
private $pluginVariablesService: IPluginVariablesService,
private $staticConfig: IStaticConfig,
private $sysInfo: ISysInfo,
private $xcodeSelectService: IXcodeSelectService) {
super($fs, $projectData, $projectDataService);
}
Expand Down Expand Up @@ -146,7 +148,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
this.replaceFileName("-Prefix.pch", projectRootFilePath).wait();
this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, this.platformData.projectRoot).wait();

let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
let pbxprojFilePath = this.pbxProjPath;
this.replaceFileContent(pbxprojFilePath).wait();
}).future<void>()();
}
Expand Down Expand Up @@ -355,7 +357,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
let isUpdateConfirmed = this.$prompter.confirm(`We need to override xcodeproj file. The old one will be saved at ${this.$options.profileDir}. Are you sure?`, () => true).wait();
if(isUpdateConfirmed) {
// Copy old file to options["profile-dir"]
let sourceDir = path.join(this.platformData.projectRoot, `${this.$projectData.projectName}.xcodeproj`);
let sourceDir = this.xcodeprojPath;
let destinationDir = path.join(this.$options.profileDir, "xcodeproj");
this.$fs.deleteDirectory(destinationDir).wait();
shell.cp("-R", path.join(sourceDir, "*"), destinationDir);
Expand All @@ -367,7 +369,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
shell.cp("-R", path.join(cachedPackagePath, "*"), sourceDir);
this.$logger.info(`Copied from ${cachedPackagePath} at ${this.platformData.projectRoot}.`);

let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
let pbxprojFilePath = this.pbxProjPath;
this.replaceFileContent(pbxprojFilePath).wait();
}

Expand Down Expand Up @@ -512,6 +514,14 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
return (<IPluginsService>this.$injector.resolve("pluginsService")).getAllInstalledPlugins();
}

private get xcodeprojPath(): string {
return path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME);
}

private get cocoaPodsXcodeprojPath(): string {
return path.join(this.platformData.projectRoot, "Pods", "Pods" + IOSProjectService.XCODE_PROJECT_EXT_NAME);
}

private get projectPodFilePath(): string {
return path.join(this.platformData.projectRoot, "Podfile");
}
Expand Down Expand Up @@ -539,7 +549,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
}

private get pbxProjPath(): string {
return path.join(this.platformData.projectRoot, this.$projectData.projectName + ".xcodeproj", "project.pbxproj");
return path.join(this.xcodeprojPath, "project.pbxproj");
}

private createPbxProj(): any {
Expand Down Expand Up @@ -585,8 +595,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
this.$logger.warn(`Podfile contains more than one post_install sections. You need to open ${this.projectPodFilePath} file and manually resolve this issue.`);
}

let pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "xcuserdata");
if(!this.$fs.exists(pbxprojFilePath).wait()) {
let xcuserDataPath = path.join(this.xcodeprojPath, "xcuserdata");
if(!this.$fs.exists(xcuserDataPath).wait()) {
this.$logger.info("Creating project scheme...");
let createSchemeRubyScript = `ruby -e "require 'xcodeproj'; xcproj = Xcodeproj::Project.open('${this.$projectData.projectName}.xcodeproj'); xcproj.recreate_user_schemes; xcproj.save"`;
this.$childProcess.exec(createSchemeRubyScript, { cwd: this.platformData.projectRoot }).wait();
Expand Down Expand Up @@ -664,6 +674,24 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
this.$errors.failWithoutHelp("CocoaPods or ruby gem 'xcodeproj' is not installed. Run `sudo gem install cocoapods` and try again.");
}

let cocoapodsVer = this.$sysInfo.getSysInfo(this.$staticConfig.pathToPackageJson).wait().cocoapodVer,
xcodeVersion = this.$xcodeSelectService.getXcodeVersion().wait();

xcodeVersion.patch = xcodeVersion.patch || "0";
let shouldUseXcproj = semver.lt(cocoapodsVer, "1.0.0") && ~helpers.versionCompare(xcodeVersion, "7.3.0");

// CocoaPods with version lower than 1.0.0 don't support Xcode 7.3 yet
// https://github.com/CocoaPods/CocoaPods/issues/2530#issuecomment-210470123
// as a result of this all .pbxprojects touched by CocoaPods get converted to XML plist format
if (shouldUseXcproj) {
// if that's the case we can use xcproj gem to convert them back to ASCII plist format
try {
this.$childProcess.exec("xcproj --version").wait();
} catch(e) {
this.$errors.failWithoutHelp(`You are using CocoaPods version ${cocoapodsVer} which does not support Xcode ${xcodeVersion.major}.${xcodeVersion.minor} yet. In order for the NativeScript CLI to be able to work correctly with this setup you need to install xcproj command line tool and add it to your PATH.`);
}
}

this.$logger.info("Installing pods...");
let podTool = this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod";
let childProcess = this.$childProcess.spawnFromEvent(podTool, ["install"], "close", { cwd: this.platformData.projectRoot, stdio: ['pipe', process.stdout, 'pipe'] }).wait();
Expand All @@ -683,6 +711,11 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
}
}

if (shouldUseXcproj) {
this.$childProcess.exec(`xcproj --project ${this.xcodeprojPath} touch`).wait();
this.$childProcess.exec(`xcproj --project ${this.cocoaPodsXcodeprojPath} touch`).wait();
}

return childProcess;
}).future<any>()();
}
Expand Down
1 change: 1 addition & 0 deletions test/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function createTestInjector(projectPath: string, projectName: string): IInjector
testInjector.register("loggingLevels", LoggingLevels);
testInjector.register("utils", Utils);
testInjector.register("iTunesValidator", {});
testInjector.register("sysInfo", {});
testInjector.register("pluginVariablesService", PluginVariablesService);
testInjector.register("pluginVariablesHelper", PluginVariablesHelper);
return testInjector;
Expand Down