-
Notifications
You must be signed in to change notification settings - Fork 2
/
create-project.js
117 lines (98 loc) · 3.47 KB
/
create-project.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { createRequire } from 'module'
import { isAbsolute, join, resolve } from 'path'
import fs from 'fs'
import git from 'isomorphic-git'
import parse from '@architect/parser'
const { existsSync, lstatSync, readFileSync, renameSync, rmSync, unlinkSync, writeFileSync } = fs
const require = createRequire(import.meta.url)
export const STARTER_PROJECT = 'https://github.com/enhance-dev/enhance-starter-project'
export async function createProject ({ dest, path, name, template = STARTER_PROJECT }) {
let looseName = /^[a-z][a-zA-Z0-9-_]+$/
let appName = 'my-enhance-app'
if (name) {
appName = name
} else if (path) {
const parts = path.trim().split('/')
appName = parts[parts.length - 1]
}
if (!looseName.test(appName)) {
throw Error('Invalid app name')
}
if (template) {
try {
new URL(template)
} catch (error) {
throw Error('Invalid template URL')
}
}
// Project folder
const projectDir = isAbsolute(dest) ? dest : resolve(dest)
if (existsSync(projectDir)) {
throw Error('Path already exists.')
}
await createFromTemplate(projectDir, dest, appName, template)
}
async function createFromTemplate(projectDir, dest, appName, template) {
const http = require('isomorphic-git/http/node')
try {
// Clone the template project
await git.clone({ fs, http, dir: projectDir, url: template })
// Check
if (!existsSync(join(projectDir, '.arc')) && !existsSync(join(projectDir, 'app.arc')) ) {
throw Error('Invalid Enhance template')
}
// Remove git folders
remove(join(projectDir, '.git'))
remove(join(projectDir, '.github'))
// Clean up miscellaneous starter project files
if (template === STARTER_PROJECT) {
cleanStarterProject(projectDir)
}
updatePackageJson(dest, appName)
updateArcFile(dest, appName)
} catch (err) {
throw Error('Unable to create project', err)
}
}
function cleanStarterProject(projectDir) {
renameSync(join(projectDir, 'template.gitignore'), join(projectDir, '.gitignore'))
remove(join(projectDir, '.npmignore'))
remove(join(projectDir, '.npmrc'))
remove(join(projectDir, 'LICENSE'))
remove(join(projectDir, 'manifest.json'))
remove(join(projectDir, 'readme.md'))
remove(join(projectDir, 'scripts'))
}
function remove(filePath) {
if (existsSync(filePath)) {
if (lstatSync(filePath).isDirectory()) {
rmSync(filePath, { recursive: true, force: true });
} else {
unlinkSync(filePath)
}
}
}
function updatePackageJson(dest, appName) {
const pkgFile = require(join(dest, 'package.json'))
pkgFile.name = appName
pkgFile.version = '0.0.1'
const newPkgFile = Object.assign({
name: null,
version: null,
scripts: null,
dependencies: null,
devDependencies: null,
},
pkgFile)
writeFileSync(
join(dest, 'package.json'),
JSON.stringify(newPkgFile, null, 2),
)
}
function updateArcFile(dest, appName) {
const arcFilePath = existsSync(join(dest, '.arc')) ? join(dest, '.arc') : join(dest, 'app.arc')
const text = readFileSync(arcFilePath, 'utf8').toString()
const result = parse(text)
let arcFile = result.app.length === 1 && result.app[0] ? text.replace(result.app[0], appName) : text
writeFileSync(arcFilePath, arcFile)
}