Skip to content

Fix update #318

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 5 commits into from
Mar 16, 2015
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
2 changes: 1 addition & 1 deletion lib/commands/update-platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class UpdatePlatformCommand implements ICommand {
this.$errors.fail("No platform specified. Please specify platforms to update.");
}

_.each(args, arg => this.$platformService.validatePlatformInstalled(arg));
_.each(args, arg => this.$platformService.validatePlatformInstalled(arg.split("@")[0]));

return true;
}).future<boolean>()();
Expand Down
1 change: 1 addition & 0 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface INodePackageManager {
load(config?: any): IFuture<void>;
install(packageName: string, options?: INpmInstallOptions): IFuture<string>;
getLatestVersion(packageName: string): IFuture<string>;
getCachedPackagePath(packageName: string, version: string): string;
}

interface INpmInstallOptions {
Expand Down
2 changes: 2 additions & 0 deletions lib/definitions/platform.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ interface IPlatformData {
validPackageNamesForDevice: string[];
validPackageNamesForEmulator?: string[];
frameworkFilesExtensions: string[];
frameworkDirectoriesExtensions?: string[];
frameworkDirectoriesNames?: string[];
targetedOS?: string[];
}

Expand Down
2 changes: 2 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ interface IPlatformProjectService {
buildProject(projectRoot: string): IFuture<void>;
isPlatformPrepared(projectRoot: string): IFuture<boolean>;
addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void>;
canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean>;
updatePlatform(currentVersion: string, newVersion: string): IFuture<void>;
}
17 changes: 14 additions & 3 deletions lib/node-package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ export class NodePackageManager implements INodePackageManager {
}

public addToCache(packageName: string, version: string): IFuture<void> {
return this.addToCacheCore(packageName, version);
return (() => {
this.addToCacheCore(packageName, version).wait();

var packagePath = path.join(npm.cache, packageName, version, "package");
if(!this.isPackageUnpacked(packagePath).wait()) {
this.cacheUnpack(packageName, version).wait();
}
}).future<void>()();
}

public load(config?: any): IFuture<void> {
Expand Down Expand Up @@ -73,6 +80,10 @@ export class NodePackageManager implements INodePackageManager {
}).future<string>()();
}

public getCachedPackagePath(packageName: string, version: string): string {
return path.join(npm.cache, packageName, version, "package");
}

private installCore(packageName: string, pathToSave: string, version: string): IFuture<string> {
return (() => {
if (options.frameworkPath) {
Expand All @@ -84,8 +95,8 @@ export class NodePackageManager implements INodePackageManager {
}
return options.frameworkPath;
} else {
var version: string = version || this.getLatestVersion(packageName).wait();
var packagePath = path.join(npm.cache, packageName, version, "package");
version = version || this.getLatestVersion(packageName).wait();
var packagePath = this.getCachedPackagePath(packageName, version);
if (!this.isPackageCached(packagePath).wait()) {
this.addToCacheCore(packageName, version).wait();
}
Expand Down
13 changes: 11 additions & 2 deletions lib/services/android-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class AndroidProjectService implements IPlatformProjectService {
private $logger: ILogger,
private $projectData: IProjectData,
private $propertiesParser: IPropertiesParser) {

}

public get platformData(): IPlatformData {
Expand All @@ -38,7 +37,7 @@ class AndroidProjectService implements IPlatformProjectService {
util.format("%s-%s.%s", this.$projectData.projectName, "debug", "apk"),
util.format("%s-%s.%s", this.$projectData.projectName, "release", "apk")
],
frameworkFilesExtensions: [".jar", ".dat"]
frameworkFilesExtensions: [".jar", ".dat", ".so"]
};
}

Expand Down Expand Up @@ -123,6 +122,16 @@ class AndroidProjectService implements IPlatformProjectService {
}).future<string>()();
}

public canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean> {
return (() => {
return true;
}).future<boolean>()();
}

updatePlatform(currentVersion: string, newVersion: string): IFuture<void> {
return (() => { }).future<void>()();
}

private updateMetadata(projectRoot: string): void {
var projMetadataDir = path.join(projectRoot, "assets", "metadata");
var libsmetadataDir = path.join(projectRoot, "../../lib", this.platformData.normalizedPlatformName, AndroidProjectService.METADATA_DIRNAME);
Expand Down
49 changes: 45 additions & 4 deletions lib/services/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class IOSProjectService implements IPlatformProjectService {
private $childProcess: IChildProcess,
private $errors: IErrors,
private $logger: ILogger,
private $iOSEmulatorServices: Mobile.IEmulatorPlatformServices) { }
private $iOSEmulatorServices: Mobile.IEmulatorPlatformServices,
private $npm: INodePackageManager) { }

public get platformData(): IPlatformData {
return {
Expand All @@ -37,7 +38,9 @@ class IOSProjectService implements IPlatformProjectService {
validPackageNamesForEmulator: [
this.$projectData.projectName + ".app"
],
frameworkFilesExtensions: [".a", ".h", ".bin"],
frameworkFilesExtensions: [".a", ".framework", ".bin"],
frameworkDirectoriesExtensions: [".framework"],
frameworkDirectoriesNames: ["Metadata"],
targetedOS: ['darwin']
};
}
Expand Down Expand Up @@ -70,7 +73,7 @@ class IOSProjectService implements IPlatformProjectService {
var xcodeProjectName = util.format("%s.xcodeproj", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER);

shell.cp("-R", path.join(frameworkDir, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, "*"), path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER));
shell.cp("-R", path.join(frameworkDir, xcodeProjectName), path.join(projectRoot));
shell.cp("-R", path.join(frameworkDir, xcodeProjectName), projectRoot);

var directoryContent = this.$fs.readDirectory(frameworkDir).wait();
var frameworkFiles = _.difference(directoryContent, [IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, xcodeProjectName]);
Expand Down Expand Up @@ -193,7 +196,45 @@ class IOSProjectService implements IPlatformProjectService {
this.$fs.writeFile(pbxProjPath, project.writeSync()).wait();
this.$logger.info("The iOS Deployment Target is now 8.0 in order to support Cocoa Touch Frameworks.");
}).future<void>()();
}
}

public canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean> {
return (() => {
var currentXcodeProjectFile = this.buildPathToXcodeProjectFile(currentVersion);
var currentXcodeProjectFileContent = this.$fs.readFile(currentXcodeProjectFile).wait();

var newXcodeProjectFile = this.buildPathToXcodeProjectFile(newVersion);
var newXcodeProjectFileContent = this.$fs.readFile(newXcodeProjectFile).wait();

return currentXcodeProjectFileContent === newXcodeProjectFileContent;

}).future<boolean>()();
}

public updatePlatform(currentVersion: string, newVersion: string): IFuture<void> {
return (() => {
// Copy old file to options["profile-dir"]
var sourceFile = path.join(this.platformData.projectRoot, util.format("%s.xcodeproj", this.$projectData.projectName));
var destinationFile = path.join(options.profileDir, "xcodeproj");
this.$fs.deleteDirectory(destinationFile).wait();
shell.cp("-R", path.join(sourceFile, "*"), destinationFile);
this.$logger.info("Backup file %s at location %s", sourceFile, destinationFile);
this.$fs.deleteDirectory(path.join(this.platformData.projectRoot, util.format("%s.xcodeproj", this.$projectData.projectName))).wait();

// Copy xcodeProject file
var cachedPackagePath = path.join(this.$npm.getCachedPackagePath(this.platformData.frameworkPackageName, newVersion), constants.PROJECT_FRAMEWORK_FOLDER_NAME, util.format("%s.xcodeproj", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER));
shell.cp("-R", path.join(cachedPackagePath, "*"), path.join(this.platformData.projectRoot, util.format("%s.xcodeproj", this.$projectData.projectName)));
this.$logger.info("Copied from %s at %s.", cachedPackagePath, this.platformData.projectRoot);


var pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
this.replaceFileContent(pbxprojFilePath).wait();
}).future<void>()();
}

private buildPathToXcodeProjectFile(version: string): string {
return path.join(this.$npm.getCachedPackagePath(this.platformData.frameworkPackageName, version), constants.PROJECT_FRAMEWORK_FOLDER_NAME, util.format("%s.xcodeproj", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER), "project.pbxproj");
}

private validateDynamicFramework(libraryPath: string): IFuture<void> {
return (() => {
Expand Down
97 changes: 65 additions & 32 deletions lib/services/platform-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ export class PlatformService implements IPlatformService {
this.$errors.fail("No platform specified.")
}

platform = platform.toLowerCase();
var parts = platform.split("@");
platform = parts[0].toLowerCase();

if (!this.isValidPlatform(platform)) {
this.$errors.fail("Invalid platform %s. Valid platforms are %s.", platform, helpers.formatListOfNames(this.$platformsData.platformsNames));
Expand Down Expand Up @@ -442,19 +443,28 @@ export class PlatformService implements IPlatformService {
var currentVersion = data && data.version ? data.version : "0.2.0";
var newVersion = version || this.$npm.getLatestVersion(platformData.frameworkPackageName).wait();

if(!semver.valid(newVersion)) {
this.$errors.fail("The version %s is not valid. The version should consists from 3 parts seperated by dot.", newVersion);
}
if(platformData.platformProjectService.canUpdatePlatform(currentVersion, newVersion).wait()) {

if(semver.gt(currentVersion, newVersion)) { // Downgrade
var isUpdateConfirmed = this.$prompter.confirm("You are going to update to lower version. Are you sure?", () => "n").wait();
if(isUpdateConfirmed) {
if(!semver.valid(newVersion)) {
this.$errors.fail("The version %s is not valid. The version should consists from 3 parts separated by dot.", newVersion);
}

if(semver.gt(currentVersion, newVersion)) { // Downgrade
var isUpdateConfirmed = this.$prompter.confirm(util.format("You are going to downgrade to android runtime v.%s. Are you sure?", newVersion), () => "n").wait();
if(isUpdateConfirmed) {
this.updatePlatformCore(platformData, currentVersion, newVersion).wait();
}
} else if(semver.eq(currentVersion, newVersion)) {
this.$errors.fail("Current and new version are the same.");
} else {
this.updatePlatformCore(platformData, currentVersion, newVersion).wait();
}
} else if(semver.eq(currentVersion, newVersion)) {
this.$errors.fail("Current and new version are the same.");
} else {
this.updatePlatformCore(platformData, currentVersion, newVersion).wait();
var isUpdateConfirmed = this.$prompter.confirm(util.format("We need to override xcodeproj file. The old one will be saved at %s. Are you sure?", options.profileDir), () => "y").wait();
if(isUpdateConfirmed) {
platformData.platformProjectService.updatePlatform(currentVersion, newVersion).wait();
this.updatePlatformCore(platformData, currentVersion, newVersion).wait();
}
}

}).future<void>()();
Expand All @@ -463,16 +473,36 @@ export class PlatformService implements IPlatformService {
private updatePlatformCore(platformData: IPlatformData, currentVersion: string, newVersion: string): IFuture<void> {
return (() => {
// Remove old framework files
var oldFrameworkFiles = this.getFrameworkFiles(platformData, currentVersion).wait();
_.each(oldFrameworkFiles, file => {
this.$fs.deleteFile(path.join(platformData.projectRoot, file)).wait();
var oldFrameworkData = this.getFrameworkFiles(platformData, currentVersion).wait();

_.each(oldFrameworkData.frameworkFiles, file => {
var fileToDelete = path.join(platformData.projectRoot, file);
this.$logger.trace("Deleting %s", fileToDelete);
this.$fs.deleteFile(fileToDelete).wait();
});

_.each(oldFrameworkData.frameworkDirectories, dir => {
var dirToDelete = path.join(platformData.projectRoot, dir);
this.$logger.trace("Deleting %s", dirToDelete);
this.$fs.deleteDirectory(dirToDelete).wait();
});

// Add new framework files
var newFrameworkFiles = this.getFrameworkFiles(platformData, newVersion).wait();
var cacheDirectoryPath = this.getNpmCacheDirectoryCore(platformData.frameworkPackageName, newVersion);
_.each(newFrameworkFiles, file => {
shell.cp("-f", path.join(cacheDirectoryPath, file), path.join(platformData.projectRoot, file));
var newFrameworkData = this.getFrameworkFiles(platformData, newVersion).wait();
var cacheDirectoryPath = this.$npm.getCachedPackagePath(platformData.frameworkPackageName, newVersion);

_.each(newFrameworkData.frameworkFiles, file => {
var sourceFile = path.join(cacheDirectoryPath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, file);
var destinationFile = path.join(platformData.projectRoot, file);
this.$logger.trace("Replacing %s with %s", sourceFile, destinationFile);
shell.cp("-f", sourceFile, destinationFile);
});

_.each(newFrameworkData.frameworkDirectories, dir => {
var sourceDirectory = path.join(cacheDirectoryPath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, dir);
var destinationDirectory = path.join(platformData.projectRoot, dir);
this.$logger.trace("Copying %s to %s", sourceDirectory, destinationDirectory);
shell.cp("-fR", path.join(sourceDirectory, "*"), destinationDirectory);
});

// Update .tnsproject file
Expand All @@ -484,32 +514,35 @@ export class PlatformService implements IPlatformService {
}).future<void>()();
}

private getFrameworkFiles(platformData: IPlatformData, version: string): IFuture<string[]> {
private getFrameworkFiles(platformData: IPlatformData, version: string): IFuture<any> {
return (() => {
var npmCacheDirectoryPath = this.getNpmCacheDirectory(platformData.frameworkPackageName, version).wait();
var allFiles = this.$fs.enumerateFilesInDirectorySync(npmCacheDirectoryPath);
var cachedPackagePath = this.$npm.getCachedPackagePath(platformData.frameworkPackageName, version);
this.ensurePackageIsCached(cachedPackagePath, platformData.frameworkPackageName, version).wait();

var allFiles = this.$fs.enumerateFilesInDirectorySync(cachedPackagePath);
var filteredFiles = _.filter(allFiles, file => _.contains(platformData.frameworkFilesExtensions, path.extname(file)));
var relativeToCacheFiles = _.map(filteredFiles, file => file.substr(npmCacheDirectoryPath.length));

return relativeToCacheFiles;
var allFrameworkDirectories = _.map(this.$fs.readDirectory(path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME)).wait(), dir => path.join(cachedPackagePath, constants.PROJECT_FRAMEWORK_FOLDER_NAME, dir));
var filteredFrameworkDirectories = _.filter(allFrameworkDirectories, dir => this.$fs.getFsStats(dir).wait().isDirectory() && (_.contains(platformData.frameworkFilesExtensions, path.extname(dir)) || _.contains(platformData.frameworkDirectoriesNames, path.basename(dir))));

}).future<string[]>()();
return {
frameworkFiles: this.mapFrameworkFiles(cachedPackagePath, filteredFiles),
frameworkDirectories: this.mapFrameworkFiles(cachedPackagePath, filteredFrameworkDirectories)
}

}).future<any>()();
}

private getNpmCacheDirectory(packageName: string, version: string): IFuture<string> {
private ensurePackageIsCached(cachedPackagePath: string, packageName: string, version: string): IFuture<void> {
return (() => {
var npmCacheDirectoryPath = this.getNpmCacheDirectoryCore(packageName, version);

if(!this.$fs.exists(npmCacheDirectoryPath).wait()) {
if(!this.$fs.exists(cachedPackagePath).wait()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider removing this check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking about it, but I can't figure out a better solution. I'm opened to any suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

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

After talking in person, we agreed on the current code.

this.$npm.addToCache(packageName, version).wait();
}

return npmCacheDirectoryPath;
}).future<string>()();
}).future<void>()();
}

private getNpmCacheDirectoryCore(packageName: string, version: string): string {
return path.join(this.$npm.getCacheRootPath(), packageName, version, "package");
private mapFrameworkFiles(npmCacheDirectoryPath: string, files: string[]): string[] {
return _.map(files, file => file.substr(npmCacheDirectoryPath.length + constants.PROJECT_FRAMEWORK_FOLDER_NAME.length + 1))
}
}
$injector.register("platformService", PlatformService);
10 changes: 10 additions & 0 deletions test/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ export class NPMStub implements INodePackageManager {
getLatestVersion(packageName: string): IFuture<string> {
return Future.fromResult("");
}

getCachedPackagePath(packageName: string, version: string): string {
return "";
}
}

export class ProjectDataStub implements IProjectData {
Expand Down Expand Up @@ -273,6 +277,12 @@ export class PlatformProjectServiceStub implements IPlatformProjectService {
addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void> {
return Future.fromResult();
}
canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean> {
return Future.fromResult(false);
}
updatePlatform(currentVersion: string, newVersion: string): IFuture<void> {
return Future.fromResult();
}
}

export class ProjectDataService implements IProjectDataService {
Expand Down