From 96987d3812eeefe0e9223e390f2c5e16e7887827 Mon Sep 17 00:00:00 2001 From: Paolo Caleffi Date: Tue, 6 Apr 2021 17:24:17 +0200 Subject: [PATCH 1/3] feat(cli): git auto initialization on creation --- cli/bin/quasar-create | 34 +++++++++++++------------ cli/lib/generate.js | 7 +++--- cli/lib/initialize-git.js | 52 +++++++++++++++++++++++++++++++++++++++ cli/package.json | 1 + 4 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 cli/lib/initialize-git.js diff --git a/cli/bin/quasar-create b/cli/bin/quasar-create index a3d367caf23..96aa851eb75 100755 --- a/cli/bin/quasar-create +++ b/cli/bin/quasar-create @@ -9,9 +9,10 @@ const argv = parseArgs(process.argv.slice(2), { k: 'kit', c: 'clone', o: 'offline', - h: 'help' + h: 'help', + n: 'nogit' }, - boolean: ['c', 'o', 'h'], + boolean: ['c', 'o', 'h', 'n'], string: ['k', 'b'] }) @@ -21,7 +22,7 @@ if (argv.help) { Creates a Quasar App or App Extension project folder Usage - $ quasar create [--kit ] [--branch ] + $ quasar create [--kit ] [--branch ] [--nogit] App Examples $ quasar create my-project @@ -46,6 +47,7 @@ if (argv.help) { --branch, -b Use specific branch of the starter kit --clone, -c Use git clone --offline, -o Use a cached starter kit + --nogit, -n Avoid intializing Git repo when project generation completes --help, -h Displays this message `) process.exit(0) @@ -75,6 +77,7 @@ const rm = require('rimraf').sync const generate = require('../lib/generate') const logger = require('../lib/logger') const { isLocalPath, getTemplatePath } = require('../lib/local-path') +const { initializeGit } = require('../lib/initialize-git') let template = argv.kit ? ( @@ -131,11 +134,7 @@ function run () { const templatePath = getTemplatePath(template) if (exists(templatePath)) { - generate(name, templatePath, to, err => { - if (err) logger.fatal(err) - console.log() - logger.success('Generated "%s".', name) - }) + generate(name, templatePath, to, onGenerationCompleted) } else { logger.fatal('Local template "%s" not found.', template) @@ -158,13 +157,16 @@ function downloadAndGenerate (template) { logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim()) } - generate(name, tmp, to, err => { - if (err) { - logger.fatal(err) - } - - console.log() - logger.success('Generated "%s".', name) - }) + generate(name, tmp, to, onGenerationCompleted) }) } + +async function onGenerationCompleted(err) { + if (err) { + logger.fatal(err) + } + + if(!argv.nogit) { + await initializeGit(to) + } +} \ No newline at end of file diff --git a/cli/lib/generate.js b/cli/lib/generate.js index d4d0d4b021d..9fb07394749 100644 --- a/cli/lib/generate.js +++ b/cli/lib/generate.js @@ -67,15 +67,16 @@ module.exports = function generate (name, src, dest, done) { metalsmith.clean(false) .source('.') // start from template root instead of `./src` which is Metalsmith's default for `source` .destination(dest) - .build((err, files) => { - done(err) + .build(async (err, files) => { if (typeof opts.complete === 'function') { const helpers = { chalk, logger, files } - opts.complete(data, helpers) + await opts.complete(data, helpers) } else { logMessage(opts.completeMessage, data) } + + done(err) }) return data diff --git a/cli/lib/initialize-git.js b/cli/lib/initialize-git.js new file mode 100644 index 00000000000..46f48df0666 --- /dev/null +++ b/cli/lib/initialize-git.js @@ -0,0 +1,52 @@ +const { yellow } = require('chalk') +const execa = require('execa') + +/** + * Checks if Git is present in the system + */ +function hasGit() { + try { + execa.sync('git', ['--version'], { stdio: 'ignore' }) + return true + } catch (e) { + return false + } +} + +/** + * Checks if the project already have an initialized Git repo + * @param {string} cwd Path of the created project directory + */ +function hasProjectGit(cwd) { + try { + execa.sync('git', ['status'], { stdio: 'ignore', cwd }) + return true + } catch (e) { + return false + } +} + +/** + * Initialize a git repository into the project directory, if possible + * @param {string} cwd Path of the created project directory + */ + module.exports.initializeGit = async function (cwd) { + if(!hasGit()) { + console.log(yellow(' Git is not present on the system, skipping repo initialization...')) + return + } + + if(hasProjectGit(cwd)) { + console.log(yellow(' The project already have an initialized Git repository, skipping repo initialization...')) + return + } + + await execa('git', ['init'], { cwd }) + await execa('git', ['add', '-A'], { cwd }) + + try { + await execa('git', ['commit', '-m', 'init', '--no-verify'], { cwd, stdio: 'ignore' }) + } catch (e) { + console.log(yellow(' Skipped git commit because an error occurred, you will need to perform the initial commit yourself.')) + } +} \ No newline at end of file diff --git a/cli/package.json b/cli/package.json index 3c670101411..9032283ae19 100644 --- a/cli/package.json +++ b/cli/package.json @@ -52,6 +52,7 @@ "cors": "2.8.5", "cross-spawn": "7.0.3", "download-git-repo": "3.0.2", + "execa": "^5.0.0", "express": "4.17.1", "fs-extra": "9.0.1", "handlebars": "4.7.6", From 4a317350ca406ea212446b3b52848ab72c436396 Mon Sep 17 00:00:00 2001 From: Paolo Caleffi Date: Tue, 6 Apr 2021 20:29:40 +0200 Subject: [PATCH 2/3] fix(cli): only run git initialization when complete returns a Promise --- cli/lib/generate.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cli/lib/generate.js b/cli/lib/generate.js index 9fb07394749..2bbd8e70b14 100644 --- a/cli/lib/generate.js +++ b/cli/lib/generate.js @@ -70,13 +70,18 @@ module.exports = function generate (name, src, dest, done) { .build(async (err, files) => { if (typeof opts.complete === 'function') { const helpers = { chalk, logger, files } - await opts.complete(data, helpers) + // To preserve backwards compatibility of possible custom starter kits, + // we won't run the `done` callback, which manages git initialization, + // if the `complete` function doesn't return a Promise (as the updated starter kits do) + const completitionPromiseOrResult = opts.complete(data, helpers) + if(completitionPromiseOrResult instanceof Promise) { + await completitionPromiseOrResult + done(err) + } } else { logMessage(opts.completeMessage, data) } - - done(err) }) return data From 6f38be04fef82b161f38bc4771121b5131e9083c Mon Sep 17 00:00:00 2001 From: Paolo Caleffi Date: Mon, 12 Apr 2021 11:23:00 +0200 Subject: [PATCH 3/3] docs(app/installation): document git repo auto-initialization --- docs/src/pages/quasar-cli/commands-list.md | 2 ++ docs/src/pages/quasar-cli/installation.md | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/quasar-cli/commands-list.md b/docs/src/pages/quasar-cli/commands-list.md index 0f7d7273d0d..4117299b295 100644 --- a/docs/src/pages/quasar-cli/commands-list.md +++ b/docs/src/pages/quasar-cli/commands-list.md @@ -82,6 +82,8 @@ You can use a starter kit stored into any publicly accessible Git repository by `master` branch will be checked out by default, but you can specify the one you prefer via `--branch ` (eg. `quasar create --kit owner/name --branch my-branch`). +Since `@quasar/cli` v1.2, a Git repo will be automatically initialized in your newly created project folder, use `--nogit` flag to avoid it. + :::warning The preferred way to build reusable code and UI Components into Quasar ecosystem are App Extensions. Use a custom starter kit only if you really know what you're doing and be aware that it will make more difficult for the Quasar team to provide you assistance. ::: diff --git a/docs/src/pages/quasar-cli/installation.md b/docs/src/pages/quasar-cli/installation.md index 31febb3f7b1..37c3f8cec11 100644 --- a/docs/src/pages/quasar-cli/installation.md +++ b/docs/src/pages/quasar-cli/installation.md @@ -43,14 +43,17 @@ $ quasar create --branch next # $ quasar create ``` +Since `@quasar/cli` v1.2, a Git repo will be automatically initialized in your newly created project folder, use `--nogit` flag to avoid it. + :::tip Some **advanced** scenarios require to use a custom starter kit (eg. testing or personal presets). In those **rare** cases, you can use `--kit` option. Read more about this into [create command](/quasar-cli/commands-list#create) description. Remember that the recommended way to go is through writing a Quasar App Extension though. +Git repo auto-initialization is disabled for starter kits not returning a Promise from their `complete` hook (as Quasar official ones do). ::: :::tip WSL2 Microsoft's recommended [Nodejs development environment setup in WSL2](https://docs.microsoft.com/en-us/windows/nodejs/setup-on-wsl2). -When using WSL2 (Windows Subsystem for Linux) [Microsoft recommends](https://docs.microsoft.com/en-us/windows/wsl/compare-versions#performance-across-os-file-systems) keeping files in the linux file sytem to maximize performance. Projects will build around 3X slower and HMR (Hot Module Reload) will not work ([without a hack](/quasar-cli/quasar-conf-js#Docker-and-WSL-Issues-with-HRM)) if the project files are on the Windows mount instead of the local linux file system. This is also true in Docker for Windows based development environments. +When using WSL2 (Windows Subsystem for Linux) [Microsoft recommends](https://docs.microsoft.com/en-us/windows/wsl/compare-versions#performance-across-os-file-systems) keeping files in the linux file sytem to maximize performance. Projects will build around 3X slower and HMR (Hot Module Reload) will not work ([without a hack](/quasar-cli/quasar-conf-js#Docker-and-WSL-Issues-with-HRM)) if the project files are on the Windows mount instead of the local linux file system. This is also true in Docker for Windows based development environments. ::: Note that you don't need separate projects if you want to build any of the available platforms. This one project can seamlessly handle all of them.