@multiplatform.one/cli 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/multiplatformOne.mjs +1 -1
- package/lib/bin/multiplatformOne.mjs +87 -15
- package/lib/types.d.mts +2 -0
- package/package.json +2 -2
- package/src/bin/multiplatformOne.ts +196 -61
- package/src/index.ts +1 -1
- package/src/types.ts +2 -0
package/bin/multiplatformOne.mjs
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
// src/bin/multiplatformOne.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { execa } from "execa";
|
|
8
|
-
import { fileURLToPath } from "url";
|
|
2
|
+
import fsSync from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
9
7
|
import { program } from "commander";
|
|
8
|
+
import { execa } from "execa";
|
|
9
|
+
import inquirer from "inquirer";
|
|
10
|
+
var availableBackends = [
|
|
11
|
+
"api",
|
|
12
|
+
"frappe"
|
|
13
|
+
];
|
|
14
|
+
var availablePlatforms = [
|
|
15
|
+
"electron",
|
|
16
|
+
"expo",
|
|
17
|
+
"keycloak",
|
|
18
|
+
"next",
|
|
19
|
+
"storybook",
|
|
20
|
+
"storybook-expo"
|
|
21
|
+
];
|
|
10
22
|
process.env.COOKIECUTTER = `sh ${path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../scripts/cookiecutter.sh")}`;
|
|
11
23
|
program.name("multiplatform.one");
|
|
12
24
|
program.version(JSON.parse(fsSync.readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../package.json"), "utf8"))?.version);
|
|
13
|
-
program.command("init").option("-r, --remote <remote>", "the remote to use", "https://gitlab.com/bitspur/multiplatform.one/cookiecutter").option("-c, --checkout <branch>", "branch, tag or commit to checkout", "main").argument("[name]", "the name of the project", "").description("init multiplatform.one").action(async (name, options) => {
|
|
25
|
+
program.command("init").option("-r, --remote <remote>", "the remote to use", "https://gitlab.com/bitspur/multiplatform.one/cookiecutter").option("-c, --checkout <branch>", "branch, tag or commit to checkout", "main").option("-p, --platforms <platforms>", "platforms to keep").option("-b, --backends <backends>", "backends to keep").argument("[name]", "the name of the project", "").description("init multiplatform.one").action(async (name, options) => {
|
|
26
|
+
let { backends, platforms } = options;
|
|
14
27
|
if ((await execa("git", [
|
|
15
28
|
"rev-parse",
|
|
16
29
|
"--is-inside-work-tree"
|
|
@@ -28,9 +41,37 @@ program.command("init").option("-r, --remote <remote>", "the remote to use", "ht
|
|
|
28
41
|
}
|
|
29
42
|
])).name;
|
|
30
43
|
}
|
|
44
|
+
if (!backends) {
|
|
45
|
+
const backendsResult = (await inquirer.prompt([
|
|
46
|
+
{
|
|
47
|
+
message: "What backends are you using?",
|
|
48
|
+
name: "backends",
|
|
49
|
+
type: "checkbox",
|
|
50
|
+
choices: availableBackends.map((name2) => ({
|
|
51
|
+
name: name2
|
|
52
|
+
}))
|
|
53
|
+
}
|
|
54
|
+
])).backends;
|
|
55
|
+
backends = backendsResult.join(",");
|
|
56
|
+
}
|
|
57
|
+
if (!platforms) {
|
|
58
|
+
const platformsResult = (await inquirer.prompt([
|
|
59
|
+
{
|
|
60
|
+
message: "What platforms are you using?",
|
|
61
|
+
name: "platforms",
|
|
62
|
+
type: "checkbox",
|
|
63
|
+
choices: availablePlatforms.map((name2) => ({
|
|
64
|
+
name: name2
|
|
65
|
+
}))
|
|
66
|
+
}
|
|
67
|
+
])).platforms;
|
|
68
|
+
platforms = platformsResult.join(",");
|
|
69
|
+
}
|
|
31
70
|
const cookieCutterConfig = {
|
|
32
71
|
default_context: {
|
|
33
|
-
name
|
|
72
|
+
name,
|
|
73
|
+
platforms,
|
|
74
|
+
backends
|
|
34
75
|
}
|
|
35
76
|
};
|
|
36
77
|
const cookieCutterConfigFile = path.join(await fs.mkdtemp(path.join(os.tmpdir(), "multiplatform-")), "config.json");
|
|
@@ -55,7 +96,34 @@ program.command("init").option("-r, --remote <remote>", "the remote to use", "ht
|
|
|
55
96
|
});
|
|
56
97
|
}
|
|
57
98
|
});
|
|
58
|
-
program.command("update").option("-r, --remote <remote>", "the remote to use", "https://gitlab.com/bitspur/multiplatform.one/cookiecutter").option("-c, --checkout <branch>", "branch, tag or commit to checkout", "main").description("update multiplatform.one").action(async (options) => {
|
|
99
|
+
program.command("update").option("-r, --remote <remote>", "the remote to use", "https://gitlab.com/bitspur/multiplatform.one/cookiecutter").option("-c, --checkout <branch>", "branch, tag or commit to checkout", "main").option("-p, --platforms <platforms>", "platforms to keep").option("-b, --backends <backends>", "backends to keep").description("update multiplatform.one").action(async (options) => {
|
|
100
|
+
let { backends, platforms } = options;
|
|
101
|
+
if (!backends) {
|
|
102
|
+
const backendsResult = await inquirer.prompt([
|
|
103
|
+
{
|
|
104
|
+
message: "What backends are you using?",
|
|
105
|
+
name: "backends",
|
|
106
|
+
type: "checkbox",
|
|
107
|
+
choices: availableBackends.map((name) => ({
|
|
108
|
+
name
|
|
109
|
+
}))
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
backends = backendsResult.backends.join(",");
|
|
113
|
+
}
|
|
114
|
+
if (!platforms) {
|
|
115
|
+
const platformsResult = await inquirer.prompt([
|
|
116
|
+
{
|
|
117
|
+
message: "What platforms are you using?",
|
|
118
|
+
name: "platforms",
|
|
119
|
+
type: "checkbox",
|
|
120
|
+
choices: availablePlatforms.map((name) => ({
|
|
121
|
+
name
|
|
122
|
+
}))
|
|
123
|
+
}
|
|
124
|
+
]);
|
|
125
|
+
platforms = platformsResult.platforms.join(",");
|
|
126
|
+
}
|
|
59
127
|
if ((await execa("git", [
|
|
60
128
|
"rev-parse",
|
|
61
129
|
"--is-inside-work-tree"
|
|
@@ -80,11 +148,15 @@ program.command("update").option("-r, --remote <remote>", "the remote to use", "
|
|
|
80
148
|
let cookieCutterConfig;
|
|
81
149
|
if ((await fs.stat(path.resolve(projectRoot, "package.json"))).isFile() && (await fs.stat(path.resolve(projectRoot, "app/package.json"))).isFile() && JSON.parse(await fs.readFile(path.resolve(projectRoot, "app/package.json"), "utf8"))?.dependencies?.["multiplatform.one"]?.length) {
|
|
82
150
|
const name = JSON.parse(await fs.readFile(path.resolve(projectRoot, "package.json"), "utf8"))?.name;
|
|
83
|
-
if (name)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
151
|
+
if (name) {
|
|
152
|
+
cookieCutterConfig = {
|
|
153
|
+
default_context: {
|
|
154
|
+
name,
|
|
155
|
+
backends,
|
|
156
|
+
platforms
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
88
160
|
}
|
|
89
161
|
if (!cookieCutterConfig) throw new Error("not a multiplatform.one project");
|
|
90
162
|
const cookieCutterConfigFile = path.join(await fs.mkdtemp(path.join(os.tmpdir(), "multiplatform-")), "config.json");
|
package/lib/types.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"author": "BitSpur <support@bitspur.com> (https://bitspur.com)",
|
|
5
5
|
"contributors": [
|
|
6
6
|
{
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@types/node": "~20.12.13",
|
|
53
53
|
"tsup": "^8.1.0",
|
|
54
54
|
"typescript": "~5.3.3",
|
|
55
|
-
"@multiplatform.one/utils": "^1.0
|
|
55
|
+
"@multiplatform.one/utils": "^0.1.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"commander": "^9.5.0",
|
|
@@ -19,64 +19,141 @@
|
|
|
19
19
|
* limitations under the License.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import { execa } from
|
|
29
|
-
import
|
|
30
|
-
import {
|
|
22
|
+
import fsSync from "node:fs";
|
|
23
|
+
import fs from "node:fs/promises";
|
|
24
|
+
import os from "node:os";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { fileURLToPath } from "node:url";
|
|
27
|
+
import { program } from "commander";
|
|
28
|
+
import { execa } from "execa";
|
|
29
|
+
import inquirer from "inquirer";
|
|
30
|
+
import type { CookieCutterConfig } from "../types";
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const availableBackends = ["api", "frappe"];
|
|
33
|
+
const availablePlatforms = [
|
|
34
|
+
"electron",
|
|
35
|
+
"expo",
|
|
36
|
+
"keycloak",
|
|
37
|
+
"next",
|
|
38
|
+
"storybook",
|
|
39
|
+
"storybook-expo",
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
process.env.COOKIECUTTER = `sh ${path.resolve(
|
|
43
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
44
|
+
"../../scripts/cookiecutter.sh"
|
|
45
|
+
)}`;
|
|
46
|
+
program.name("multiplatform.one");
|
|
34
47
|
program.version(
|
|
35
48
|
JSON.parse(
|
|
36
|
-
fsSync.readFileSync(
|
|
37
|
-
|
|
49
|
+
fsSync.readFileSync(
|
|
50
|
+
path.resolve(
|
|
51
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
52
|
+
"../../package.json"
|
|
53
|
+
),
|
|
54
|
+
"utf8"
|
|
55
|
+
)
|
|
56
|
+
)?.version
|
|
38
57
|
);
|
|
39
58
|
|
|
40
59
|
program
|
|
41
|
-
.command(
|
|
42
|
-
.option(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
60
|
+
.command("init")
|
|
61
|
+
.option(
|
|
62
|
+
"-r, --remote <remote>",
|
|
63
|
+
"the remote to use",
|
|
64
|
+
"https://gitlab.com/bitspur/multiplatform.one/cookiecutter"
|
|
65
|
+
)
|
|
66
|
+
.option(
|
|
67
|
+
"-c, --checkout <branch>",
|
|
68
|
+
"branch, tag or commit to checkout",
|
|
69
|
+
"main"
|
|
70
|
+
)
|
|
71
|
+
.option("-p, --platforms <platforms>", "platforms to keep")
|
|
72
|
+
.option("-b, --backends <backends>", "backends to keep")
|
|
73
|
+
.argument("[name]", "the name of the project", "")
|
|
74
|
+
.description("init multiplatform.one")
|
|
46
75
|
.action(async (name, options) => {
|
|
47
|
-
|
|
48
|
-
|
|
76
|
+
let { backends, platforms } = options;
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
(
|
|
80
|
+
await execa("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
81
|
+
reject: false,
|
|
82
|
+
})
|
|
83
|
+
).exitCode === 0
|
|
84
|
+
) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
"multiplatform.one cannot be initialized inside a git repository"
|
|
87
|
+
);
|
|
49
88
|
}
|
|
50
89
|
if (!name) {
|
|
51
90
|
name = (
|
|
52
91
|
await inquirer.prompt([
|
|
53
92
|
{
|
|
54
|
-
message:
|
|
55
|
-
name:
|
|
56
|
-
type:
|
|
93
|
+
message: "What is the project name?",
|
|
94
|
+
name: "name",
|
|
95
|
+
type: "input",
|
|
57
96
|
},
|
|
58
97
|
])
|
|
59
98
|
).name;
|
|
60
99
|
}
|
|
61
|
-
|
|
62
|
-
|
|
100
|
+
if (!backends) {
|
|
101
|
+
const backendsResult = (
|
|
102
|
+
await inquirer.prompt([
|
|
103
|
+
{
|
|
104
|
+
message: "What backends are you using?",
|
|
105
|
+
name: "backends",
|
|
106
|
+
type: "checkbox",
|
|
107
|
+
choices: availableBackends.map((name) => ({ name })),
|
|
108
|
+
},
|
|
109
|
+
])
|
|
110
|
+
).backends;
|
|
111
|
+
|
|
112
|
+
backends = backendsResult.join(",");
|
|
113
|
+
}
|
|
114
|
+
if (!platforms) {
|
|
115
|
+
const platformsResult = (
|
|
116
|
+
await inquirer.prompt([
|
|
117
|
+
{
|
|
118
|
+
message: "What platforms are you using?",
|
|
119
|
+
name: "platforms",
|
|
120
|
+
type: "checkbox",
|
|
121
|
+
choices: availablePlatforms.map((name) => ({ name })),
|
|
122
|
+
},
|
|
123
|
+
])
|
|
124
|
+
).platforms;
|
|
125
|
+
platforms = platformsResult.join(",");
|
|
126
|
+
}
|
|
127
|
+
const cookieCutterConfig: CookieCutterConfig = {
|
|
128
|
+
default_context: { name, platforms, backends },
|
|
129
|
+
};
|
|
130
|
+
const cookieCutterConfigFile = path.join(
|
|
131
|
+
await fs.mkdtemp(path.join(os.tmpdir(), "multiplatform-")),
|
|
132
|
+
"config.json"
|
|
133
|
+
);
|
|
63
134
|
try {
|
|
64
|
-
await fs.writeFile(
|
|
135
|
+
await fs.writeFile(
|
|
136
|
+
cookieCutterConfigFile,
|
|
137
|
+
JSON.stringify(cookieCutterConfig, null, 2)
|
|
138
|
+
);
|
|
65
139
|
await execa(
|
|
66
|
-
|
|
140
|
+
"sh",
|
|
67
141
|
[
|
|
68
|
-
path.resolve(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
142
|
+
path.resolve(
|
|
143
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
144
|
+
"../../scripts/init.sh"
|
|
145
|
+
),
|
|
146
|
+
"--no-input",
|
|
147
|
+
"-f",
|
|
148
|
+
"--config-file",
|
|
72
149
|
cookieCutterConfigFile,
|
|
73
|
-
|
|
150
|
+
"--checkout",
|
|
74
151
|
options.checkout,
|
|
75
152
|
options.remote,
|
|
76
153
|
],
|
|
77
154
|
{
|
|
78
|
-
stdio:
|
|
79
|
-
}
|
|
155
|
+
stdio: "inherit",
|
|
156
|
+
}
|
|
80
157
|
);
|
|
81
158
|
} finally {
|
|
82
159
|
await fs.rm(cookieCutterConfigFile, { recursive: true, force: true });
|
|
@@ -84,55 +161,113 @@ program
|
|
|
84
161
|
});
|
|
85
162
|
|
|
86
163
|
program
|
|
87
|
-
.command(
|
|
88
|
-
.option(
|
|
89
|
-
|
|
90
|
-
|
|
164
|
+
.command("update")
|
|
165
|
+
.option(
|
|
166
|
+
"-r, --remote <remote>",
|
|
167
|
+
"the remote to use",
|
|
168
|
+
"https://gitlab.com/bitspur/multiplatform.one/cookiecutter"
|
|
169
|
+
)
|
|
170
|
+
.option(
|
|
171
|
+
"-c, --checkout <branch>",
|
|
172
|
+
"branch, tag or commit to checkout",
|
|
173
|
+
"main"
|
|
174
|
+
)
|
|
175
|
+
.option("-p, --platforms <platforms>", "platforms to keep")
|
|
176
|
+
.option("-b, --backends <backends>", "backends to keep")
|
|
177
|
+
.description("update multiplatform.one")
|
|
91
178
|
.action(async (options) => {
|
|
92
|
-
|
|
93
|
-
|
|
179
|
+
let { backends, platforms } = options;
|
|
180
|
+
if (!backends) {
|
|
181
|
+
const backendsResult = await inquirer.prompt([
|
|
182
|
+
{
|
|
183
|
+
message: "What backends are you using?",
|
|
184
|
+
name: "backends",
|
|
185
|
+
type: "checkbox",
|
|
186
|
+
choices: availableBackends.map((name) => ({ name })),
|
|
187
|
+
},
|
|
188
|
+
]);
|
|
189
|
+
backends = backendsResult.backends.join(",");
|
|
190
|
+
}
|
|
191
|
+
if (!platforms) {
|
|
192
|
+
const platformsResult = await inquirer.prompt([
|
|
193
|
+
{
|
|
194
|
+
message: "What platforms are you using?",
|
|
195
|
+
name: "platforms",
|
|
196
|
+
type: "checkbox",
|
|
197
|
+
choices: availablePlatforms.map((name) => ({ name })),
|
|
198
|
+
},
|
|
199
|
+
]);
|
|
200
|
+
platforms = platformsResult.platforms.join(",");
|
|
201
|
+
}
|
|
202
|
+
if (
|
|
203
|
+
(
|
|
204
|
+
await execa("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
205
|
+
reject: false,
|
|
206
|
+
})
|
|
207
|
+
).exitCode !== 0
|
|
208
|
+
) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
"multiplatform.one cannot be updated outside of a git repository"
|
|
211
|
+
);
|
|
94
212
|
}
|
|
95
213
|
if (
|
|
96
214
|
(
|
|
97
|
-
await execa(
|
|
215
|
+
await execa("git", ["diff", "--cached", "--quiet"], {
|
|
98
216
|
reject: false,
|
|
99
217
|
})
|
|
100
218
|
).exitCode !== 0
|
|
101
219
|
) {
|
|
102
|
-
throw new Error(
|
|
220
|
+
throw new Error(
|
|
221
|
+
"multiplatform.one cannot be updated with uncommitted changes"
|
|
222
|
+
);
|
|
103
223
|
}
|
|
104
|
-
const projectRoot = (
|
|
224
|
+
const projectRoot = (
|
|
225
|
+
await execa("git", ["rev-parse", "--show-toplevel"])
|
|
226
|
+
).stdout.trim();
|
|
105
227
|
let cookieCutterConfig: CookieCutterConfig | undefined;
|
|
106
228
|
if (
|
|
107
|
-
(await fs.stat(path.resolve(projectRoot,
|
|
108
|
-
(await fs.stat(path.resolve(projectRoot,
|
|
109
|
-
JSON.parse(
|
|
110
|
-
|
|
111
|
-
]?.length
|
|
229
|
+
(await fs.stat(path.resolve(projectRoot, "package.json"))).isFile() &&
|
|
230
|
+
(await fs.stat(path.resolve(projectRoot, "app/package.json"))).isFile() &&
|
|
231
|
+
JSON.parse(
|
|
232
|
+
await fs.readFile(path.resolve(projectRoot, "app/package.json"), "utf8")
|
|
233
|
+
)?.dependencies?.["multiplatform.one"]?.length
|
|
112
234
|
) {
|
|
113
|
-
const name = JSON.parse(
|
|
114
|
-
|
|
235
|
+
const name = JSON.parse(
|
|
236
|
+
await fs.readFile(path.resolve(projectRoot, "package.json"), "utf8")
|
|
237
|
+
)?.name;
|
|
238
|
+
if (name) {
|
|
239
|
+
cookieCutterConfig = { default_context: { name, backends, platforms } };
|
|
240
|
+
}
|
|
115
241
|
}
|
|
116
|
-
if (!cookieCutterConfig) throw new Error(
|
|
117
|
-
const cookieCutterConfigFile = path.join(
|
|
242
|
+
if (!cookieCutterConfig) throw new Error("not a multiplatform.one project");
|
|
243
|
+
const cookieCutterConfigFile = path.join(
|
|
244
|
+
await fs.mkdtemp(path.join(os.tmpdir(), "multiplatform-")),
|
|
245
|
+
"config.json"
|
|
246
|
+
);
|
|
118
247
|
try {
|
|
119
|
-
await fs.writeFile(
|
|
248
|
+
await fs.writeFile(
|
|
249
|
+
cookieCutterConfigFile,
|
|
250
|
+
JSON.stringify(cookieCutterConfig, null, 2)
|
|
251
|
+
);
|
|
120
252
|
await execa(
|
|
121
|
-
|
|
253
|
+
"sh",
|
|
122
254
|
[
|
|
123
|
-
path.resolve(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
255
|
+
path.resolve(
|
|
256
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
257
|
+
"../../scripts/update.sh"
|
|
258
|
+
),
|
|
259
|
+
"--no-input",
|
|
260
|
+
"-f",
|
|
261
|
+
"--config-file",
|
|
127
262
|
cookieCutterConfigFile,
|
|
128
|
-
|
|
263
|
+
"--checkout",
|
|
129
264
|
options.checkout,
|
|
130
265
|
options.remote,
|
|
131
266
|
],
|
|
132
267
|
{
|
|
133
268
|
cwd: projectRoot,
|
|
134
|
-
stdio:
|
|
135
|
-
}
|
|
269
|
+
stdio: "inherit",
|
|
270
|
+
}
|
|
136
271
|
);
|
|
137
272
|
} finally {
|
|
138
273
|
await fs.rm(cookieCutterConfigFile, { recursive: true, force: true });
|
package/src/index.ts
CHANGED