Skip to content

Fix ENOENT error when add ios platform #1073

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
Oct 19, 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
1 change: 1 addition & 0 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface INpmInstallationManager {
cacheUnpack(packageName: string, version: string, unpackTarget?: string): IFuture<void>;
install(packageName: string, options?: INpmInstallOptions): IFuture<string>;
getLatestVersion(packageName: string): IFuture<string>;
getLatestCompatibleVersion(packageName: string): IFuture<string>;
getCachedPackagePath(packageName: string, version: string): string;
addCleanCopyToCache(packageName: string, version: string): IFuture<void>;
}
Expand Down
37 changes: 35 additions & 2 deletions lib/npm-installation-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import semver = require("semver");
import * as npm from "npm";
import * as constants from "./constants";

interface IVersionData {
Copy link
Contributor

Choose a reason for hiding this comment

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

Some JSDocs would be much welcome

major: string;
minor: string;
patch: string;
}

export class NpmInstallationManager implements INpmInstallationManager {
private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later.";
private versionsCache: IDictionary<string[]>;
Expand All @@ -20,7 +26,8 @@ export class NpmInstallationManager implements INpmInstallationManager {
private $lockfile: ILockFile,
private $errors: IErrors,
private $options: IOptions,
private $fs: IFileSystem) {
private $fs: IFileSystem,
private $staticConfig: IStaticConfig) {
this.versionsCache = {};
this.$npm.load().wait();
}
Expand Down Expand Up @@ -63,6 +70,27 @@ export class NpmInstallationManager implements INpmInstallationManager {
}).future<string>()();
}

public getLatestCompatibleVersion(packageName: string): IFuture<string> {
return (() => {
let latestVersion = this.getLatestVersion(packageName).wait();
let data = this.$npm.view(packageName, "versions").wait();
let versions: string[] = data[latestVersion].versions;

let versionData = this.getVersionData(this.$staticConfig.version);

let compatibleVersions = _(versions)
.map(ver => this.getVersionData(ver))
.filter(verData => versionData.major === verData.major && versionData.minor === verData.minor)
.sortBy(verData => verData.patch)
.value();

let result = _.last(compatibleVersions);

let latestCompatibleVersion = `${result.major}.${result.minor}.${result.patch}`;
return latestCompatibleVersion;
}).future<string>()();
}

public install(packageName: string, opts?: INpmInstallOptions): IFuture<string> {
return (() => {
this.$lockfile.lock().wait();
Expand Down Expand Up @@ -131,7 +159,7 @@ export class NpmInstallationManager implements INpmInstallationManager {
}
return this.$options.frameworkPath;
} else {
version = version || this.getLatestVersion(packageName).wait();
version = version || this.getLatestCompatibleVersion(packageName).wait();
let packagePath = this.getCachedPackagePath(packageName, version);
this.addToCache(packageName, version).wait();
return packagePath;
Expand Down Expand Up @@ -163,5 +191,10 @@ export class NpmInstallationManager implements INpmInstallationManager {
return this.$fs.exists(directory).wait() && this.$fs.enumerateFilesInDirectorySync(directory).length > 0;
}).future<boolean>()();
}

private getVersionData(version: string): IVersionData {
let [ major, minor, patch ] = version.split(".");
return { major, minor, patch };
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The code is correct, but could be made more concise:

let [ major, minor, patch ] = version.split(".")
return { major, minor, patch }

}
$injector.register("npmInstallationManager", NpmInstallationManager);
2 changes: 1 addition & 1 deletion lib/services/init-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class InitService implements IInitService {

private getVersionData(packageName: string): IFuture<IStringDictionary> {
return (() => {
let latestVersion = this.$npmInstallationManager.getLatestVersion(packageName).wait();
let latestVersion = this.$npmInstallationManager.getLatestCompatibleVersion(packageName).wait();
if(this.useDefaultValue) {
return this.buildVersionData(latestVersion);
}
Expand Down
95 changes: 95 additions & 0 deletions test/npm-installation-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/// <reference path=".d.ts" />
"use strict";

import {assert} from "chai";
import * as ConfigLib from "../lib/config";
import * as ErrorsLib from "../lib/common/errors";
import * as FsLib from "../lib/common/file-system";
import * as HostInfoLib from "../lib/common/host-info";
import * as LoggerLib from "../lib/common/logger";
import * as NpmInstallationManagerLib from "../lib/npm-installation-manager";
import * as OptionsLib from "../lib/options";
import * as StaticConfigLib from "../lib/config";

import Future = require("fibers/future");
import yok = require("../lib/common/yok");

function createTestInjector(): IInjector {
let testInjector = new yok.Yok();

testInjector.register("config", ConfigLib.Configuration);
testInjector.register("logger", LoggerLib.Logger);
testInjector.register("lockfile", { });
testInjector.register("errors", ErrorsLib.Errors);
testInjector.register("options", OptionsLib.Options);
testInjector.register("fs", FsLib.FileSystem);
testInjector.register("hostInfo", HostInfoLib.HostInfo);
testInjector.register("staticConfig", StaticConfigLib.StaticConfig);

testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);

return testInjector;
}

function mockNpm(testInjector: IInjector, versions: string[], latestVersion: string) {
testInjector.register("npm", {
view: (packageName: string, propertyName: string) => {
return (() => {
if(propertyName === "versions") {
let result = Object.create(null);
result[latestVersion] = {
"versions": versions
};

return result;
}

throw new Error(`Unable to find propertyName ${propertyName}.`);
}).future<any>()();
},
load: () => Future.fromResult()
});
}

describe("Npm installation manager tests", () => {
it("returns correct latest compatible version when only one exists", () => {
let testInjector = createTestInjector();

let versions = ["1.4.0"];
let latestVersion = "1.4.0";

mockNpm(testInjector, versions, latestVersion);

// Mock staticConfig.version
let staticConfig = testInjector.resolve("staticConfig");
staticConfig.version = "1.4.0";

// Mock npmInstallationManager.getLatestVersion
let npmInstallationManager = testInjector.resolve("npmInstallationManager");
npmInstallationManager.getLatestVersion = (packageName: string) => Future.fromResult(latestVersion);

let actualLatestCompatibleVersion = npmInstallationManager.getLatestCompatibleVersion("").wait();
let expectedLatestCompatibleVersion = "1.4.0";
assert.equal(actualLatestCompatibleVersion, expectedLatestCompatibleVersion);
});
it("returns correct latest compatible version", () => {
let testInjector = createTestInjector();

let versions = ["1.2.0", "1.3.0", "1.3.1", "1.3.2", "1.3.3", "1.4.0"];
let latestVersion = "1.3.3";

mockNpm(testInjector, versions, latestVersion);

// Mock staticConfig.version
let staticConfig = testInjector.resolve("staticConfig");
staticConfig.version = "1.3.0";

// Mock npmInstallationManager.getLatestVersion
let npmInstallationManager = testInjector.resolve("npmInstallationManager");
npmInstallationManager.getLatestVersion = (packageName: string) => Future.fromResult(latestVersion);

let actualLatestCompatibleVersion = npmInstallationManager.getLatestCompatibleVersion("").wait();
let expectedLatestCompatibleVersion = "1.3.3";
assert.equal(actualLatestCompatibleVersion, expectedLatestCompatibleVersion);
});
});
4 changes: 4 additions & 0 deletions test/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ export class NpmInstallationManagerStub implements INpmInstallationManager {
return Future.fromResult("");
}

getLatestCompatibleVersion(packageName: string): IFuture<string> {
return Future.fromResult("");
}

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