Initialize Git repo on app creation (#9376)

* Initialize Git repo on app creation
This PR initializes a Git repository after Create Next App runs.

We ensure the app was not created in an already-existing Git or Mercurial repo.

Failures of setup (no Git installed) do not fail the application bootstrapping.

Closes #9077 (replaces)

* Add test

* Update index.test.js
This commit is contained in:
Joe Haddad 2019-11-10 21:42:51 -08:00 committed by GitHub
parent 79e717a76b
commit 00badd4d58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 2 deletions

View file

@ -0,0 +1,50 @@
// Type definitions for rimraf 2.0
// Project: https://github.com/isaacs/rimraf
// Definitions by: Carlos Ballesteros Velasco <https://github.com/soywiz>
// e-cloud <https://github.com/e-cloud>
// Ruben Schmidmeister <https://github.com/bash>
// Oganexon <https://github.com/oganexon>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// Imported from: https://github.com/soywiz/typescript-node-definitions/rimraf.d.ts
declare module 'rimraf' {
/// <reference types="node" />
import glob = require('glob')
import fs = require('fs')
function rimraf(
path: string,
options: rimraf.Options,
callback: (error: Error) => void
): void
function rimraf(path: string, callback: (error: Error) => void): void
// eslint-disable-next-line no-redeclare
namespace rimraf {
function __promisify__(path: string, options?: Options): Promise<void>
function sync(path: string, options?: Options): void
let EMFILE_MAX: number
let BUSYTRIES_MAX: number
interface Options {
maxBusyTries?: number
emfileWait?: number
disableGlob?: boolean
glob?: glob.IOptions | false
unlink?: typeof fs.unlink
chmod?: typeof fs.chmod
stat?: typeof fs.stat
lstat?: typeof fs.lstat
rmdir?: typeof fs.rmdir
readdir?: typeof fs.readdir
unlinkSync?: typeof fs.unlinkSync
chmodSync?: typeof fs.chmodSync
statSync?: typeof fs.statSync
lstatSync?: typeof fs.lstatSync
rmdirSync?: typeof fs.rmdirSync
readdirSync?: typeof fs.readdirSync
}
}
export = rimraf
}

View file

@ -6,6 +6,7 @@ import os from 'os'
import path from 'path'
import { downloadAndExtractExample, hasExample } from './helpers/examples'
import { tryGitInit } from './helpers/git'
import { install } from './helpers/install'
import { isFolderEmpty } from './helpers/is-folder-empty'
import { getOnline } from './helpers/is-online'
@ -60,6 +61,15 @@ export async function createApp({
console.log()
await downloadAndExtractExample(root, example)
// Copy our default `.gitignore` if the application did not provide one
const ignorePath = path.join(root, '.gitignore')
if (!fs.existsSync(ignorePath)) {
fs.copyFileSync(
path.join(__dirname, 'templates', 'default', 'gitignore'),
ignorePath
)
}
console.log('Installing packages. This might take a couple of minutes.')
console.log()
@ -103,6 +113,11 @@ export async function createApp({
})
}
if (tryGitInit(root)) {
console.log('Initialized a git repository.')
console.log()
}
let cdpath: string
if (path.join(originalDirectory, appName) === appPath) {
cdpath = appName

View file

@ -0,0 +1,45 @@
import { execSync } from 'child_process'
import path from 'path'
import rimraf from 'rimraf'
function isInGitRepository() {
try {
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' })
return true
} catch (_) {}
return false
}
function isInMercurialRepository() {
try {
execSync('hg --cwd . root', { stdio: 'ignore' })
return true
} catch (_) {}
return false
}
export function tryGitInit(root: string) {
let didInit = false
try {
execSync('git --version', { stdio: 'ignore' })
if (isInGitRepository() || isInMercurialRepository()) {
return false
}
execSync('git init', { stdio: 'ignore' })
didInit = true
execSync('git add -A', { stdio: 'ignore' })
execSync('git commit -m "Initial commit from Create Next App"', {
stdio: 'ignore',
})
return true
} catch (e) {
if (didInit) {
try {
rimraf.sync(path.join(root, '.git'))
} catch (_) {}
}
return false
}
}

View file

@ -40,7 +40,7 @@
"make-dir": "3.0.0",
"promisepipe": "3.0.0",
"prompts": "2.1.0",
"rimraf": "2.6.3",
"rimraf": "3.0.0",
"tar": "4.4.10",
"typescript": "^3.5.3",
"update-check": "1.5.3",

View file

@ -76,5 +76,9 @@ describe('create next app', () => {
expect(
fs.existsSync(path.join(cwd, projectName, 'pages/index.js'))
).toBeTruthy()
// check we copied default `.gitignore`
expect(
fs.existsSync(path.join(cwd, projectName, '.gitignore'))
).toBeTruthy()
})
})

View file

@ -13131,7 +13131,7 @@ rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6
dependencies:
glob "^7.1.3"
rimraf@^3.0.0:
rimraf@3.0.0, rimraf@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b"
integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==