@gx-design-vue/create-gx-cli 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,15 @@ npm init @gx-design-vue/create-gx-cli
10
10
  npx @gx-design-vue/create-gx-cli
11
11
  # or
12
12
  npm install -g @gx-design-vue/create-gx-cli
13
+
14
+ # create project
13
15
  create-gx-cli
16
+ # cli version
17
+ create-gx-cli -v
18
+ # short create(first: project name、--template: template project)
19
+ create-gx-cli app --template gx-design-pro
20
+ create-gx-cli app --template gx-design-thin
21
+ create-gx-cli app --template mobile-vant-cli
22
+ create-gx-cli app --template mobile-vant-html
14
23
  ```
15
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gx-design-vue/create-gx-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "license": "MIT",
5
5
  "description": "a cli to bootstrap gx project",
6
6
  "main": "src/index.js",
@@ -15,14 +15,15 @@
15
15
  "author": "gx12358",
16
16
  "dependencies": {
17
17
  "chalk": "^2.4.2",
18
+ "child_process": "^1.0.2",
18
19
  "esm": "^3.2.18",
20
+ "execa": "^8.0.1",
19
21
  "inquirer": "^6.2.2",
20
22
  "kolorist": "^1.6.0",
21
23
  "listr": "^0.14.3",
22
24
  "minimist": "^1.2.7",
23
25
  "nanospinner": "^1.1.0",
24
26
  "ncp": "^2.0.0",
25
- "obtain-git-repo": "^1.0.2",
26
27
  "prompts": "^2.4.1"
27
28
  },
28
29
  "files": [
package/src/cli.js CHANGED
@@ -1,9 +1,14 @@
1
+ import chalk from 'chalk'
1
2
  import minimist from 'minimist'
2
3
  import prompts from 'prompts'
3
4
  import { yellow, reset, blue, red, green } from 'kolorist'
4
5
  import { createProject } from './main'
5
6
 
6
- const defaultTargetDir = 'gx-cli-project'
7
+ import pag from '../package.json'
8
+
9
+ const { version } = pag
10
+
11
+ const defaultTargetDir = 'vue3-project'
7
12
 
8
13
  const FRAMEWORKS = [
9
14
  {
@@ -37,20 +42,24 @@ function parseArgumentsIntoOptions() {
37
42
  const argTargetDir = formatTargetDir(argv._[0])
38
43
  const argTemplate = argv.template || argv.t
39
44
  return {
45
+ v: argv.v,
40
46
  template: argTemplate,
41
47
  projectName: argTargetDir
42
48
  }
43
49
  }
44
50
 
45
51
  async function promptForMissingOptions(options) {
46
- const answers = await prompts([
47
- {
52
+ const projectNamePrompts = []
53
+ if (!options.projectName) {
54
+ projectNamePrompts.push({
48
55
  type: options.projectName ? null : 'text',
49
56
  name: 'projectName',
50
57
  message: reset('Project name:'),
51
58
  initial: defaultTargetDir
52
- },
53
- {
59
+ })
60
+ }
61
+ if (typeof options.template !== 'string' || !TEMPLATES.includes(options.template)) {
62
+ projectNamePrompts.push({
54
63
  type: 'select',
55
64
  name: 'template',
56
65
  message:
@@ -66,20 +75,36 @@ async function promptForMissingOptions(options) {
66
75
  value: framework
67
76
  }
68
77
  })
69
- }
70
- ])
78
+ })
79
+ }
80
+ let answers = {
81
+ template: {
82
+ name: ''
83
+ },
84
+ projectName: ''
85
+ }
86
+
87
+ if (projectNamePrompts.length) {
88
+ answers = await prompts(projectNamePrompts)
89
+ }
71
90
 
72
91
  return {
73
92
  ...options,
74
- template: options.template || answers.template ? answers.template.name : '',
93
+ template: options.template || (answers.template ? answers.template.name : ''),
75
94
  projectName: options.projectName || answers.projectName || ''
76
95
  }
77
96
  }
78
97
 
79
98
  export async function cli() {
80
99
  let options = parseArgumentsIntoOptions()
100
+ if (options.v) {
101
+ console.log(chalk.whiteBright(version))
102
+ process.exit(1)
103
+ }
81
104
  options = await promptForMissingOptions(options)
82
105
  if (options.template && options.projectName) {
83
106
  await createProject(options)
107
+ } else {
108
+ process.exit(1)
84
109
  }
85
110
  }
package/src/git.js ADDED
@@ -0,0 +1,76 @@
1
+ import { spawn } from 'child_process'
2
+
3
+ function git(opts) {
4
+ return opts.git || 'git'
5
+ }
6
+
7
+ function buildCloneCommand(repo, targetPath, opts) {
8
+ let args = [ 'clone' ]
9
+ const userArgs = opts.args || []
10
+
11
+ if (opts.shallow) {
12
+ if (userArgs.indexOf('--depth') >= 0) {
13
+ throw new Error('\'--depth\' cannot be specified when shallow is set to \'true\'')
14
+ }
15
+ args.push('--depth', '1')
16
+ }
17
+
18
+ if (opts.progress) {
19
+ args.push('--progress')
20
+ }
21
+
22
+ args = args.concat(userArgs)
23
+ args.push('--', repo, targetPath)
24
+
25
+ return [ git(opts), args ]
26
+ }
27
+
28
+ function buildCheckoutCommand(ref, opts) {
29
+ return [ git(opts), [ 'checkout', ref ] ]
30
+ }
31
+
32
+ export function clone(repo, targetPath, opts, onSuccess, onError) {
33
+ const [ cmd, args ] = buildCloneCommand(repo, targetPath, opts)
34
+ const proc = spawn(cmd, args)
35
+
36
+ if (opts.progress) {
37
+ proc.stderr.on('data', (evt) => {
38
+ const line = evt.toString()
39
+ if (line.match(/Receiving objects:\s+(\d+)%/)) {
40
+ opts.progress({
41
+ phase: 'receivingObjects',
42
+ percent: Number(RegExp.$1)
43
+ })
44
+ } else if (line.match(/Resolving deltas:\s+(\d+)%/)) {
45
+ opts.progress({
46
+ phase: 'resolvingDeltas',
47
+ percent: Number(RegExp.$1)
48
+ })
49
+ }
50
+ })
51
+ }
52
+
53
+ proc.on('close', (status) => {
54
+ if (status == 0) {
55
+ if (opts.checkout) {
56
+ _checkout()
57
+ } else {
58
+ onSuccess()
59
+ }
60
+ } else {
61
+ onError(new Error('\'git clone\' failed with status ' + status))
62
+ }
63
+ })
64
+
65
+ function _checkout() {
66
+ const [ cmd, args ] = buildCheckoutCommand(opts.checkout, opts)
67
+ const proc = spawn(cmd, args, { cwd: targetPath })
68
+ proc.on('close', function (status) {
69
+ if (status == 0) {
70
+ onSuccess()
71
+ } else {
72
+ onError(new Error('\'git checkout\' failed with status ' + status))
73
+ }
74
+ })
75
+ }
76
+ }
package/src/main.js CHANGED
@@ -1,23 +1,34 @@
1
1
  import chalk from 'chalk'
2
2
  import fs from 'fs'
3
+ import { reset } from 'kolorist'
4
+ import prompts from 'prompts'
3
5
  import { fileURLToPath } from 'url'
4
6
  import Listr from 'listr'
5
7
  import ncp from 'ncp'
6
8
  import path from 'path'
7
9
  import { promisify } from 'util'
8
10
  import { createSpinner } from 'nanospinner'
9
- import { download } from 'obtain-git-repo'
11
+ import { clone } from './git'
10
12
 
11
13
  const copy = promisify(ncp)
12
14
 
13
15
  const gitRepositoryList = [
14
16
  {
15
17
  name: 'gx-design-pro',
16
- git: 'https://gitee.com/gx12358/vue3-antd-admin.git'
18
+ children: [
19
+ {
20
+ name: 'Gitee',
21
+ url: 'https://gitee.com/gx12358/vue3-antd-admin.git',
22
+ },
23
+ {
24
+ name: 'Github',
25
+ url: 'https://github.com/gx12358/vue3-antd-admin.git',
26
+ }
27
+ ]
17
28
  },
18
29
  {
19
30
  name: 'gx-design-thin',
20
- git: 'https://gitee.com/gx12358/gx-admin-thin.git'
31
+ url: 'https://gitee.com/gx12358/gx-admin-thin.git'
21
32
  }
22
33
  ]
23
34
 
@@ -64,19 +75,35 @@ function doneLog(cwd, root) {
64
75
  if (root !== cwd) {
65
76
  console.log(chalk.blueBright(`cd ${path.relative(cwd, root)}`))
66
77
  }
67
- console.log(chalk.blueBright(`pnpm(yarn、npm) install`))
68
- console.log(chalk.blueBright(`pnpm(yarn、npm) run dev`))
78
+ console.log(chalk.blueBright(`pnpmyarn、npm install`))
79
+ console.log(chalk.blueBright(`pnpmyarn、npm run dev`))
69
80
  console.log()
70
81
  }
71
82
 
83
+ function getProjectName(projectName) {
84
+ return projectName === '.' ? path.basename(path.resolve()) : projectName
85
+ }
86
+
87
+ function download(url, root, projectName) {
88
+ const spinner = createSpinner(`开始下载...${url}`).start()
89
+ // 下载git代码
90
+ clone(`${url}`, root, { clone: true }, async () => {
91
+ await editPackageJson(root, projectName || getProjectName(projectName))
92
+ spinner.success({
93
+ text: '项目创建成功,请依次执行以下命令'
94
+ })
95
+ doneLog(process.cwd(), root)
96
+ },async function (err) {
97
+ console.log(err)
98
+ spinner.error({ text: '下载失败' })
99
+ })
100
+ }
101
+
72
102
  export async function createProject(options) {
73
103
  const cwd = process.cwd()
74
104
 
75
105
  const root = path.join(cwd, options.projectName)
76
106
 
77
- const getProjectName = () =>
78
- options.projectName === '.' ? path.basename(path.resolve()) : options.projectName
79
-
80
107
  const downloadGit = gitRepositoryList.find(el => el.name === options.template)
81
108
 
82
109
  const templateDir = path.resolve(
@@ -103,19 +130,25 @@ export async function createProject(options) {
103
130
  }
104
131
 
105
132
  if (downloadGit) {
106
- const spinner = createSpinner(`开始下载...${downloadGit.git}`).start()
107
- // 下载git代码
108
- download(`direct:${downloadGit.git}`, root, { clone: true }, async function (err) {
109
- if (err) {
110
- spinner.error({ text: '下载失败' })
111
- } else {
112
- await editPackageJson(root, options.projectName || getProjectName())
113
- spinner.success({
114
- text: '项目创建成功,请依次执行以下命令'
115
- })
116
- fs.doneLog(cwd, root)
117
- }
118
- })
133
+ if (downloadGit.children && downloadGit.children.length > 0) {
134
+ prompts([
135
+ {
136
+ type: 'select',
137
+ name: 'url',
138
+ message: reset('Select a Url:'),
139
+ choices: downloadGit.children.map((item) => {
140
+ return {
141
+ title: item.name,
142
+ value: item.url
143
+ }
144
+ })
145
+ }
146
+ ]).then(answers => {
147
+ if (answers.url) download(answers.url, root, options.projectName)
148
+ })
149
+ } else if (downloadGit.url) {
150
+ download(downloadGit.url, root, options.projectName)
151
+ }
119
152
  } else {
120
153
  const tasks = new Listr(
121
154
  [
@@ -125,7 +158,7 @@ export async function createProject(options) {
125
158
  },
126
159
  options.template !== 'mobile-vant-html' ? {
127
160
  title: '初始化项目',
128
- task: () => editPackageJson(root, options.projectName || getProjectName())
161
+ task: () => editPackageJson(root, options.projectName || getProjectName(options.projectName))
129
162
  } : {}
130
163
  ],
131
164
  {
@@ -54,4 +54,4 @@
54
54
  "vite-plugin-vue-setup-extend": "^0.4.0",
55
55
  "vue-tsc": "^1.8.27"
56
56
  }
57
- }
57
+ }