@rollipop/init 0.0.0 → 0.1.0-alpha.4
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/README.md +1 -1
- package/bin/index.js +3 -0
- package/dist/index.js +120 -0
- package/package.json +38 -2
- package/.editorconfig +0 -10
- package/.gitattributes +0 -4
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# rollipop
|
|
1
|
+
# @rollipop/core
|
package/bin/index.js
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import glob from "fast-glob";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import whichPm from "which-pm";
|
|
6
|
+
import xcode from "xcode";
|
|
7
|
+
|
|
8
|
+
//#region src/index.ts
|
|
9
|
+
const TARGET_BUILD_PHASE_NAME = "Bundle React Native code and images";
|
|
10
|
+
const EXPORT_CLI_PATH = "export CLI_PATH=\"$PROJECT_DIR/node_modules/rollipop/bin/index.js\"";
|
|
11
|
+
const logger = {
|
|
12
|
+
success(message) {
|
|
13
|
+
console.log(pc.green("✓"), message);
|
|
14
|
+
},
|
|
15
|
+
error(message, reason) {
|
|
16
|
+
console.error(pc.red("✗"), `${message}: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
async function findAppBuildGradle(cwd$1) {
|
|
20
|
+
const files = await glob("**/android/app/build.gradle", { cwd: cwd$1 });
|
|
21
|
+
if (files.length === 0) throw new Error("No Android build.gradle found");
|
|
22
|
+
if (files.length > 1) throw new Error("Multiple Android build.gradle found:\n" + files.join("\n"));
|
|
23
|
+
return path.join(cwd$1, files[0]);
|
|
24
|
+
}
|
|
25
|
+
async function updateGradleCLIPath(appBuildGradlePath) {
|
|
26
|
+
const appBuildGradleLines = fs.readFileSync(appBuildGradlePath, "utf8").split("\n");
|
|
27
|
+
if (appBuildGradleLines.find((line) => line.trim().startsWith("cliFile ="))) throw new Error(`'cliFile' already configured`);
|
|
28
|
+
const index = appBuildGradleLines.findIndex((line) => line.trim().startsWith("react {"));
|
|
29
|
+
if (index === -1) throw new Error(`'react' configuration block not found in build.gradle`);
|
|
30
|
+
fs.writeFileSync(appBuildGradlePath, [
|
|
31
|
+
...appBuildGradleLines.slice(0, index + 1),
|
|
32
|
+
" cliFile = file(\"../../node_modules/rollipop/bin/index.js\")",
|
|
33
|
+
...appBuildGradleLines.slice(index + 1)
|
|
34
|
+
].join("\n"));
|
|
35
|
+
}
|
|
36
|
+
async function findXCodeProject(cwd$1) {
|
|
37
|
+
const basePath = path.join(cwd$1, "ios");
|
|
38
|
+
const files = await glob("**/*.xcodeproj/project.pbxproj", {
|
|
39
|
+
cwd: basePath,
|
|
40
|
+
ignore: ["Pods/**"]
|
|
41
|
+
});
|
|
42
|
+
if (files.length === 0) throw new Error("No Xcode project found");
|
|
43
|
+
if (files.length > 1) throw new Error("Multiple Xcode projects found:\n" + files.join("\n"));
|
|
44
|
+
return path.join(basePath, files[0]);
|
|
45
|
+
}
|
|
46
|
+
function updateXCodeCLIPath(xcodeProjectPath) {
|
|
47
|
+
const project = xcode.project(xcodeProjectPath).parseSync();
|
|
48
|
+
const buildPhase = Object.entries(project.hash?.project?.objects?.PBXShellScriptBuildPhase ?? {}).find(([_key, phase]) => phase.name.includes(TARGET_BUILD_PHASE_NAME));
|
|
49
|
+
if (buildPhase == null) throw new Error(`'${TARGET_BUILD_PHASE_NAME}' build phase not found`);
|
|
50
|
+
const originShellScript = JSON.parse(buildPhase[1].shellScript);
|
|
51
|
+
if (originShellScript.includes("CLI_PATH=")) throw new Error(`'CLI_PATH' environment variable already configured`);
|
|
52
|
+
const originShellScriptLines = originShellScript.split("\n");
|
|
53
|
+
const index = originShellScriptLines.findIndex((line) => line.trim().startsWith("set -"));
|
|
54
|
+
let newShellScript = "";
|
|
55
|
+
if (index === -1) newShellScript = `${EXPORT_CLI_PATH}\n${originShellScript}`;
|
|
56
|
+
else newShellScript = [
|
|
57
|
+
...originShellScriptLines.slice(0, index + 1),
|
|
58
|
+
EXPORT_CLI_PATH,
|
|
59
|
+
...originShellScriptLines.slice(index + 1)
|
|
60
|
+
].join("\n");
|
|
61
|
+
buildPhase[1].shellScript = JSON.stringify(newShellScript);
|
|
62
|
+
fs.writeFileSync(project.filepath, project.writeSync());
|
|
63
|
+
}
|
|
64
|
+
async function setupAndroid(cwd$1) {
|
|
65
|
+
await updateGradleCLIPath(await findAppBuildGradle(cwd$1));
|
|
66
|
+
}
|
|
67
|
+
async function setupIos(cwd$1) {
|
|
68
|
+
updateXCodeCLIPath(await findXCodeProject(cwd$1));
|
|
69
|
+
}
|
|
70
|
+
function setupPackage(cwd$1) {
|
|
71
|
+
const packageJsonPath = path.join(cwd$1, "package.json");
|
|
72
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
73
|
+
packageJson.devDependencies = {
|
|
74
|
+
...packageJson.devDependencies,
|
|
75
|
+
rollipop: "latest"
|
|
76
|
+
};
|
|
77
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
78
|
+
}
|
|
79
|
+
const cwd = process.cwd();
|
|
80
|
+
let failed = false;
|
|
81
|
+
try {
|
|
82
|
+
await setupAndroid(cwd);
|
|
83
|
+
logger.success("Android setup completed");
|
|
84
|
+
} catch (error) {
|
|
85
|
+
logger.error("Android setup failed", error);
|
|
86
|
+
failed ||= true;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
await setupIos(cwd);
|
|
90
|
+
logger.success("iOS setup completed");
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.error("iOS setup failed", error);
|
|
93
|
+
failed ||= true;
|
|
94
|
+
}
|
|
95
|
+
let packageManager = null;
|
|
96
|
+
try {
|
|
97
|
+
packageManager = (await whichPm(cwd))?.name ?? null;
|
|
98
|
+
setupPackage(cwd);
|
|
99
|
+
logger.success("Package setup completed");
|
|
100
|
+
} catch (error) {
|
|
101
|
+
logger.error("Package setup failed", error);
|
|
102
|
+
failed ||= true;
|
|
103
|
+
}
|
|
104
|
+
if (failed) {
|
|
105
|
+
console.warn(`
|
|
106
|
+
Failed to setup project automatically
|
|
107
|
+
|
|
108
|
+
Please follow the manual setup guide: ${pc.underline("https://rollipop.dev/docs/get-started/quick-start")}`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
} else {
|
|
111
|
+
logger.success("Project setup completed");
|
|
112
|
+
if (packageManager == null) console.log("No package manager found, please install dependencies manually");
|
|
113
|
+
else {
|
|
114
|
+
const command = pc.bold(`${packageManager} install`);
|
|
115
|
+
console.log(`Run ${command} to install dependencies`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
export { };
|
package/package.json
CHANGED
|
@@ -1,4 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rollipop/init",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": "./bin/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"bin",
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/leegeunhyeok/rollipop.git",
|
|
13
|
+
"directory": "packages/core"
|
|
14
|
+
},
|
|
15
|
+
"author": "leegeunhyeok <dev.ghlee@gmail.com> (https://github.com/leegeunhyeok)",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/leegeunhyeok/rollipop/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/leegeunhyeok/rollipop#readme",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"execute": "tsx src/index.ts",
|
|
23
|
+
"prepack": "yarn build",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"test": "vitest --run --passWithNoTests",
|
|
26
|
+
"build": "tsdown"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"fast-glob": "^3.3.3",
|
|
30
|
+
"picocolors": "^1.1.1",
|
|
31
|
+
"which-pm": "^3.0.1",
|
|
32
|
+
"xcode": "^3.0.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"tsdown": "0.18.1",
|
|
36
|
+
"tsx": "^4.21.0",
|
|
37
|
+
"typescript": "5.9.3",
|
|
38
|
+
"vitest": "4.0.16"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/.editorconfig
DELETED
package/.gitattributes
DELETED