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+ }
0 commit comments