complete first
This commit is contained in:
		
							
								
								
									
										23
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| pipeline { | ||||
|   agent any | ||||
|  | ||||
|   environment { | ||||
|       VERSION = VersionNumber([ | ||||
|           versionNumberString: | ||||
|               '${BUILDS_ALL_TIME}', | ||||
|           versionPrefix: '1.0.', | ||||
|           worstResultForIncrement: 'SUCCESS' | ||||
|       ]) | ||||
|   } | ||||
|  | ||||
|   stages { | ||||
|       stage('Building') { | ||||
|           steps { | ||||
|               script { | ||||
|                   currentBuild.displayName = env.VERSION | ||||
|               } | ||||
|               sh 'yarn ci ${VERSION}' | ||||
|           } | ||||
|       } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										26
									
								
								jenkins.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								jenkins.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* eslint-disable no-process-exit */ | ||||
| /* eslint-disable no-console */ | ||||
| /* eslint-disable no-sync */ | ||||
| 'use strict'; | ||||
|  | ||||
| const fs = require ('fs'); | ||||
| const child_process = require ('child_process'); | ||||
|  | ||||
| const pkg = JSON.parse (fs.readFileSync ('package.json', 'utf-8')); | ||||
| [ | ||||
|   ,, pkg.version | ||||
| ] = process.argv; | ||||
| fs.writeFileSync ('package.json', JSON.stringify (pkg, null, 2)); | ||||
|  | ||||
| child_process.execSync ('yarn lint', { stdio: 'inherit' }); | ||||
| child_process.execSync ('yarn test', { stdio: 'inherit' }); | ||||
| child_process.execSync ('yarn compile', { stdio: 'inherit' }); | ||||
|  | ||||
| child_process.exec ('git log -1 | grep \'\\[no publish\\]\'') | ||||
|   .addListener ('exit', (code) => { | ||||
|     if (code === 0) { | ||||
|       console.log ('build not marked for deployment'); | ||||
|       process.exit (1); | ||||
|     } | ||||
|     else { child_process.execSync ('yarn publish'); } | ||||
|   }); | ||||
| @@ -1,8 +1,11 @@ | ||||
| /* eslint-disable max-lines-per-function */ | ||||
| /* eslint-disable complexity */ | ||||
| /* eslint-disable max-statements */ | ||||
| /* eslint-disable no-process-env */ | ||||
| import { Persistent } from '@scode/modelling'; | ||||
| import fs from 'fs-extra'; | ||||
| import yargs from 'yargs'; | ||||
| import { Confirm, Input } from 'enquirer'; | ||||
|  | ||||
| enum OptionType { | ||||
|   string = 'string', | ||||
| @@ -20,6 +23,8 @@ interface Option { | ||||
|   default?: unknown; | ||||
|   alias?: string; | ||||
|   env?: string; | ||||
|   description?: string; | ||||
|   message?: string; | ||||
| } | ||||
|  | ||||
| interface OptionProcess extends Option { | ||||
| @@ -45,22 +50,24 @@ export class InteractiveOptions extends Persistent { | ||||
|   } | ||||
|  | ||||
|   public async parse (): Promise<void> { | ||||
|     this.get_env_options (); | ||||
|     this.get_args_options (); | ||||
|     await this.get_env_options (); | ||||
|     await this.get_args_options (); | ||||
|     await this.get_interactive_options (); | ||||
|   } | ||||
|  | ||||
|   private get unfilled (): Array<OptionProcess> { | ||||
|     return this.options.filter ((o) => !o.filled); | ||||
|   } | ||||
|  | ||||
|   private async assign_arg (opt: OptionProcess, value: unknown): Promise<void> { | ||||
|     if (opt.type === OptionType.string) { | ||||
|       opt.value = value; | ||||
|       opt.value = String (value); | ||||
|       opt.filled = true; | ||||
|       return; | ||||
|     } | ||||
|     if (opt.type === OptionType.number) { | ||||
|       if (![ | ||||
|         'string', | ||||
|         'number' | ||||
|       ].includes (typeof value)) | ||||
|         return; | ||||
|  | ||||
|       const as_num = parseInt (value); | ||||
|       const is_num = !isNaN (as_num); | ||||
|       if (is_num) { | ||||
| @@ -70,10 +77,20 @@ export class InteractiveOptions extends Persistent { | ||||
|       return; | ||||
|     } | ||||
|     if (opt.type === OptionType.boolean) { | ||||
|       const is_boo = (/^(?:true|false)$/ui).test (value); | ||||
|       if (is_boo) { | ||||
|         const as_boo = (/true/ui).test (value); | ||||
|         opt.value = as_boo; | ||||
|       if (![ | ||||
|         'string', | ||||
|         'boolean', | ||||
|         'number' | ||||
|       ].includes (typeof value)) | ||||
|         return; | ||||
|  | ||||
|       const is_bool = [ | ||||
|         0, | ||||
|         1 | ||||
|       ].includes (value) || (/^(?:true|false)$/ui).test (value); | ||||
|       if (is_bool) { | ||||
|         const as_bool = value === 1 || (/true/ui).test (value as string); | ||||
|         opt.value = as_bool; | ||||
|         opt.filled = true; | ||||
|       } | ||||
|       return; | ||||
| @@ -83,7 +100,7 @@ export class InteractiveOptions extends Persistent { | ||||
|       || opt.type === OptionType.file | ||||
|       || opt.type === OptionType.folder | ||||
|     ) { | ||||
|       if (!await fs.pathExists (value)) | ||||
|       if (typeof value !== 'string' || !await fs.pathExists (value)) | ||||
|         return; | ||||
|       if (opt.type === OptionType.path) { | ||||
|         opt.value = value; | ||||
| @@ -98,7 +115,7 @@ export class InteractiveOptions extends Persistent { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private async get_env_options (): void { | ||||
|   private async get_env_options (): Promise<void> { | ||||
|     await Promise.all (this.options.map ((opt) => { | ||||
|       if ( | ||||
|         typeof opt.env !== 'undefined' | ||||
| @@ -109,11 +126,64 @@ export class InteractiveOptions extends Persistent { | ||||
|     })); | ||||
|   } | ||||
|  | ||||
|   private async get_args_options (): void { | ||||
|   private async get_args_options (): Promise<void> { | ||||
|     const yargs_config = { | ||||
|       quiet: { | ||||
|         alias:    'q', | ||||
|         default:  false, | ||||
|         type:     'boolean', | ||||
|         describe: 'do not ask for options interactively' | ||||
|       } | ||||
|     }; | ||||
|     for (const opt of this.options) { | ||||
|       yargs_config[opt.name] = { | ||||
|         alias:    opt.alias, | ||||
|         default:  opt.default, | ||||
|         type:     opt.type === OptionType.boolean ? 'boolean' : 'string', | ||||
|         describe: opt.description | ||||
|       }; | ||||
|     } | ||||
|     const argv = yargs.options (yargs_config); | ||||
|     await Promise.all (this.options.map ((opt) => { | ||||
|       if (typeof argv[opt.name] !== 'undefined') | ||||
|         return this.assign_arg (opt, argv[opt.name]); | ||||
|       return Promise.resolve (); | ||||
|     })); | ||||
|   } | ||||
|  | ||||
|   private async prompt (opt: OptionProcess): Promise<void> { | ||||
|     if (opt.filled) | ||||
|       return; | ||||
|     if ( | ||||
|       opt.type === OptionType.string | ||||
|       || opt.type === OptionType.file | ||||
|       || opt.type === OptionType.folder | ||||
|       || opt.type === OptionType.path | ||||
|       || opt.type === OptionType.number | ||||
|     ) { | ||||
|       const value = await new Input ({ | ||||
|         message: opt.message, | ||||
|         default: opt.default | ||||
|       }) | ||||
|         .run (); | ||||
|       await this.assign_arg (opt, value); | ||||
|       return; | ||||
|     } | ||||
|     if ( | ||||
|       opt.type === OptionType.boolean | ||||
|     ) { | ||||
|       const value = await new Confirm ({ | ||||
|         message: opt.message, | ||||
|         default: opt.default | ||||
|       }) | ||||
|         .run (); | ||||
|       await this.assign_arg (opt, value); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private async get_interactive_options (): Promise<void> { | ||||
|  | ||||
|     for (const opt of this.options) | ||||
|       // eslint-disable-next-line no-await-in-loop | ||||
|       await this.prompt (opt); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								lib/enquirer.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/enquirer.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| declare module 'enquirer'; | ||||
| @@ -8,6 +8,7 @@ | ||||
|     "@ava/typescript": "^1.1.1", | ||||
|     "@scode/eslint-config-ts": "^1.0.31", | ||||
|     "@types/fs-extra": "^8.1.0", | ||||
|     "@types/yargs": "^15.0.4", | ||||
|     "ava": "^3.8.1", | ||||
|     "eslint": "^6.8.0", | ||||
|     "nyc": "^15.0.1", | ||||
| @@ -16,14 +17,15 @@ | ||||
|   "scripts": { | ||||
|     "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs", | ||||
|     "test": "echo \"no test\"", | ||||
|     "compile": "tsc" | ||||
|     "compile": "tsc", | ||||
|     "ci": "yarn && node jenkins.js" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "LICENSE", | ||||
|     "/dist/" | ||||
|   ], | ||||
|   "dependencies": { | ||||
|     "@scode/modelling": "^1.0.24", | ||||
|     "@scode/modelling": "^1.0.26", | ||||
|     "enquirer": "^2.3.5", | ||||
|     "fs-extra": "^9.0.0", | ||||
|     "yargs": "^15.3.1" | ||||
|   | ||||
							
								
								
									
										14
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -253,7 +253,7 @@ | ||||
|     eslint-plugin-node "^11.0.0" | ||||
|     eslint-plugin-sort-requires-by-path "^1.0.2" | ||||
|  | ||||
| "@scode/modelling@^1.0.24": | ||||
| "@scode/modelling@^1.0.26": | ||||
|   version "1.0.26" | ||||
|   resolved "https://npm.scode.ovh/@scode%2fmodelling/-/modelling-1.0.26.tgz#e976a98762cb3c1b66af7d65616a50022230e5b1" | ||||
|   integrity sha512-Pk6NXQ7HurAlCaLChvX8ycgbWZG31I2UwnKEyevvxYPS6WvNqFpEhxve1sRas1caQrVq0b626nyVjChviPZT+Q== | ||||
| @@ -321,6 +321,18 @@ | ||||
|   resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" | ||||
|   integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== | ||||
|  | ||||
| "@types/yargs-parser@*": | ||||
|   version "15.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" | ||||
|   integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== | ||||
|  | ||||
| "@types/yargs@^15.0.4": | ||||
|   version "15.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" | ||||
|   integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== | ||||
|   dependencies: | ||||
|     "@types/yargs-parser" "*" | ||||
|  | ||||
| "@typescript-eslint/eslint-plugin@^2.26.0": | ||||
|   version "2.31.0" | ||||
|   resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz#942c921fec5e200b79593c71fafb1e3f57aa2e36" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user