Skip to content

Commit 8066627

Browse files
Install devDependencies before prepare
As our hooks (like typescript) are called before executing prepare method, we must be sure we have all devDependencies installed in order to be able to execute before-prepare hooks. This is mandatory for projects where typescript is enabled, but you do not have node_modules directory yet.
1 parent c579ae8 commit 8066627

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

lib/definitions/plugins.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ interface IPluginsService {
55
getAllInstalledPlugins(): IFuture<IPluginData[]>;
66
ensureAllDependenciesAreInstalled(): IFuture<void>;
77
afterPrepareAllPlugins(): IFuture<void>;
8+
/**
9+
* Installs all devDependencies of the project.
10+
* In case all of them are already installed, no operation will be executed.
11+
* In case any of them is missing, all of them will be installed.
12+
* @return {IFuture<void>}
13+
*/
14+
installDevDependencies(): IFuture<void>;
815
}
916

1017
interface IPluginData extends INodeModuleData {
@@ -53,6 +60,7 @@ interface IPluginVariablesService {
5360
* @return {IFuture<string>} returns the changed plugin configuration file content.
5461
*/
5562
getPluginVariablePropertyName(pluginData: IPluginData): string;
63+
5664
}
5765

5866
interface IPluginVariableData {

lib/services/platform-service.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,20 @@ export class PlatformService implements IPlatformService {
154154
}).future<string[]>()();
155155
}
156156

157-
@helpers.hook('prepare')
158157
public preparePlatform(platform: string): IFuture<void> {
159158
return (() => {
160159
this.validatePlatform(platform);
161160

161+
//Install dev-dependencies here, so before-prepare hooks will be executed correctly.
162+
this.$pluginsService.installDevDependencies().wait();
163+
164+
this.preparePlatformCore(platform).wait();
165+
}).future<void>()();
166+
}
167+
168+
@helpers.hook('prepare')
169+
private preparePlatformCore(platform: string): IFuture<void> {
170+
return (() => {
162171
platform = platform.toLowerCase();
163172
this.ensurePlatformInstalled(platform).wait();
164173

lib/services/plugins-service.ts

+16
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,22 @@ export class PluginsService implements IPluginsService {
185185
return this.executeForAllInstalledPlatforms(action);
186186
}
187187

188+
public installDevDependencies(): IFuture<void> {
189+
return (() => {
190+
let installedDependencies = this.$fs.exists(this.nodeModulesPath).wait() ? this.$fs.readDirectory(this.nodeModulesPath).wait() : [];
191+
let packageJsonContent = this.$fs.readJson(this.getPackageJsonFilePath()).wait();
192+
let devDependencies = _.keys(packageJsonContent.devDependencies);
193+
if(devDependencies.length && (this.$options.force || _.difference(devDependencies, installedDependencies).length)) {
194+
let command = `npm install ${devDependencies.join(" ")}`;
195+
if(this.$options.ignoreScripts) {
196+
command += "--ignore-scripts";
197+
}
198+
this.$logger.trace(`Command for installing devDependencies is: '${command}'.`);
199+
this.$childProcess.exec(command, { cwd: this.$projectData.projectDir }).wait();
200+
}
201+
}).future<void>()();
202+
}
203+
188204
private get nodeModulesPath(): string {
189205
return path.join(this.$projectData.projectDir, "node_modules");
190206
}

test/platform-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ function createTestInjector() {
4949
},
5050
ensureAllDependenciesAreInstalled: () => {
5151
return Future.fromResult();
52-
}
52+
},
53+
installDevDependencies: () => Future.fromResult()
5354
});
5455
testInjector.register("projectFilesManager", ProjectFilesManagerLib.ProjectFilesManager);
5556
testInjector.register("hooksService", stubs.HooksServiceStub);

0 commit comments

Comments
 (0)