Skip to content

Commit d4777af

Browse files
Bump version to 1.0.3, update Chocolatey installation script, and add setup script for React Native environment
1 parent 2f2dce3 commit d4777af

File tree

3 files changed

+77
-56
lines changed

3 files changed

+77
-56
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-cli-setup",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"type": "module",
55
"main": "./dist/esm/index.js",
66
"module": "./dist/esm/index.js",

src/ChocolateyInstallNonAdmin.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ Set-ExecutionPolicy Bypass -Scope Process -Force;
1414
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
1515

1616
# Optionally, you can verify the installation by checking the Chocolatey version
17-
choco --version
17+
# choco --version

src/index.ts

Lines changed: 75 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import fs from "fs";
66
import path from "path";
77
import { fileURLToPath } from "url";
88
import { execSync } from "child_process";
9+
910
// THIRD-PARTY MODULES
1011
import ora from "ora";
1112
import chalk from "chalk";
@@ -15,9 +16,8 @@ import inquirer from "inquirer";
1516
// Get the directory name of the current module
1617
const __filename = fileURLToPath(import.meta.url);
1718
const __dirname = path.dirname(__filename);
18-
const options = { name: "RN Setup by Sumit Singh Rathore" };
1919

20-
// Function to check if a command exists
20+
/** Function to check if a command exists */
2121
function checkCommand(command: string): boolean {
2222
try {
2323
execSync(`where ${command}`);
@@ -27,25 +27,35 @@ function checkCommand(command: string): boolean {
2727
}
2828
}
2929

30-
// Function to install Chocolatey
31-
async function installChocolatey() {
32-
const spinner = ora({ text: chalk.blue("Installing Chocolatey...") }).start();
30+
/** Retry function */
31+
async function retry(task: () => Promise<void>, retries = 3): Promise<void> {
32+
for (let attempt = 0; attempt < retries; attempt++) {
33+
try {
34+
await task();
35+
return; // Exit if the task succeeds
36+
} catch (error) {
37+
console.error(error);
38+
if (attempt === retries - 1) throw new Error("Max retries reached");
39+
console.log(`Retrying... (${attempt + 1}/${retries})`);
40+
}
41+
}
42+
}
3343

44+
/** Function to install Chocolatey */
45+
async function installChocolatey(): Promise<void> {
46+
const spinner = ora({ text: chalk.blue("Installing Chocolatey...") }).start();
3447
try {
3548
const admin = await isAdmin();
36-
3749
// Check if Chocolatey is already installed
3850
if (checkCommand("choco")) {
3951
spinner.succeed(chalk.green("Chocolatey is already installed."));
4052
return;
4153
}
42-
4354
if (!admin) {
4455
spinner.info(
4556
chalk.yellow("Running Chocolatey installation as non-admin...")
4657
);
47-
const scriptPath = path.join(__dirname, "ChocolateyInstallNonAdmin.ps1"); // Adjust this path as necessary
48-
58+
const scriptPath = path.join(__dirname, "ChocolateyInstallNonAdmin.ps1");
4959
// Execute the PowerShell script for non-admin installation
5060
execSync(`powershell.exe -ExecutionPolicy Bypass -File "${scriptPath}"`, {
5161
stdio: "inherit",
@@ -62,7 +72,6 @@ async function installChocolatey() {
6272
);
6373
spinner.succeed(chalk.green("Chocolatey installed successfully."));
6474
}
65-
6675
// Add Chocolatey to the current session's PATH
6776
const chocoPath = `${process.env.ProgramData}\\chocoportable\\bin`;
6877
process.env.PATH = `${process.env.PATH};${chocoPath}`;
@@ -73,12 +82,11 @@ async function installChocolatey() {
7382
}
7483
}
7584

76-
// Function to install JDK
77-
async function installJDK() {
85+
/** Function to install JDK */
86+
async function installJDK(): Promise<void> {
7887
const spinner = ora({
7988
text: chalk.blue("Checking for JDK installation..."),
8089
}).start();
81-
8290
spinner.stop();
8391
if (process.platform === "win32") {
8492
if (!checkCommand("java")) {
@@ -88,7 +96,7 @@ async function installJDK() {
8896
await installChocolatey();
8997
}
9098
try {
91-
execSync("choco install -y microsoft-openjdk17", { stdio: "inherit" });
99+
execSync("choco install microsoft-openjdk17", { stdio: "inherit" });
92100
spinner.succeed(chalk.green("OpenJDK installed successfully."));
93101
} catch (error) {
94102
spinner.fail(chalk.red("Failed to install OpenJDK."));
@@ -125,11 +133,15 @@ async function installJDK() {
125133
}
126134
}
127135

128-
// Function to install Android Studio
129-
async function installAndroidStudio() {
136+
/** Function to install Android Studio */
137+
async function installAndroidStudio(): Promise<void> {
130138
const spinner = ora({
131139
text: chalk.blue("Checking for Android Studio installation..."),
132140
}).start();
141+
spinner.stop();
142+
if (!checkCommand("choco")) {
143+
await installChocolatey();
144+
}
133145

134146
const androidStudioPath = path.join(
135147
process.env.ProgramFiles || "C:\\Program Files",
@@ -139,21 +151,16 @@ async function installAndroidStudio() {
139151
"studio.exe"
140152
);
141153

142-
spinner.stop();
143-
144154
if (process.platform === "win32") {
145155
if (!fs.existsSync(androidStudioPath)) {
146156
spinner.text = chalk.yellow("Installing Android Studio...");
147157
spinner.start();
148158
try {
149159
// Path to your PowerShell script
150160
const scriptPath = path.join(__dirname, "AndroidStudioInstall.ps1");
151-
152-
// Run the PowerShell script
153161
execSync(`powershell -ExecutionPolicy Bypass -File "${scriptPath}"`, {
154162
stdio: "inherit",
155163
});
156-
157164
spinner.succeed(chalk.green("Android Studio installed successfully."));
158165
} catch (error) {
159166
spinner.fail(chalk.red("Failed to install Android Studio."));
@@ -163,28 +170,52 @@ async function installAndroidStudio() {
163170
} else {
164171
spinner.succeed(chalk.green("Android Studio is already installed."));
165172
}
173+
} else {
174+
spinner.fail(
175+
chalk.red(
176+
"Please install Android Studio manually on non-Windows systems."
177+
)
178+
);
179+
}
180+
}
166181

182+
/** Function to add Android Studio to PATH */
183+
async function addAndroidStudioToPath(): Promise<void> {
184+
const spinner = ora({
185+
text: chalk.blue("Adding Android Studio to PATH..."),
186+
}).start();
187+
spinner.stop();
188+
189+
if (process.platform === "win32") {
167190
// Set ANDROID_HOME environment variable
168191
const androidHomePath = path.join(
169192
process.env.ProgramFiles || "C:\\Program Files",
170193
"Android",
171194
"Sdk"
172195
);
196+
197+
if (!fs.existsSync(androidHomePath)) {
198+
spinner.fail(
199+
chalk.red("Android SDK not found. Please install Android Studio.")
200+
);
201+
return;
202+
}
203+
173204
try {
174205
execSync(`setx ANDROID_HOME "${androidHomePath}" /M`, {
175206
stdio: "inherit",
176207
});
177208
execSync(`setx ANDROID_SDK_ROOT "${androidHomePath}" /M`, {
178209
stdio: "inherit",
179210
});
211+
180212
execSync(
181213
`setx PATH "%PATH%;${androidHomePath}\\tools;${androidHomePath}\\platform-tools" /M`,
182214
{ stdio: "inherit" }
183215
);
216+
184217
spinner.succeed(
185-
chalk.green(
186-
"ANDROID_HOME and ANDROID_SDK_ROOT environment variables set successfully."
187-
)
218+
chalk.green("Android Studio added to PATH successfully.")
188219
);
189220
} catch (error) {
190221
spinner.fail(
@@ -195,17 +226,11 @@ async function installAndroidStudio() {
195226
console.error(error);
196227
throw error;
197228
}
198-
} else {
199-
spinner.fail(
200-
chalk.red(
201-
"Please install Android Studio manually on non-Windows systems."
202-
)
203-
);
204229
}
205230
}
206231

207-
// Function to prompt user for project details
208-
async function promptUserForProjectDetails() {
232+
/** Function to prompt user for project details */
233+
async function promptUserForProjectDetails(): Promise<{ projectName: string }> {
209234
const questions = [
210235
{
211236
type: "input",
@@ -215,19 +240,13 @@ async function promptUserForProjectDetails() {
215240
validate: (input: string) =>
216241
input.length > 0 ? true : "Project name cannot be empty.",
217242
},
218-
// {
219-
// type: "list",
220-
// name: "template",
221-
// message: "Which template would you like to use?",
222-
// choices: ["Default", "TypeScript"],
223-
// },
224243
];
225244

226245
return await inquirer.prompt(questions);
227246
}
228247

229-
// Function to create a new React Native project
230-
async function createReactNativeProject(projectName: string, template: string) {
248+
/** Function to create a new React Native project */
249+
async function createReactNativeProject(projectName: string): Promise<void> {
231250
const spinner = ora({
232251
text: chalk.blue(`Creating React Native project "${projectName}"...`),
233252
}).start();
@@ -236,21 +255,22 @@ async function createReactNativeProject(projectName: string, template: string) {
236255
execSync(`npx @react-native-community/cli@latest init ${projectName}`, {
237256
stdio: "inherit",
238257
});
258+
239259
spinner.succeed(
240260
chalk.green(`Project "${projectName}" created successfully.`)
241261
);
242262

243-
spinner.text = chalk.blue(
244-
`Installing dependencies and starting the project...`
245-
);
246-
// Change directory to the project folder
263+
// Change directory and install dependencies
247264
process.chdir(projectName);
248265

249-
// Install dependencies
250-
execSync("npm install", { stdio: "inherit" });
266+
await retry(async () => {
267+
execSync("npm install", { stdio: "inherit" });
268+
});
251269

252270
// Start the project
253-
execSync("npm run start", { stdio: "inherit" });
271+
await retry(async () => {
272+
execSync("npm run start", { stdio: "inherit" });
273+
});
254274

255275
spinner.succeed(
256276
chalk.green(`Dependencies installed and project started successfully.`)
@@ -261,20 +281,21 @@ async function createReactNativeProject(projectName: string, template: string) {
261281
}
262282
}
263283

264-
// Main setup function
265-
export async function setup() {
284+
/** Main setup function */
285+
export async function setup(): Promise<void> {
266286
console.log(chalk.cyan("Setting up React Native development environment..."));
267287

268288
// Check and install necessary tools
269-
await installJDK();
270-
await installChocolatey();
271-
await installAndroidStudio();
289+
await retry(installChocolatey);
290+
await retry(installJDK);
291+
await retry(installAndroidStudio);
292+
await retry(addAndroidStudioToPath);
272293

273294
// Prompt user for project details
274-
const { projectName, template } = await promptUserForProjectDetails();
295+
const { projectName } = await promptUserForProjectDetails();
275296

276297
// Create the React Native project with user inputs
277-
await createReactNativeProject(projectName, template);
298+
await retry(() => createReactNativeProject(projectName));
278299

279300
console.log(chalk.green("Setup completed successfully!"));
280301
}

0 commit comments

Comments
 (0)