@@ -7,57 +7,68 @@ const { red, green } = require('colors');
77const debug = require ( 'debug' ) ( 'fun:deploy' ) ;
88
99const frameworks = [
10+ // php
1011 require ( './thinkphp' ) ,
12+
13+ // java
1114 require ( './spring-boot' ) ,
15+
16+ // node
1217 require ( './nuxt' ) ,
1318 require ( './express' ) ,
1419 require ( './next' ) ,
15- require ( './hexo' )
20+ require ( './hexo' ) ,
21+
22+ // go
23+ require ( './go' )
1624] ;
1725
1826function resolvePath ( p ) {
1927 if ( _ . isArray ( p ) ) {
2028 return path . join ( ...p ) ;
21- }
29+ }
2230 return p ;
23-
2431}
2532
2633const runtimeCheckers = {
27- 'nodejs' : async ( codeDir ) => {
28- const stat = await fs . lstat ( codeDir ) ;
29-
30- if ( stat . isFile ( ) ) {
31- throw new Error ( 'file is not supported' ) ;
32- }
33-
34- const packageJsonPath = path . join ( codeDir , 'package.json' ) ;
35-
36- return await fs . pathExists ( packageJsonPath ) ;
34+ 'nodejs' : {
35+ 'type' : 'file' ,
36+ 'path' : 'package.json'
3737 } ,
38- 'java' : async ( codeDir ) => {
39- const stat = await fs . lstat ( codeDir ) ;
40-
41- if ( stat . isFile ( ) ) {
42- throw new Error ( 'file is not supported' ) ;
43- }
44-
45- const pomPath = path . join ( codeDir , 'pom.xml' ) ;
46-
47- return await fs . pathExists ( pomPath ) ;
38+ 'java' : {
39+ 'type' : 'file' ,
40+ 'path' : 'pom.xml'
4841 } ,
49- 'php' : async ( codeDir ) => {
50- const stat = await fs . lstat ( codeDir ) ;
42+ 'php' : {
43+ 'type' : 'file' ,
44+ 'path' : 'composer.json'
45+ } ,
46+ 'go' : {
47+ 'type' : 'file' ,
48+ 'paths' : [ 'go.mod' , 'Gopkg.toml' , [ 'vendor' , 'vendor.json' ] , [ 'Godeps' , 'Godeps.json' ] , / \. g o $ / ]
49+ }
50+ } ;
5151
52- if ( stat . isFile ( ) ) {
53- throw new Error ( 'file is not supported' ) ;
52+ async function parseRulePaths ( codeDir , rule ) {
53+ const rs = [ ] ;
54+ const paths = rule . paths || [ rule . path ] ;
55+ for ( const relativePath of paths ) {
56+ if ( _ . isRegExp ( relativePath ) ) {
57+ const pathRegex = relativePath ;
58+ const files = await fs . readdir ( codeDir ) ;
59+
60+ for ( const file of files ) {
61+ if ( pathRegex . test ( file ) ) {
62+ rs . push ( path . join ( codeDir , file ) ) ;
63+ }
64+ }
65+ } else {
66+ rs . push ( path . join ( codeDir , resolvePath ( relativePath ) ) ) ;
5467 }
55-
56- const pomPath = path . join ( codeDir , 'composer.json' ) ;
57-
58- return await fs . pathExists ( pomPath ) ;
5968 }
60- } ;
69+
70+ return rs ;
71+ }
6172
6273async function readJsonFile ( p ) {
6374 if ( ! await fs . pathExists ( p ) ) { return { success : false } ; }
@@ -86,45 +97,53 @@ async function checkJsonRule(codeDir, rule) {
8697 return _ . includes ( value , jsonValueContains ) ;
8798 }
8899 return true ;
89-
90100}
91101
92102async function checkContainsRule ( codeDir , rule ) {
93- const paths = rule . paths || [ rule . path ] ;
103+ const paths = await parseRulePaths ( codeDir , rule ) ;
94104 const content = rule . content ;
95- for ( const relativePath of paths ) {
96- const p = path . join ( codeDir , resolvePath ( relativePath ) ) ;
97-
105+ for ( const p of paths ) {
98106 if ( ! await fs . pathExists ( p ) ) { continue ; }
99107 const fileContent = await fs . readFile ( p , 'utf8' ) ;
100-
108+
101109 if ( _ . includes ( fileContent , content ) ) { return true ; }
102110 }
103111
104112 return false ;
105113}
106114
107115async function checkDirRule ( codeDir , rule ) {
108- const paths = rule . paths || [ rule . path ] ;
109- for ( const relativePath of paths ) {
110- const p = path . join ( codeDir , resolvePath ( relativePath ) ) ;
111-
112- if ( await fs . pathExists ( p ) ) { return true ; }
116+ const paths = await parseRulePaths ( codeDir , rule ) ;
117+
118+ for ( const p of paths ) {
119+ if ( await fs . pathExists ( p ) ) {
120+ const stat = await fs . stat ( p ) ;
121+ return stat . isDirectory ( ) ;
122+ }
123+ }
124+
125+ return false ;
126+ }
127+
128+ async function checkFileRule ( codeDir , rule ) {
129+ const paths = await parseRulePaths ( codeDir , rule ) ;
130+ for ( const f of paths ) {
131+ if ( await fs . pathExists ( f ) ) {
132+ const stat = await fs . stat ( f ) ;
133+ if ( stat . isFile ( ) ) { return true ; }
134+ }
113135 }
114136
115137 return false ;
116138}
117139
118140async function checkRegexRule ( codeDir , rule ) {
119- const paths = rule . paths || [ rule . path ] ;
141+ const paths = await parseRulePaths ( codeDir , rule ) ;
120142
121143 const regexContent = rule . content ;
122144 const regex = new RegExp ( regexContent , 'gm' ) ;
123145
124- if ( ! paths ) { return false ; }
125-
126- for ( const relativePath of paths ) {
127- const p = path . join ( codeDir , relativePath ) ;
146+ for ( const p of paths ) {
128147 if ( ! await fs . pathExists ( p ) ) { continue ; }
129148 const fileContent = await fs . readFile ( p ) ;
130149
@@ -147,6 +166,8 @@ async function checkRule(codeDir, rule) {
147166 return await checkContainsRule ( codeDir , rule ) ;
148167 case 'dir' :
149168 return await checkDirRule ( codeDir , rule ) ;
169+ case 'file' :
170+ return await checkFileRule ( codeDir , rule ) ;
150171 default :
151172 throw new Error ( `rule type ${ type } not supported` ) ;
152173 }
@@ -193,19 +214,19 @@ async function execProcessor(codeDir, processor) {
193214 p = path . join ( codeDir , p ) ;
194215
195216 await fs . ensureDir ( path . dirname ( p ) ) ;
196-
217+
197218 const mode = processor . mode ;
198219 const content = processor . content ;
199220
200221 console . log ( green ( 'Generating ' + p + '...' ) ) ;
201- if ( await fs . pathExists ( p ) ) {
222+ if ( await fs . pathExists ( p ) ) {
202223 const backup = processor . backup ;
203224 if ( _ . isNil ( backup ) || backup ) {
204225 console . warn ( red ( `File ${ p } already exists, Fun will rename to ${ p } .bak` ) ) ;
205226
206227 await fs . copyFile ( p , `${ p } .bak` , {
207228 overwrite : true
208- } ) ;
229+ } ) ;
209230 }
210231 }
211232
@@ -228,10 +249,14 @@ async function detectFramework(codeDir) {
228249 throw new Error ( 'could not found runtime checker' ) ;
229250 }
230251
231- const checkResult = await runtimeChecker ( codeDir ) ;
252+ const checkResult = await checkRule ( codeDir , runtimeChecker ) ;
232253
233254 if ( checkResult ) {
234255 const detectors = framework . detectors ;
256+
257+ // no need to detect
258+ if ( _ . isEmpty ( detectors ) ) { return framework ; }
259+
235260 const match = await checkRules ( codeDir , detectors ) ;
236261 if ( match ) {
237262 return framework ;
0 commit comments