Skip to content

Commit 7ab2c83

Browse files
committed
Initial commit
0 parents  commit 7ab2c83

File tree

7 files changed

+13581
-0
lines changed

7 files changed

+13581
-0
lines changed

.gitignore

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env
17+
.env.local
18+
.env.development.local
19+
.env.test.local
20+
.env.production.local
21+
22+
npm-debug.log*
23+
yarn-debug.log*
24+
yarn-error.log*
25+
26+
# OSX
27+
#
28+
.DS_Store
29+
30+
# Xcode
31+
#
32+
build/
33+
*.pbxuser
34+
!default.pbxuser
35+
*.mode1v3
36+
!default.mode1v3
37+
*.mode2v3
38+
!default.mode2v3
39+
*.perspectivev3
40+
!default.perspectivev3
41+
xcuserdata
42+
*.xccheckout
43+
*.moved-aside
44+
DerivedData
45+
*.hmap
46+
*.ipa
47+
*.xcuserstate
48+
49+
# Android/IntelliJ
50+
#
51+
build/
52+
.idea
53+
.gradle
54+
local.properties
55+
*.iml
56+
57+
# Panic's Nova.app IDE
58+
.nova
59+
60+
# node.js
61+
#
62+
node_modules/
63+
npm-debug.log
64+
yarn-error.log
65+
66+
# BUCK
67+
buck-out/
68+
\.buckd/
69+
*.keystore
70+
!debug.keystore
71+
72+
# fastlane
73+
#
74+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
75+
# screenshots whenever they are needed.
76+
# For more information about the recommended setup visit:
77+
# https://docs.fastlane.tools/best-practices/source-control/
78+
79+
*/fastlane/report.xml
80+
*/fastlane/Preview.html
81+
*/fastlane/screenshots
82+
83+
# Bundle artifact
84+
*.jsbundle
85+
86+
# CocoaPods
87+
/ios/Pods/
88+
89+
#next
90+
.next
91+
src/.next
92+
93+
# @generated: @expo/[email protected]
94+
/.expo/*
95+
# Expo Web
96+
/web-build/*
97+
# Expo Native
98+
*.jks
99+
*.p8
100+
*.p12
101+
*.key
102+
*.mobileprovision
103+
*.orig.*
104+
# Next.js
105+
/.next/*
106+
/out/
107+
# Next.js production
108+
/build/
109+
# Next.js dependencies
110+
/.pnp
111+
.pnp.js
112+
# @end @expo/next-adapter
113+
114+
.nova

cli.js

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env node
2+
3+
const chalk = require('chalk');
4+
const commander = require('commander');
5+
// const fs = require('fs-extra');
6+
// const path = require('path');
7+
const execSync = require('child_process').execSync;
8+
const packageJson = require('./package.json');
9+
// const copyFiles = require('./copyFiles');
10+
11+
const nodeVersion = process.versions.node;
12+
const nodeVersionSplitted = nodeVersion.split('.');
13+
const nodeMajorVersion = nodeVersionSplitted[0];
14+
15+
if (nodeMajorVersion < 8) {
16+
console.error(
17+
chalk.red(`
18+
You are running Node ${nodeVersion}
19+
Create React Once App requires Node 8 or higher.
20+
Please update your version of Node.
21+
`),
22+
);
23+
process.exit(1);
24+
}
25+
26+
const printCyan = (text) => console.log(` ${chalk.cyan(text)}`);
27+
// const printGreen = (text) => console.log(` ${chalk.green(text)}`);
28+
29+
let appName;
30+
const program = new commander.Command(packageJson.name)
31+
.version(packageJson.version)
32+
.arguments('<project-directory>')
33+
.usage(`${chalk.green('<project-directory>')}`)
34+
.action((name) => {
35+
appName = name;
36+
})
37+
.on('--help', () => {
38+
console.log(` ${chalk.green('<project-directory>')} is required.`);
39+
console.log();
40+
console.log(
41+
` If you have any problems, do not hesitate to file an issue:`,
42+
);
43+
printCyan(
44+
'https://gitlab.com/NoahGray/react-once-template/issues/new',
45+
);
46+
console.log();
47+
})
48+
.parse(process.argv);
49+
50+
async function run() {
51+
if (appName) {
52+
printCyan(`⏳ Creating React Once App by the name of ${appName}`);
53+
console.log();
54+
55+
execSync(
56+
`npx react-native init ${appName} --template https://gitlab.com/NoahGray/react-once-template.git`,
57+
{stdio: [0, 1, 2]},
58+
);
59+
60+
let isYarnAvailable;
61+
try {
62+
execSync('yarnpkg --version', {stdio: 'ignore'});
63+
isYarnAvailable = true;
64+
} catch (e) {
65+
isYarnAvailable = false;
66+
}
67+
68+
try {
69+
execSync(`cd ${appName} && git init`);
70+
} catch (error) {}
71+
72+
const packageManagerRunCommand = isYarnAvailable ? 'yarn' : 'npm run';
73+
console.log(`
74+
${chalk.magenta('*')} ${chalk.magenta(
75+
'change directory to your new project',
76+
)}
77+
$ ${chalk.cyan(`cd ${appName}`)}
78+
79+
$ ${chalk.cyan('Then run the these commands to get started:')}
80+
81+
${chalk.magenta('*')} ${chalk.magenta('To run development Web server')}
82+
$ ${chalk.cyan(packageManagerRunCommand + ' web')}
83+
84+
${chalk.magenta('*')} ${chalk.magenta(
85+
'To run Android on connected device (after installing Android Debug Bridge "adb" - https://developer.android.com/studio/releases/platform-tools)',
86+
)}
87+
$ ${chalk.cyan(packageManagerRunCommand + ' android')}
88+
89+
${chalk.magenta('*')} ${chalk.magenta(
90+
'To run ios simulator (after installing Xcode - only on Apple devices)',
91+
)}
92+
$ ${chalk.cyan(packageManagerRunCommand + ' ios')}
93+
94+
${chalk.magenta('*')} ${chalk.magenta(
95+
'To run tests for Native and Web',
96+
)}
97+
$ ${chalk.cyan(packageManagerRunCommand + ' test')}
98+
99+
${chalk.magenta('*')} ${chalk.magenta('To run build for Web')}
100+
$ ${chalk.cyan(packageManagerRunCommand + ' build')}
101+
`);
102+
} else {
103+
console.error(
104+
chalk.red(
105+
'In order to create a new project you must give a name as an argument. ',
106+
),
107+
chalk.cyan('Example: create-react-once-app AppName'),
108+
);
109+
process.exit(1);
110+
}
111+
}
112+
113+
try {
114+
run();
115+
} catch (error) {
116+
console.error(error);
117+
}

cli.test.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
const chalk = require('chalk');
2+
const execSync = require('child_process').execSync;
3+
4+
const originalConsoleLog = console.log;
5+
console.log = jest.fn(() => true);
6+
7+
const originalConsoleError = console.error;
8+
console.error = jest.fn();
9+
10+
jest.mock('child_process', () => {
11+
const execSync = jest.fn();
12+
13+
return {execSync};
14+
});
15+
16+
jest.mock('chalk', () => {
17+
const red = jest.fn((text) => text);
18+
const cyan = jest.fn((text) => text);
19+
const green = jest.fn((text) => text);
20+
const magenta = jest.fn((text) => text);
21+
22+
return {
23+
red,
24+
cyan,
25+
green,
26+
magenta,
27+
};
28+
});
29+
30+
describe('cli runs properly', () => {
31+
it('cli runs with argument and logs info', (done) => {
32+
process.argv[2] = 'myFakeName';
33+
jest.requireActual('./cli');
34+
35+
let isYarnAvailable;
36+
try {
37+
execSync('yarnpkg --version', {stdio: 'ignore'});
38+
isYarnAvailable = true;
39+
} catch (e) {
40+
isYarnAvailable = false;
41+
}
42+
43+
const packageManagerRunCommand = isYarnAvailable ? 'yarn' : 'npm run';
44+
process.nextTick(() => {
45+
expect(chalk.red.mock.calls).toEqual([]);
46+
expect(chalk.cyan.mock.calls).toEqual([
47+
['⏳ Creating React Once App by the name of myFakeName'],
48+
['cd myFakeName'],
49+
['Then run the these commands to get started:'],
50+
[`${packageManagerRunCommand} web`],
51+
[`${packageManagerRunCommand} android`],
52+
[`${packageManagerRunCommand} ios`],
53+
[`${packageManagerRunCommand} test`],
54+
[`${packageManagerRunCommand} build`],
55+
]);
56+
expect(chalk.green.mock.calls).toEqual([['<project-directory>']]);
57+
expect(chalk.magenta.mock.calls).toEqual([
58+
['*'],
59+
['change directory to your new project'],
60+
['*'],
61+
['To run development Web server'],
62+
['*'],
63+
[
64+
'To run Android on connected device (after installing Android Debug Bridge "adb" - https://developer.android.com/studio/releases/platform-tools)',
65+
],
66+
['*'],
67+
[
68+
'To run ios simulator (after installing Xcode - only on Apple devices)',
69+
],
70+
['*'],
71+
['To run tests for Native and Web'],
72+
['*'],
73+
['To run build for Web'],
74+
]);
75+
76+
expect(execSync.mock.calls).toEqual([
77+
[
78+
'npx react-native init myFakeName --template https://gitlab.com/NoahGray/react-once-template.git',
79+
{stdio: [0, 1, 2]},
80+
],
81+
['yarnpkg --version', {stdio: 'ignore'}],
82+
['cd myFakeName && git init'],
83+
['yarnpkg --version', {stdio: 'ignore'}],
84+
]);
85+
});
86+
done();
87+
});
88+
});

error.test.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const chalk = require('chalk');
2+
const commander = require('commander');
3+
const path = require('path');
4+
const execSync = require('child_process').execSync;
5+
const packageJson = require('./package.json');
6+
7+
const originalConsoleLog = console.log;
8+
console.log = jest.fn();
9+
10+
const originalConsoleError = console.error;
11+
console.error = jest.fn();
12+
13+
jest.mock('child_process', () => {
14+
const execSync = jest.fn();
15+
16+
return { execSync };
17+
});
18+
19+
jest.mock('chalk', () => {
20+
const red = jest.fn(text => text);
21+
const cyan = jest.fn(text => text);
22+
const green = jest.fn(text => text);
23+
const magenta = jest.fn(text => text);
24+
25+
return {
26+
red,
27+
cyan,
28+
green,
29+
magenta,
30+
};
31+
});
32+
33+
describe('cli shows error', () => {
34+
it('cli runs without arguments', () => {
35+
const originalProcessExit = process.exit;
36+
process.exit = jest.fn();
37+
process.argv[2] = '';
38+
require('./cli');
39+
40+
41+
expect(console.error.mock.calls).toEqual([['In order to create a new project you must give a name as an argument. ', 'Example: create-react-once-app AppName']]);
42+
expect(process.exit.mock.calls).toEqual([[1]]);
43+
process.exit = originalProcessExit;
44+
});
45+
});

0 commit comments

Comments
 (0)