Skip to content

Make --provision work with distribution certificates and able to update the project after initial prepare #2705

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 27, 2017
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
3 changes: 3 additions & 0 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ $injector.require("projectChangesService", "./services/project-changes-service")

$injector.require("emulatorPlatformService", "./services/emulator-platform-service");

$injector.require("pbxprojDomXcode", "./node/pbxproj-dom-xcode");
$injector.require("xcode", "./node/xcode");

$injector.require("staticConfig", "./config");

$injector.require("requireService", "./services/require-service");
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/emulate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class EmulateCommandBase {
keyStorePassword: this.$options.keyStorePassword,
keyStorePath: this.$options.keyStorePath
};
return this.$platformService.emulatePlatform(args[0], appFilesUpdaterOptions, emulateOptions, this.$projectData, this.$options.provision);
return this.$platformService.emulatePlatform(args[0], appFilesUpdaterOptions, emulateOptions, this.$projectData, this.$options);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ interface IClean {
}

interface IProvision {
provision: any;
provision: string;
}

interface ITeamIdentifier {
Expand Down
7 changes: 5 additions & 2 deletions lib/definitions/project-changes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ interface IProjectChangesInfo {
configChanged: boolean;
packageChanged: boolean;
nativeChanged: boolean;
hasChanges: boolean;
changesRequireBuild: boolean;
signingChanged: boolean;

readonly hasChanges: boolean;
readonly changesRequireBuild: boolean;
readonly changesRequirePrepare: boolean;
}

interface IProjectChangesOptions extends IAppFilesUpdaterOptions, IProvision {}
Expand Down
6 changes: 6 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ interface IPlatformProjectService extends NodeJS.EventEmitter {
* @returns {void}
*/
cleanProject(projectRoot: string, projectData: IProjectData): Promise<void>

/**
* Check the current state of the project, and validate against the options.
* If there are parts in the project that are inconsistent with the desired options, marks them in the changeset flags.
*/
checkForChanges(changeset: IProjectChangesInfo, options: IProjectChangesOptions, projectData: IProjectData): void;
}

interface IAndroidProjectPropertiesManager {
Expand Down
7 changes: 7 additions & 0 deletions lib/node/pbxproj-dom-xcode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as pbxprojDomXcodeModule from "pbxproj-dom/xcode";

declare global {
type IPbxprojDomXcode = typeof pbxprojDomXcodeModule;
}

$injector.register("pbxprojDomXcode", pbxprojDomXcodeModule);
11 changes: 11 additions & 0 deletions lib/node/xcode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as xcode from "xcode";

declare global {
type IXcode = typeof xcode;
export namespace IXcode {
export type project = typeof xcode.project;
export interface Options extends xcode.Options {} // tslint:disable-line
}
}

$injector.register("xcode", xcode);
4 changes: 4 additions & 0 deletions lib/services/android-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
await adb.executeShellCommand(["rm", "-rf", deviceRootPath]);
}

public checkForChanges(changesInfo: IProjectChangesInfo, options: IProjectChangesOptions, projectData: IProjectData): void {
// Nothing android specific to check yet.
}

private _canUseGradle: boolean;
private canUseGradle(projectData: IProjectData, frameworkVersion?: string): boolean {
if (!this._canUseGradle) {
Expand Down
67 changes: 53 additions & 14 deletions lib/services/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as path from "path";
import * as shell from "shelljs";
import * as os from "os";
import * as semver from "semver";
import * as xcode from "xcode";
import * as constants from "../constants";
import * as helpers from "../common/helpers";
import { attachAwaitDetach } from "../common/helpers";
Expand All @@ -11,7 +10,6 @@ import { PlistSession } from "plist-merge-patch";
import { EOL } from "os";
import * as temp from "temp";
import * as plist from "plist";
import { Xcode } from "pbxproj-dom/xcode";
import { IOSProvisionService } from "./ios-provision-service";

export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServiceBase implements IPlatformProjectService {
Expand Down Expand Up @@ -42,7 +40,9 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
private $pluginVariablesService: IPluginVariablesService,
private $xcprojService: IXcprojService,
private $iOSProvisionService: IOSProvisionService,
private $sysInfo: ISysInfo) {
private $sysInfo: ISysInfo,
private $pbxprojDomXcode: IPbxprojDomXcode,
private $xcode: IXcode) {
super($fs, $projectDataService);
}

Expand Down Expand Up @@ -379,10 +379,9 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
await this.createIpa(projectRoot, projectData, buildConfig);
}

private async setupSigningFromProvision(projectRoot: string, projectData: IProjectData, provision?: any): Promise<void> {
private async setupSigningFromProvision(projectRoot: string, projectData: IProjectData, provision?: string): Promise<void> {
if (provision) {
const pbxprojPath = path.join(projectRoot, projectData.projectName + ".xcodeproj", "project.pbxproj");
const xcode = Xcode.open(pbxprojPath);
const xcode = this.$pbxprojDomXcode.Xcode.open(this.getPbxProjPath(projectData));
const signing = xcode.getSigning(projectData.projectName);

let shouldUpdateXcode = false;
Expand All @@ -399,8 +398,6 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
}

if (shouldUpdateXcode) {
// This is slow, it read through 260 mobileprovision files on my machine and does quite some checking whether provisioning profiles and devices will match.
// That's why we try to avoid id by checking in the Xcode first.
const pickStart = Date.now();
const mobileprovision = await this.$iOSProvisionService.pick(provision, projectData.projectId);
const pickEnd = Date.now();
Expand Down Expand Up @@ -428,11 +425,16 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
}

private async setupSigningForDevice(projectRoot: string, buildConfig: IiOSBuildConfig, projectData: IProjectData): Promise<void> {
const pbxprojPath = path.join(projectRoot, projectData.projectName + ".xcodeproj", "project.pbxproj");
const xcode = Xcode.open(pbxprojPath);
const xcode = this.$pbxprojDomXcode.Xcode.open(this.getPbxProjPath(projectData));
const signing = xcode.getSigning(projectData.projectName);

if ((this.readXCConfigProvisioningProfile(projectData) || this.readXCConfigProvisioningProfileForIPhoneOs(projectData)) && (!signing || signing.style !== "Manual")) {
const hasProvisioningProfileInXCConfig =
this.readXCConfigProvisioningProfileSpecifierForIPhoneOs(projectData) ||
this.readXCConfigProvisioningProfileSpecifier(projectData) ||
this.readXCConfigProvisioningProfileForIPhoneOs(projectData) ||
this.readXCConfigProvisioningProfile(projectData);

if (hasProvisioningProfileInXCConfig && (!signing || signing.style !== "Manual")) {
xcode.setManualSigningStyle(projectData.projectName);
xcode.save();
} else if (!buildConfig.provision && !(signing && signing.style === "Manual" && !buildConfig.teamId)) {
Expand Down Expand Up @@ -490,7 +492,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
let frameworkBinaryPath = path.join(frameworkPath, frameworkName);
let isDynamic = _.includes((await this.$childProcess.spawnFromEvent("otool", ["-Vh", frameworkBinaryPath], "close")).stdout, " DYLIB ");

let frameworkAddOptions: xcode.Options = { customFramework: true };
let frameworkAddOptions: IXcode.Options = { customFramework: true };

if (isDynamic) {
frameworkAddOptions["embed"] = true;
Expand Down Expand Up @@ -623,7 +625,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f

if (provision) {
let projectRoot = path.join(projectData.platformsDir, "ios");
await this.setupSigningFromProvision(projectRoot, provision);
await this.setupSigningFromProvision(projectRoot, projectData, provision);
}

let project = this.createPbxProj(projectData);
Expand Down Expand Up @@ -787,7 +789,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
}

private createPbxProj(projectData: IProjectData): any {
let project = new xcode.project(this.getPbxProjPath(projectData));
let project = new this.$xcode.project(this.getPbxProjPath(projectData));
project.parseSync();

return project;
Expand Down Expand Up @@ -844,6 +846,35 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
return Promise.resolve();
}

public checkForChanges(changesInfo: IProjectChangesInfo, options: IProjectChangesOptions, projectData: IProjectData): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we add few tests for this method

const provision = options.provision;
if (provision !== undefined) {
// Check if the native project's signing is set to the provided provision...
const pbxprojPath = this.getPbxProjPath(projectData);

if (this.$fs.exists(pbxprojPath)) {
const xcode = this.$pbxprojDomXcode.Xcode.open(pbxprojPath);
const signing = xcode.getSigning(projectData.projectName);
if (signing && signing.style === "Manual") {
for (let name in signing.configurations) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you use:

for (let config of signing.configurations) {
 ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its an object, not an array, my node throws [Symbol.iterator] is not a function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, I didn't notice this is an object.

let config = signing.configurations[name];
if (config.uuid !== provision && config.name !== provision) {
changesInfo.signingChanged = true;
break;
}
}
} else {
// Specifying provisioning profile requires "Manual" signing style.
// If the current signing style was not "Manual" it was probably "Automatic" or,
// it was not uniform for the debug and release build configurations.
changesInfo.signingChanged = true;
}
} else {
changesInfo.signingChanged = true;
}
}
}

private getAllLibsForPluginWithFileExtension(pluginData: IPluginData, fileExtension: string): string[] {
let filterCallback = (fileName: string, pluginPlatformsFolderPath: string) => path.extname(fileName) === fileExtension;
return this.getAllNativeLibrariesForPlugin(pluginData, IOSProjectService.IOS_PLATFORM_NAME, filterCallback);
Expand Down Expand Up @@ -1186,6 +1217,14 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
return this.readXCConfig("PROVISIONING_PROFILE[sdk=iphoneos*]", projectData);
}

private readXCConfigProvisioningProfileSpecifier(projectData: IProjectData): string {
return this.readXCConfig("PROVISIONING_PROFILE_SPECIFIER", projectData);
}

private readXCConfigProvisioningProfileSpecifierForIPhoneOs(projectData: IProjectData): string {
return this.readXCConfig("PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]", projectData);
}

private async getDevelopmentTeam(projectData: IProjectData, teamId?: string): Promise<string> {
teamId = teamId || this.readTeamId(projectData);

Expand Down
2 changes: 1 addition & 1 deletion lib/services/ios-provision-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class IOSProvisionService {

function formatSupportedDeviceCount(prov: mobileprovision.provision.MobileProvision) {
if (devices.length > 0 && prov.Type === "Development") {
return prov.ProvisionedDevices.reduce((count, device) => count + (devices.indexOf(device) >= 0 ? 1 : 0), 0) + "/" + devices.length + " targets";
return prov.ProvisionedDevices.filter(device => devices.indexOf(device) >= 0).length + "/" + devices.length + " targets";
} else {
return "";
}
Expand Down
2 changes: 1 addition & 1 deletion lib/services/platform-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
}
}

if (!changesInfo || changesInfo.appResourcesChanged) {
if (!changesInfo || changesInfo.changesRequirePrepare) {
await this.copyAppFiles(platform, appFilesUpdaterOptions, projectData);
this.copyAppResources(platform, projectData);
await platformData.platformProjectService.prepareProject(projectData, platformSpecificData);
Expand Down
23 changes: 12 additions & 11 deletions lib/services/project-changes-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,27 @@ class ProjectChangesInfo implements IProjectChangesInfo {
public configChanged: boolean;
public packageChanged: boolean;
public nativeChanged: boolean;
public signingChanged: boolean;

public get hasChanges(): boolean {
return this.packageChanged ||
this.appFilesChanged ||
this.appResourcesChanged ||
this.modulesChanged ||
this.configChanged;
this.configChanged ||
this.signingChanged;
}

public get changesRequireBuild(): boolean {
return this.packageChanged ||
this.appResourcesChanged ||
this.nativeChanged;
}

public get changesRequirePrepare(): boolean {
return this.appResourcesChanged ||
this.signingChanged;
}
}

export class ProjectChangesService implements IProjectChangesService {
Expand Down Expand Up @@ -75,16 +82,10 @@ export class ProjectChangesService implements IProjectChangesService {
]);
}
}
if (platform.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
const nextCommandProvisionUUID = projectChangesOptions.provision;
// We should consider reading here the provisioning profile UUID from the xcodeproj and xcconfig.
const prevProvisionUUID = this._prepareInfo.iOSProvisioningProfileUUID;
if (nextCommandProvisionUUID !== prevProvisionUUID) {
this._changesInfo.nativeChanged = true;
this._changesInfo.configChanged = true;
this._prepareInfo.iOSProvisioningProfileUUID = nextCommandProvisionUUID;
}
}

let projectService = platformData.platformProjectService;
projectService.checkForChanges(this._changesInfo, projectChangesOptions, projectData);

if (projectChangesOptions.bundle !== this._prepareInfo.bundle || projectChangesOptions.release !== this._prepareInfo.release) {
this._changesInfo.appFilesChanged = true;
this._changesInfo.appResourcesChanged = true;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"mute-stream": "0.0.5",
"open": "0.0.5",
"osenv": "0.1.3",
"pbxproj-dom": "1.0.9",
"pbxproj-dom": "1.0.11",
"plist": "1.1.0",
"plist-merge-patch": "0.0.9",
"plistlib": "0.2.1",
Expand Down Expand Up @@ -98,8 +98,8 @@
"grunt-tslint": "4.0.0",
"istanbul": "0.4.5",
"mocha": "3.1.2",
"mocha-typescript": "^1.0.4",
"should": "7.0.2",
"source-map-support": "^0.4.14",
"tslint": "4.3.1",
"typescript": "2.1.4"
},
Expand Down
Loading