Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Commit 87df46a

Browse files
committed
feat: Working CLI (install skeletons)
1 parent 8d49560 commit 87df46a

File tree

7 files changed

+192
-16
lines changed

7 files changed

+192
-16
lines changed

gulpfile.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ gulp.task("dist", ["prepare:clean"], function(done) {
156156
done)
157157
});
158158

159+
gulp.task("dev-cli", [], function(done) {
160+
runSequence("prepare:js")
161+
return result = gulp.watch("src/**/**", done => {
162+
return runSequence("prepare:js")
163+
})
164+
});
165+
159166
gulp.task("prepare:es6-index", () => {
160167
const contents = `
161168
const path = require("path");

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"ieee754": "^1.1.8",
8888
"inquirer": "^3.0.6",
8989
"lego-api": "^1.0.7",
90+
"minimist": "^1.2.0",
9091
"mustache": "^2.3.0",
9192
"node-sass": "^4.9.0",
9293
"postcss": "^6.0.1",

src/cli/FuseFileExecution.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ export class FuseFileExecution {
44
public static test(){
55
console.log(process.cwd());
66
}
7+
8+
public install(){
9+
console.log(this.args);
10+
console.log("install");
11+
}
712
public static init(args : any){
13+
console.log("init", args);
814
return new FuseFileExecution(args);
915
}
1016
}

src/cli/Help.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as log from "./log";
2+
3+
export class Help {
4+
constructor(args) {
5+
log.help({
6+
"install --search [name]" : "Searches for a skeleton (or lists them)",
7+
"install [name]" : "Install skeleton into the current folder",
8+
"install [name] [dir]" : "Install skeleton into the specific directory",
9+
"install --update" : "Updates the skeleton repository",
10+
})
11+
}
12+
}

src/cli/Install.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import * as path from "path";
2+
import * as fsExtra from "fs-extra";
3+
import * as fs from "fs";
4+
import { exec } from "child_process";
5+
import * as log from "./log";
6+
7+
const HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
8+
const REPOSITORY_PATH = path.join(HOME, '.fuse-box', 'bootstrap-collection');
9+
const SKELETONS = path.join(REPOSITORY_PATH, 'skeletons');
10+
function listProjects(dirname) {
11+
const results = fs.readdirSync(dirname).filter(function (file) {
12+
return fs.statSync(path.join(dirname, file)).isDirectory();
13+
});
14+
const output = [];
15+
results.forEach(dir => {
16+
const absPath = path.join(dirname, dir);
17+
const packageJSON = path.join(absPath, "package.json");
18+
if (fs.existsSync(packageJSON)) {
19+
const json = require(packageJSON);
20+
output.push({ dir: absPath, json: json })
21+
}
22+
});
23+
return output;
24+
}
25+
26+
export class Install {
27+
constructor(args) {
28+
const major = args._;
29+
if (major.length === 0) {
30+
if (args.update) {
31+
this.update();
32+
} else {
33+
this.search(args.search);
34+
}
35+
} else {
36+
this.install(major[0], major[1])
37+
}
38+
}
39+
40+
private async update() {
41+
await this.verifyRepository()
42+
await this.pullRepository();
43+
}
44+
45+
private async pullRepository() {
46+
return new Promise((resolve, reject) => {
47+
fsExtra.ensureDirSync(REPOSITORY_PATH);
48+
log.info("pulling https://github.com/fuse-box/bootstrap-collection")
49+
exec("git pull",
50+
{ cwd: REPOSITORY_PATH },
51+
(error, stdout, stderr) => {
52+
if (error) {
53+
return reject(error);
54+
}
55+
log.info("Pulled successfully")
56+
return resolve();
57+
})
58+
});
59+
}
60+
private cloneRepository() {
61+
return new Promise((resolve, reject) => {
62+
fsExtra.ensureDirSync(REPOSITORY_PATH);
63+
log.info("Cloning https://github.com/fuse-box/bootstrap-collection")
64+
exec("git clone https://github.com/fuse-box/bootstrap-collection .",
65+
{ cwd: REPOSITORY_PATH },
66+
(error, stdout, stderr) => {
67+
if (error) {
68+
return reject(error);
69+
}
70+
log.info("Cloned successfully")
71+
return resolve();
72+
})
73+
});
74+
75+
}
76+
private async verifyRepository() {
77+
if (!fs.existsSync(REPOSITORY_PATH)) {
78+
log.info("Repository not found")
79+
this.cloneRepository();
80+
}
81+
}
82+
83+
private async search(searchName?: string) {
84+
log.info("Listing available skeletons")
85+
await this.verifyRepository();
86+
const projects = listProjects(SKELETONS);
87+
const results = projects.filter(item => {
88+
if (typeof searchName !== "string") return item;
89+
if (item.json.name.toLowerCase().indexOf(searchName.toLowerCase()) > -1) {
90+
return item;
91+
}
92+
});
93+
results.forEach(item => {
94+
log.title(item.json.name);
95+
log.desc(item.json.description);
96+
})
97+
}
98+
99+
private async install(name: string, targetPath: string) {
100+
log.info(`Installing ${name}`);
101+
const projects = listProjects(SKELETONS);
102+
const result = projects.filter(item => {
103+
if (item.json.name.toLowerCase().indexOf(name.toLowerCase()) > -1) {
104+
return item;
105+
}
106+
});
107+
if (!result.length) {
108+
return log.error("Skeleton was not found. Try 'fuse install --search'")
109+
}
110+
if (result.length > 1) {
111+
return log.error("More than one repository found")
112+
}
113+
const item = result[0];
114+
const source = item.dir;
115+
targetPath = path.join(process.cwd(), targetPath ? targetPath : item.json.name);
116+
if (fs.existsSync(targetPath)) {
117+
log.error(`Directory ${targetPath} exists`);
118+
log.error(`Choose a different one by typing:`)
119+
log.info(`fuse install "${name}" dirname`);
120+
return;
121+
}
122+
log.info(`Copying to ${targetPath}`);
123+
await fsExtra.copy(source, targetPath)
124+
log.info(`Done!`);
125+
log.info(` cd ${targetPath};`);
126+
log.info(` yarn;`);
127+
}
128+
}

src/cli/entry.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
1-
#!/usr/bin/env node
1+
#! /usr/bin/env node
2+
const argv = require('minimist')(process.argv.slice(2));
3+
import { Install } from './Install';
4+
import { Help } from './Help';
25

3-
import * as yargs from "yargs";
4-
import { FuseFileExecution } from './FuseFileExecution';
5-
6-
const SYSTEM_ARGS = ["boostrap", "snippet", "run"];
6+
const CMD = {
7+
"install": Install,
8+
'help': Help
9+
}
10+
function extractParams(args) {
711

8-
function extractParams(args){
9-
const primaryArgs = args._;
10-
const firstPrimaryArg = primaryArgs[0];
11-
return {
12-
primary : firstPrimaryArg,
13-
args : args,
14-
isSystemArgument : () => SYSTEM_ARGS.indexOf(firstPrimaryArg) > -1
12+
if (args.help) {
13+
return new Help(args)
1514
}
15+
args._.forEach((name, index) => {
16+
if (CMD[name]) {
17+
args._ = args._.splice(index + 1)
18+
return new CMD[name](args)
19+
}
20+
});
1621
}
1722
function initCLI() {
18-
const args = extractParams(yargs.args);
19-
if( !args.primary || !args.isSystemArgument() && FuseFileExecution.test()){
20-
return FuseFileExecution.init(args);
21-
}
23+
extractParams(argv);
2224
}
2325
initCLI();

src/cli/log.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as chalk from "chalk";
2+
3+
export function info(text: string) {
4+
console.log(chalk.gray(` : ${text}`));
5+
}
6+
export function help(obj: any) {
7+
for (const cmd in obj) {
8+
console.log(' ' + chalk.green.bold(cmd));
9+
console.log(chalk.gray(` ${obj[cmd]}`));
10+
}
11+
}
12+
export function error(text: string) {
13+
console.log(chalk.bold.red(` : ${text}`));
14+
}
15+
export function title(text: string) {
16+
console.log(chalk.bold.green(` ${text}`));
17+
}
18+
export function desc(text: string) {
19+
console.log(chalk.gray(` - ${text}`));
20+
}

0 commit comments

Comments
 (0)