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:
parent
79e717a76b
commit
00badd4d58
6 changed files with 116 additions and 2 deletions
50
packages/create-next-app/@types/rimraf.d.ts
vendored
Normal file
50
packages/create-next-app/@types/rimraf.d.ts
vendored
Normal 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
|
||||
}
|
|
@ -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
|
||||
|
|
45
packages/create-next-app/helpers/git.ts
Normal file
45
packages/create-next-app/helpers/git.ts
Normal 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
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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==
|
||||
|
|
Loading…
Reference in a new issue