Skip to content

Commit

Permalink
Merge pull request #56 from SAP/getNpmPaths
Browse files Browse the repository at this point in the history
overide env.getNpmPaths
  • Loading branch information
slavik-lvovsky authored Dec 23, 2019
2 parents 56faaf4 + bcc7636 commit c5853ee
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 36 deletions.
8 changes: 4 additions & 4 deletions backend/.nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"temp-dir": "./reports/.nyc_output",
"report-dir": "./reports/coverage",
"check-coverage": true,
"branches": 22,
"lines": 41,
"functions": 30,
"statements": 41
"branches": 29,
"lines": 44,
"functions": 33,
"statements": 44
}
4 changes: 2 additions & 2 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "Apache 2.0",
"description": "Provide rich user experience for Yeoman generators using VSCode extension or the browser",
"repository": "https://github.com/SAP/yeoman-ui",
"version": "0.0.12",
"version": "0.0.13",
"engines": {
"vscode": "^1.38.0"
},
Expand Down Expand Up @@ -52,7 +52,7 @@
"lodash": "^4.17.15",
"strip-ansi": "^6.0.0",
"ws": "^7.2.0",
"yeoman-environment": "^2.6.0",
"yeoman-environment": "^2.7.0",
"fs-extra": "^8.1.0"
},
"devDependencies": {
Expand Down
35 changes: 27 additions & 8 deletions backend/src/yeomanui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export class YeomanUI {
private static defaultMessage =
"Some quick example text of the generator description. This is a long text so that the example will look good.";
private static YEOMAN_PNG = "yeoman.png";
private static isWin32 = (process.platform === 'win32');
private static CWD = path.join(os.homedir(), 'projects');
private static NODE_MODULES = 'node_modules';

private rpc: IRpc;
private logger: YouiLog;
Expand Down Expand Up @@ -74,20 +77,36 @@ export class YeomanUI {
// on the other hand, we never look for newly installed generators...

const promise: Promise<IPrompt> = new Promise(resolve => {
const env: Environment.Options = Environment.createEnv();
const env: Environment.Options = this.getEnv();
env.lookup(async () => this.onEnvLookup(env, resolve, this.genFilter));
});

return promise;
}

public async runGenerator(generatorName: string) {
private getEnv(): Environment.Options {
const env: Environment.Options = Environment.createEnv();
const envGetNpmPaths: () => any = env.getNpmPaths;
env.getNpmPaths = function (localOnly:boolean = false) {
// Start with the local paths derived by cwd in vscode
// (as opposed to cwd of the plugin host process which is what is used by yeoman/environment)
// Walk up the CWD and add `node_modules/` folder lookup on each level
const parts: string[] = YeomanUI.CWD.split(path.sep);
const localPaths = _.map(parts, (part, index) => {
const resrpath = path.join(...parts.slice(0, index + 1), YeomanUI.NODE_MODULES);
return YeomanUI.isWin32 ? resrpath : path.join(path.sep, resrpath);

// TODO: ensure projects folder exist
const destinationRoot: string = path.join(os.homedir(), "projects");
});
const defaultPaths = envGetNpmPaths.call(this, localOnly);

return _.uniq(localPaths.concat(defaultPaths));
};
return env;
}

public async runGenerator(generatorName: string) {
// TODO: wait for dir to be created
fs.mkdir(destinationRoot, { recursive: true }, (err) => {
fs.mkdir(YeomanUI.CWD, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
Expand Down Expand Up @@ -128,7 +147,7 @@ export class YeomanUI {

this.promptCount = 0;
this.gen = (gen as Generator);
this.gen.destinationRoot(destinationRoot);
this.gen.destinationRoot(YeomanUI.CWD);
/* Generator.run() returns promise. Sending a callback is deprecated:
https://yeoman.github.io/generator/Generator.html#run
... but .d.ts hasn't been updated for a while:
Expand All @@ -142,7 +161,7 @@ export class YeomanUI {
}

console.log("done running yeomanui");
message = `${generatorName} is done. Destination directory is ${destinationRoot}`;
message = `The '${generatorName}' project has been generated. You can find it at ${YeomanUI.CWD}`;
this.doGeneratorDone(true, message);
});
} catch (err) {
Expand Down Expand Up @@ -212,7 +231,7 @@ export class YeomanUI {
message: "",
choices: _.compact(generatorChoices)
};
resolve({ name: "Generator Selection", questions: [generatorQuestion] });
resolve({ name: "Select Generator", questions: [generatorQuestion] });
}

private async getGeneratorChoice(genName: string, filter?: GeneratorFilter): Promise<IGeneratorChoice | undefined> {
Expand Down
77 changes: 73 additions & 4 deletions backend/tests/yeomanui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ describe('yeomanui unit test', () => {
}
}

const rpc = new TestRpc();
const logger = new TestLog();
const yeomanUi: YeomanUI = new YeomanUI(rpc, logger);

before(() => {
sandbox = sinon.createSandbox();
});
Expand All @@ -105,9 +109,6 @@ describe('yeomanui unit test', () => {
});

describe("getGenerators", () => {
const rpc = new TestRpc();
const logger = new TestLog();
const yeomanUi: YeomanUI = new YeomanUI(rpc, logger);
let envMock: any;

const environment = {
Expand Down Expand Up @@ -139,7 +140,7 @@ describe('yeomanui unit test', () => {
message: "",
choices: []
};
expect(result).to.be.deep.equal({ name: "Generator Selection", questions: [generatorQuestion] });
expect(result).to.be.deep.equal({ name: "Select Generator", questions: [generatorQuestion] });
});

it("get generators with type project", async () => {
Expand Down Expand Up @@ -340,4 +341,72 @@ describe('yeomanui unit test', () => {
expect(test3Choice.name).to.be.equal("test4");
});
});

describe("getEnv", () => {
const yeomanUi: YeomanUI = new YeomanUI(rpc, logger);
const testEnv = yeomanUi["getEnv"]();
const nodemodules = YeomanUI["NODE_MODULES"];
testEnv.getNpmPaths = (localOnly: boolean = false): string[] => {
return localOnly ?
[path.join("localPath1", nodemodules), path.join("localPath2", nodemodules)] :
[path.join("path1", nodemodules), path.join("path2", nodemodules), path.join("localPath1", nodemodules), path.join("localPath2", nodemodules)];
};

beforeEach(() => {
YeomanUI["CWD"] = path.join("root/project/folder");
yeomanEnvMock.expects("createEnv").returns(testEnv);
});

it("env.getNpmPaths - localOnly is false, isWin32 is true", () => {
YeomanUI["isWin32"] = true;
const env = yeomanUi["getEnv"]();
const res = env.getNpmPaths();
expect(res).to.have.lengthOf(7);
expect(res).to.include(path.join("root", nodemodules));
expect(res).to.include(path.join("root", "project", nodemodules));
expect(res).to.include(path.join("root", "project", "folder", nodemodules));
expect(res).to.include(path.join("path1", nodemodules));
expect(res).to.include(path.join("path2", nodemodules));
expect(res).to.include(path.join("localPath1", nodemodules));
expect(res).to.include(path.join("localPath2", nodemodules));
});

it("env.getNpmPaths - localOnly is true, isWin32 is true", () => {
YeomanUI["isWin32"] = true;
const env = yeomanUi["getEnv"]();
const res = env.getNpmPaths(true);
expect(res).to.have.lengthOf(5);
expect(res).to.include(path.join("root", nodemodules));
expect(res).to.include(path.join("root", "project", nodemodules));
expect(res).to.include(path.join("root", "project", "folder", nodemodules));
expect(res).to.include(path.join("localPath1", nodemodules));
expect(res).to.include(path.join("localPath2", nodemodules));
});

it("env.getNpmPaths - localOnly is false, isWin32 is false", () => {
YeomanUI["isWin32"] = false;
const env = yeomanUi["getEnv"]();
const res = env.getNpmPaths();
expect(res).to.have.lengthOf(7);
expect(res).to.include(path.join(path.sep, "root", nodemodules));
expect(res).to.include(path.join(path.sep, "root", "project", nodemodules));
expect(res).to.include(path.join(path.sep, "root", "project", "folder", nodemodules));
expect(res).to.include(path.join("path1", nodemodules));
expect(res).to.include(path.join("path2", nodemodules));
expect(res).to.include(path.join("localPath1", nodemodules));
expect(res).to.include(path.join("localPath2", nodemodules));
});

it("env.getNpmPaths - localOnly is true, isWin32 is false", () => {
YeomanUI["isWin32"] = false;
const env = yeomanUi["getEnv"]();
const res = env.getNpmPaths(true);
expect(res).to.have.lengthOf(5);
expect(res).to.include(path.join(path.sep, "root", nodemodules));
expect(res).to.include(path.join(path.sep, "root", "project", nodemodules));
expect(res).to.include(path.join(path.sep, "root", "project", "folder", nodemodules));
expect(res).to.include(path.join("localPath1", nodemodules));
expect(res).to.include(path.join("localPath2", nodemodules));
});
});
});
4 changes: 2 additions & 2 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export default {
delete currentPrompt.status
}
} else {
// first prompt (Generator Selection)
// first prompt (Select Generator)
prompt.active = true
this.prompts.push(prompt)
}
Expand Down Expand Up @@ -253,7 +253,7 @@ export default {
},
generatorDone(success, message) {
if (this.currentPrompt.status === "pending") {
this.currentPrompt.name = "Done"
this.currentPrompt.name = "Confirmation"
}
this.doneMessage = message
this.isDone = true
Expand Down
6 changes: 1 addition & 5 deletions frontend/src/components/Header.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<template>
<div>
<b-navbar>
<b-navbar-brand>Yeoman UI Wizzard: {{generatorName}}</b-navbar-brand>

<b-navbar-nav>
<b-nav-text>{{ stepName }}</b-nav-text>
</b-navbar-nav>
<b-navbar-brand>Yeoman UI Wizard: {{generatorName}}</b-navbar-brand>

<!-- Right aligned nav items -->
<b-navbar-nav class="ml-auto">
Expand Down
2 changes: 1 addition & 1 deletion frontend/tests/App.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ describe('App.vue', () => {

expect(wrapper.vm.doneMessage).toBe('testMessage')
expect(wrapper.vm.isDone).toBeTruthy()
expect(wrapper.vm.currentPrompt.name).toBe('Done')
expect(wrapper.vm.currentPrompt.name).toBe('Confirmation')
})
})
})
11 changes: 1 addition & 10 deletions frontend/tests/components/Header.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,7 @@ describe('Header.vue', () => {
test('generator brand', () => {
const testGen = 'testGenerator'
wrapper = initComponent(Header, { generatorName: testGen })
expect(wrapper.find(BNavbarBrand).text()).toBe(`Yeoman UI Wizzard: ${testGen}`)
})

test('find step text and step text name', () => {
const testPrompt = 'testPrompt'
const testStepName = 'testStepName'
const testNumOfSteps = 3
wrapper = initComponent(Header, { stepName: testStepName })
const bNavTexts = wrapper.findAll(BNavText)
expect(bNavTexts.wrappers[0].element.textContent).toBe(`${testStepName}`)
expect(wrapper.find(BNavbarBrand).text()).toBe(`Yeoman UI Wizard: ${testGen}`)
})

test('click triggers collapseLog method', async () => {
Expand Down

0 comments on commit c5853ee

Please sign in to comment.