-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathNewProject.res
More file actions
135 lines (109 loc) · 4.06 KB
/
NewProject.res
File metadata and controls
135 lines (109 loc) · 4.06 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
open Node
module P = ClackPrompts
let packageNameRegExp = /^[a-z0-9-]+$/
let validateProjectName = projectName =>
if projectName->String.trim->String.length === 0 {
Some("Project name must not be empty.")
} else if !(packageNameRegExp->RegExp.test(projectName)) {
Some("Project name may only contain lower case letters, numbers and hyphens.")
} else if Fs.existsSync(Path.join2(Process.cwd(), projectName)) {
Some(`The folder ${projectName} already exist in the current directory.`)
} else {
None
}
let updatePackageJson = async (~projectName, ~versions) =>
await JsonUtils.updateJsonFile("package.json", json =>
switch json {
| Object(config) => {
config->Dict.set("name", String(projectName))
let scripts = switch config->Dict.get("scripts") {
| Some(Object(scripts)) => scripts
| _ =>
let scripts = Dict.make()
config->Dict.set("scripts", Object(scripts))
scripts
}
if RescriptVersions.usesRewatch(versions) {
scripts->Dict.set("res:dev", String("rescript watch"))
}
}
| _ => ()
}
)
let updateRescriptJson = async (~projectName, ~versions) =>
await JsonUtils.updateJsonFile("rescript.json", json =>
switch json {
| Object(config) =>
config->Dict.set("name", String(projectName))
switch config->Dict.get("package-specs") {
| Some(Object(packageSpecs)) | Some(Array([Object(packageSpecs)])) =>
let moduleSystemName = versions->RescriptVersions.esmModuleSystemName
packageSpecs->Dict.set("module", String(moduleSystemName))
let suffix = moduleSystemName->ModuleSystem.getSuffix
config->Dict.set("suffix", String(suffix))
| _ => ()
}
if Option.isNone(versions.rescriptCoreVersion) {
RescriptJsonUtils.removeRescriptCore(config)
}
// https://github.com/rescript-lang/rescript/blob/master/CHANGELOG.md#1200-beta3
if CompareVersions.satisfies(versions.rescriptVersion, ">=12.0.0-beta.3") {
RescriptJsonUtils.modernizeConfigurationFields(config)
}
| _ => ()
}
)
let newProjectMessage = "Create a new ReScript project"
let getTemplateOptions = () =>
Templates.templates->Array.map(({name, displayName, shortDescription}) => {
P.value: name,
label: displayName,
hint: shortDescription,
})
let createProject = async (~templateName, ~projectName, ~versions) => {
let templatePath = CraPaths.getTemplatePath(~templateName)
let projectPath = Path.join2(Process.cwd(), projectName)
let s = P.spinner()
if !CI.isRunningInCI {
s->P.Spinner.start("Creating project...")
}
await Fs.Promises.cp(templatePath, projectPath, ~options={recursive: true})
Process.chdir(projectPath)
await Fs.Promises.rename("_gitignore", ".gitignore")
await updatePackageJson(~projectName, ~versions)
await updateRescriptJson(~projectName, ~versions)
await RescriptVersions.installVersions(versions)
let _ = await Promisified.ChildProcess.exec("git init")
if !CI.isRunningInCI {
s->P.Spinner.stop("Project created.")
}
P.note(
~title="Get started",
~message=`cd ${projectName}
# See the project's README.md for more information.`,
)
}
let createNewProject = async () => {
P.note(~title="New Project", ~message=newProjectMessage)
if CI.isRunningInCI {
// type versions = {rescriptVersion: string, rescriptCoreVersion: string}
await createProject(
~templateName="rescript-template-basic",
~projectName="test",
~versions={rescriptVersion: "11.1.1", rescriptCoreVersion: Some("1.5.0")},
)
} else {
let projectName = await P.text({
message: "What is the name of your new ReScript project?",
placeholder: "my-rescript-app",
initialValue: ?Process.argv[2],
validate: validateProjectName,
})->P.resultOrRaise
let templateName = await P.select({
message: "Select a template",
options: getTemplateOptions(),
})->P.resultOrRaise
let versions = await RescriptVersions.promptVersions()
await createProject(~templateName, ~projectName, ~versions)
}
}