diff --git a/.eslintrc.js b/.eslintrc.js
index 1c885b1..7668090 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -2,12 +2,22 @@
// Distributed under Apache 2.0 License. See LICENSE file in the project root for full license information.
// ESLint config for magic-script-cli project.
module.exports = {
- "env": {
- "es6": true,
- "node": true
- },
- "parserOptions": {
- "ecmaVersion": 2018
- },
- "extends": "semistandard"
+ env: {
+ es6: true,
+ node: true
+ },
+ parserOptions: {
+ ecmaVersion: 2018
+ },
+ rules: {
+ 'space-before-function-paren': [
+ 'error',
+ {
+ anonymous: 'always',
+ named: 'never',
+ asyncArrow: 'always'
+ }
+ ]
+ },
+ extends: 'semistandard'
};
diff --git a/__tests__/initutils.js b/__tests__/initutils.js
index f4fe918..04c6824 100644
--- a/__tests__/initutils.js
+++ b/__tests__/initutils.js
@@ -2,6 +2,7 @@ jest.mock('fs');
jest.mock('../lib/util');
jest.mock('../lib/logger');
jest.mock('child_process');
+jest.mock('../lib/rename/rename.js');
const child_process = require('child_process');
jest.spyOn(child_process, 'spawnSync');
@@ -11,37 +12,61 @@ const mockedFs = require('fs');
const util = require('../lib/util');
const initUtil = require('../lib/initutils');
const logger = require('../lib/logger');
+const mockedRename = require('../lib/rename/rename');
afterEach(() => {
jest.resetAllMocks();
});
describe('Test init utils methods', () => {
-
function createStat(isFile, isDirectory) {
var statObject = {};
- statObject.isFile = function () { return isFile; };
- statObject.isDirectory = function () { return isDirectory; };
+ statObject.isFile = function () {
+ return isFile;
+ };
+ statObject.isDirectory = function () {
+ return isDirectory;
+ };
return statObject;
}
test('should update manifest package id in manifest file', () => {
- let result = initUtil.updateManifest('com.magicleap.magicscript.hello-sample', 'com.test.sample', 'name', false);
+ let result = initUtil.updateManifest(
+ 'com.magicleap.magicscript.hello-sample',
+ 'com.test.sample',
+ 'name',
+ false
+ );
expect(result).toBe('com.test.sample');
});
test('should update manifest visible name in manifest file', () => {
- let result = initUtil.updateManifest('MagicScript Hello Sample', 'com.test.sample', 'test name', false);
+ let result = initUtil.updateManifest(
+ 'MagicScript Hello Sample',
+ 'com.test.sample',
+ 'test name',
+ false
+ );
expect(result).toBe('test name');
});
test('should update manifest to fullscreen if is immersive', () => {
- let result = initUtil.updateManifest('universe', 'com.test.sample', 'test name', true);
+ let result = initUtil.updateManifest(
+ 'universe',
+ 'com.test.sample',
+ 'test name',
+ true
+ );
expect(result).toBe('fullscreen');
});
test('should update manifest to Fullscreen if is immersive', () => {
- let result = initUtil.updateManifest('Universe', 'com.test.sample', 'test name', true);
+ let result = initUtil.updateManifest(
+ 'Universe',
+ 'com.test.sample',
+ 'test name',
+ true
+ );
expect(result).toBe('Fullscreen');
});
@@ -56,20 +81,37 @@ describe('Test init utils methods', () => {
});
test('should update components manifest privileges', () => {
- let result = initUtil.updateComponentManifest('');
- expect(result).toBe('\n ');
+ let result = initUtil.updateComponentManifest(
+ ''
+ );
+ expect(result).toBe(
+ '\n '
+ );
});
test('should update manifest privileges if is immersive', () => {
- let result = initUtil.updateManifest('', 'com.test.sample', 'test name', true);
- expect(result).toBe('\n ');
+ let result = initUtil.updateManifest(
+ '',
+ 'com.test.sample',
+ 'test name',
+ true
+ );
+ expect(result).toBe(
+ '\n '
+ );
});
test('should create directory if does not exist when copying vanilla files', () => {
mockedFs.existsSync.mockReturnValueOnce(false);
mockedFs.readdirSync.mockReturnValueOnce([]);
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', false, 'com.test.app', 'visibleName');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ false,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.existsSync).toHaveBeenCalledWith('dstPath');
expect(mockedFs.mkdirSync).toHaveBeenCalledWith('dstPath');
@@ -78,7 +120,7 @@ describe('Test init utils methods', () => {
test('should create directory if does not exist when copying components files', () => {
mockedFs.existsSync.mockReturnValueOnce(false);
mockedFs.readdirSync.mockReturnValueOnce([]);
-
+
initUtil.copyComponentFiles('srcPath', 'dstPath', false, '');
expect(mockedFs.existsSync).toHaveBeenCalledWith('dstPath');
@@ -88,122 +130,266 @@ describe('Test init utils methods', () => {
test('should copy components manifest file with updated privilege when is immersive', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['manifest.xml', 'file']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('').mockReturnValueOnce('fileContent');
-
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('')
+ .mockReturnValueOnce('fileContent');
+
initUtil.copyComponentFiles('srcPath', 'dstPath', true, '');
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
- expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/manifest.xml');
+ expect(mockedFs.statSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/manifest.xml'
+ );
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/file');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/manifest.xml', 'utf8');
+
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/manifest.xml',
+ 'utf8'
+ );
expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/file');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/manifest.xml', '\n ', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/file', 'fileContent');
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/manifest.xml',
+ '\n ',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/file',
+ 'fileContent'
+ );
});
test('should change main.js or main.tsx file from landscape to immersive when is immersive', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['main.js', 'main.tsx']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('landscape').mockReturnValueOnce('landscape');
-
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('landscape')
+ .mockReturnValueOnce('landscape');
+
initUtil.copyComponentFiles('srcPath', 'dstPath', true, '');
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/main.js');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/main.tsx');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/main.js', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/main.tsx', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/main.js', 'immersive', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/main.tsx', 'immersive', 'utf8');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/main.js',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/main.tsx',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/main.js',
+ 'immersive',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/main.tsx',
+ 'immersive',
+ 'utf8'
+ );
});
test('should change lumin icon portal package name when copying component files', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['portal.kmat', 'portal.fbx']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('com_magicscript_template').mockReturnValueOnce('com_magicscript_template');
-
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('com_magicscript_template')
+ .mockReturnValueOnce('com_magicscript_template');
+
initUtil.copyComponentFiles('srcPath', 'dstPath', true, 'org.test.package');
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/portal.kmat');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/portal.fbx');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/portal.kmat', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/portal.fbx', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/portal.kmat', 'org_test_package', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/portal.fbx', 'org_test_package', 'utf8');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/portal.kmat',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/portal.fbx',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/portal.kmat',
+ 'org_test_package',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/portal.fbx',
+ 'org_test_package',
+ 'utf8'
+ );
});
test('should change lumin icon model package name when copying component files', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['model.kmat', 'model.fbx']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('com_magicscript_template').mockReturnValueOnce('com_magicscript_template');
-
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('com_magicscript_template')
+ .mockReturnValueOnce('com_magicscript_template');
+
initUtil.copyComponentFiles('srcPath', 'dstPath', true, 'org.test.package');
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/model.kmat');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/model.fbx');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/model.kmat', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/model.fbx', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/model.kmat', 'org_test_package', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/model.fbx', 'org_test_package', 'utf8');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/model.kmat',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/model.fbx',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/model.kmat',
+ 'org_test_package',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/model.fbx',
+ 'org_test_package',
+ 'utf8'
+ );
});
test('should change lumin icon portal package name when copying vanilla files', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['portal.kmat', 'portal.fbx']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('com_magicleap_magicscript_hello-sample').mockReturnValueOnce('com_magicleap_magicscript_hello-sample');
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', false, 'com.test.app', 'visibleName');
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('com_magicleap_magicscript_hello-sample')
+ .mockReturnValueOnce('com_magicleap_magicscript_hello-sample');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ false,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/portal.kmat');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/portal.fbx');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/portal.kmat', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/portal.fbx', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/portal.kmat', 'com_test_app', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/portal.fbx', 'com_test_app', 'utf8');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/portal.kmat',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/portal.fbx',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/portal.kmat',
+ 'com_test_app',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/portal.fbx',
+ 'com_test_app',
+ 'utf8'
+ );
});
test('should change lumin icon model package name when copying vanilla files', () => {
mockedFs.existsSync.mockReturnValueOnce(true);
mockedFs.readdirSync.mockReturnValueOnce(['model.kmat', 'model.fbx']);
- mockedFs.statSync.mockReturnValueOnce(createStat(true, false)).mockReturnValueOnce(createStat(true, false));
- mockedFs.readFileSync.mockReturnValueOnce('com_magicleap_magicscript_hello-sample').mockReturnValueOnce('com_magicleap_magicscript_hello-sample');
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', false, 'com.test.app', 'visibleName');
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true, false))
+ .mockReturnValueOnce(createStat(true, false));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('com_magicleap_magicscript_hello-sample')
+ .mockReturnValueOnce('com_magicleap_magicscript_hello-sample');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ false,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/model.kmat');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/model.fbx');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/model.kmat', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/model.fbx', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/model.kmat', 'com_test_app', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/model.fbx', 'com_test_app', 'utf8');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/model.kmat',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/model.fbx',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/model.kmat',
+ 'com_test_app',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/model.fbx',
+ 'com_test_app',
+ 'utf8'
+ );
});
test('should run recursively when its directory when copying components files', () => {
mockedFs.existsSync.mockReturnValueOnce(true).mockReturnValueOnce(true);
- mockedFs.readdirSync.mockReturnValueOnce(['directory']).mockReturnValueOnce([]);
+ mockedFs.readdirSync
+ .mockReturnValueOnce(['directory'])
+ .mockReturnValueOnce([]);
mockedFs.statSync.mockReturnValueOnce(createStat(false, true));
-
+
initUtil.copyComponentFiles('srcPath', 'dstPath', true, '');
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
@@ -224,19 +410,45 @@ describe('Test init utils methods', () => {
.mockReturnValueOnce('srcPath/manifest.xml', 'utf8')
.mockReturnValueOnce('fileContent', 'utf8')
.mockReturnValueOnce('fileContent');
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', false, 'com.test.app', 'visibleName');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ false,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
- expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/manifest.xml');
+ expect(mockedFs.statSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/manifest.xml'
+ );
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/file');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/manifest.xml', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/file', 'utf8');
+
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/manifest.xml',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/file',
+ 'utf8'
+ );
expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(3, 'srcPath/file');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/manifest.xml', 'com.test.app', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/file', 'fileContent');
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/manifest.xml',
+ 'com.test.app',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/file',
+ 'fileContent'
+ );
});
test('should replace app content file when is immersive', () => {
@@ -249,27 +461,58 @@ describe('Test init utils methods', () => {
.mockReturnValueOnce('LandscapeApp')
.mockReturnValueOnce('fileContent')
.mockReturnValueOnce('fileContent');
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', true, 'com.test.app', 'visibleName');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ true,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(1, 'srcPath/app.js');
expect(mockedFs.statSync).toHaveBeenNthCalledWith(2, 'srcPath/file');
-
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(1, 'srcPath/app.js', 'utf8');
- expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(2, 'srcPath/file', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/app.js', 'ImmersiveApp', 'utf8');
- expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(2, 'dstPath/file', 'fileContent');
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'srcPath/app.js',
+ 'utf8'
+ );
+ expect(mockedFs.readFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'srcPath/file',
+ 'utf8'
+ );
+
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 1,
+ 'dstPath/app.js',
+ 'ImmersiveApp',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(
+ 2,
+ 'dstPath/file',
+ 'fileContent'
+ );
// expect(mockedFs.writeFileSync).toHaveBeenNthCalledWith(1, 'dstPath/file', 'fileContent', 'utf8');
});
test('should run recursively when its directory', () => {
mockedFs.existsSync.mockReturnValueOnce(true).mockReturnValueOnce(true);
- mockedFs.readdirSync.mockReturnValueOnce(['directory']).mockReturnValueOnce([]);
+ mockedFs.readdirSync
+ .mockReturnValueOnce(['directory'])
+ .mockReturnValueOnce([]);
mockedFs.statSync.mockReturnValueOnce(createStat(false, true));
-
- initUtil.copyVanillaFiles('srcPath', 'dstPath', true, 'com.test.app', 'visibleName');
+
+ initUtil.copyVanillaFiles(
+ 'srcPath',
+ 'dstPath',
+ true,
+ 'com.test.app',
+ 'visibleName'
+ );
expect(mockedFs.readdirSync).toHaveBeenCalledWith('srcPath');
expect(mockedFs.statSync).toHaveBeenCalledWith('srcPath/directory');
@@ -281,29 +524,35 @@ describe('Test init utils methods', () => {
test('should remove files recursively for android if android is not specified', () => {
let path = 'path';
mockedFs.existsSync.mockReturnValueOnce(true);
-
+
initUtil.preparePlatforms(path, ['IOS', 'LUMIN']);
-
- expect(mockedFs.existsSync).toHaveBeenCalledWith('path/reactnative/android');
- expect(util.removeFilesRecursively).toHaveBeenCalledWith('path/reactnative/android');
+
+ expect(mockedFs.existsSync).toHaveBeenCalledWith(
+ 'path/reactnative/android'
+ );
+ expect(util.removeFilesRecursively).toHaveBeenCalledWith(
+ 'path/reactnative/android'
+ );
});
test('should remove files recursively for ios if ios is not specified', () => {
let path = 'path';
mockedFs.existsSync.mockReturnValueOnce(true);
-
+
initUtil.preparePlatforms(path, ['ANDROID', 'LUMIN']);
-
+
expect(mockedFs.existsSync).toHaveBeenCalledWith('path/reactnative/ios');
- expect(util.removeFilesRecursively).toHaveBeenCalledWith('path/reactnative/ios');
+ expect(util.removeFilesRecursively).toHaveBeenCalledWith(
+ 'path/reactnative/ios'
+ );
});
test('should remove files recursively for lumin if lumin is not specified', () => {
let path = 'path';
mockedFs.existsSync.mockReturnValueOnce(true).mockReturnValueOnce(true);
-
+
initUtil.preparePlatforms(path, ['ANDROID', 'IOS']);
-
+
expect(mockedFs.existsSync).toHaveBeenCalledWith('path/lumin');
expect(util.removeFilesRecursively).toHaveBeenCalledWith('path/lumin');
});
@@ -311,21 +560,35 @@ describe('Test init utils methods', () => {
test('should create android local properties if android is specified', () => {
let path = 'path';
mockedFs.existsSync.mockReturnValueOnce(true);
-
+
initUtil.preparePlatforms(path, ['ANDROID', 'IOS']);
-
- expect(mockedFs.existsSync).toHaveBeenCalledWith('path/reactnative/android/local.properties');
+
+ expect(mockedFs.existsSync).toHaveBeenCalledWith(
+ 'path/reactnative/android/local.properties'
+ );
});
test('should remove whole reactnative directory is neither android nor ios is specified ', () => {
let path = 'path';
- mockedFs.existsSync.mockReturnValueOnce(true).mockReturnValueOnce(true).mockReturnValueOnce(true);
-
+ mockedFs.existsSync
+ .mockReturnValueOnce(true)
+ .mockReturnValueOnce(true)
+ .mockReturnValueOnce(true);
+
initUtil.preparePlatforms(path, ['LUMIN']);
-
- expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(1, 'path/reactnative/ios');
- expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(2, 'path/reactnative/android');
- expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(3, 'path/reactnative');
+
+ expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(
+ 1,
+ 'path/reactnative/ios'
+ );
+ expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(
+ 2,
+ 'path/reactnative/android'
+ );
+ expect(util.removeFilesRecursively).toHaveBeenNthCalledWith(
+ 3,
+ 'path/reactnative'
+ );
});
test('should return true if is components option is enabled', () => {
@@ -337,8 +600,12 @@ describe('Test init utils methods', () => {
test('should create symlink and return true if its successful', () => {
let result = initUtil.createSymlink('curDir', 'folderName');
-
- expect(mockedFs.symlinkSync).toHaveBeenCalledWith('../assets', 'curDir/folderName/reactnative/assets', 'dir');
+
+ expect(mockedFs.symlinkSync).toHaveBeenCalledWith(
+ '../assets',
+ 'curDir/folderName/reactnative/assets',
+ 'dir'
+ );
expect(result).toBe(true);
});
@@ -347,32 +614,50 @@ describe('Test init utils methods', () => {
throw new Error();
});
let result = initUtil.createSymlink('curDir', 'folderName');
-
- expect(mockedFs.symlinkSync).toHaveBeenCalledWith('../assets', 'curDir/folderName/reactnative/assets', 'dir');
+
+ expect(mockedFs.symlinkSync).toHaveBeenCalledWith(
+ '../assets',
+ 'curDir/folderName/reactnative/assets',
+ 'dir'
+ );
expect(result).toBe(false);
});
test('should unlink main.js and app.js for typescript preparation', () => {
initUtil.prepareTypescript('curDir', 'folder');
-
- expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(1, 'curDir/folder/src/main.js');
- expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(2, 'curDir/folder/src/app.js');
+
+ expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(
+ 1,
+ 'curDir/folder/src/main.js'
+ );
+ expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(
+ 2,
+ 'curDir/folder/src/app.js'
+ );
});
test('should unlink main.js from lumin directory and app.js from src directory for typescript components preparation', () => {
initUtil.prepareComponentsTypescript('curDir', 'folder');
-
- expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(1, 'curDir/folder/lumin/src/main.js');
- expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(2, 'curDir/folder/src/app.js');
+
+ expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(
+ 1,
+ 'curDir/folder/lumin/src/main.js'
+ );
+ expect(mockedFs.unlinkSync).toHaveBeenNthCalledWith(
+ 2,
+ 'curDir/folder/src/app.js'
+ );
});
test('create android local properties file if does not exist', () => {
mockedFs.existsSync.mockReturnValueOnce(false);
process.env.ANDROID_HOME = 'test';
- jest.spyOn(mockedFs, 'writeFileSync').mockImplementationOnce((path, content) => {
- expect(path.endsWith('android/local.properties')).toBeTruthy();
- expect(content).toBe('sdk.dir=test');
- });
+ jest
+ .spyOn(mockedFs, 'writeFileSync')
+ .mockImplementationOnce((path, content) => {
+ expect(path.endsWith('android/local.properties')).toBeTruthy();
+ expect(content).toBe('sdk.dir=test');
+ });
initUtil.createAndroidLocalProperties();
});
@@ -380,10 +665,12 @@ describe('Test init utils methods', () => {
mockedFs.existsSync.mockReturnValueOnce(false);
process.env.ANDROID_HOME = 'test';
Object.defineProperty(process, 'platform', { value: 'win32' });
- jest.spyOn(mockedFs, 'writeFileSync').mockImplementationOnce((path, content) => {
- expect(path.endsWith('android/local.properties')).toBeTruthy();
- expect(content).toBe('sdk.dir=test');
- });
+ jest
+ .spyOn(mockedFs, 'writeFileSync')
+ .mockImplementationOnce((path, content) => {
+ expect(path.endsWith('android/local.properties')).toBeTruthy();
+ expect(content).toBe('sdk.dir=test');
+ });
initUtil.createAndroidLocalProperties();
});
@@ -404,49 +691,84 @@ describe('Test init utils methods', () => {
test('should log error when visible name is not set', () => {
initUtil.renameComponentsFiles('folderName', 'packageName');
- expect(logger.red).toHaveBeenCalledWith('You have to specify the project name to rename the project!');
+ expect(logger.red).toHaveBeenCalledWith(
+ 'You have to specify the project name to rename the project!'
+ );
});
test('should change visible name and package name in manifest if it exists', () => {
process.cwd = jest.fn().mockReturnValue('cwd');
mockedFs.existsSync.mockReturnValueOnce(true);
- mockedFs.readFileSync.mockReturnValueOnce('ml:visible_name="example" \n ml:package="com.example"');
-
- initUtil.renameComponentsFiles('folderName', 'packageName', 'visibleName', ['LUMIN']);
-
- expect(logger.green).toHaveBeenNthCalledWith(1, 'new project name: visibleName');
- expect(logger.green).toHaveBeenNthCalledWith(2, 'Lumin manifest file has been updated successfully');
- expect(mockedFs.writeFileSync).toHaveBeenCalledWith('cwd/folderName/lumin/manifest.xml', 'ml:visible_name="visibleName" \n ml:package="packageName"', 'utf8');
+ mockedFs.readFileSync.mockReturnValueOnce(
+ 'ml:visible_name="example" \n ml:package="com.example"'
+ );
+
+ initUtil.renameComponentsFiles('folderName', 'packageName', 'visibleName', [
+ 'LUMIN'
+ ]);
+
+ expect(logger.green).toHaveBeenNthCalledWith(
+ 1,
+ 'new project name: visibleName'
+ );
+ expect(logger.green).toHaveBeenNthCalledWith(
+ 2,
+ 'Lumin manifest file has been updated successfully'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenCalledWith(
+ 'cwd/folderName/lumin/manifest.xml',
+ 'ml:visible_name="visibleName" \n ml:package="packageName"',
+ 'utf8'
+ );
});
test('should change only visible name in manifest if package name is null', () => {
process.cwd = jest.fn().mockReturnValue('cwd');
mockedFs.existsSync.mockReturnValueOnce(true);
- mockedFs.readFileSync.mockReturnValueOnce('ml:visible_name="example" \n ml:package="com.example"');
-
- initUtil.renameComponentsFiles('folderName', null, 'visibleName', ['LUMIN']);
-
- expect(logger.green).toHaveBeenNthCalledWith(1, 'new project name: visibleName');
- expect(logger.green).toHaveBeenNthCalledWith(2, 'Lumin manifest file has been updated successfully');
- expect(mockedFs.writeFileSync).toHaveBeenCalledWith('cwd/folderName/lumin/manifest.xml', 'ml:visible_name="visibleName" \n ml:package="com.example"', 'utf8');
+ mockedFs.readFileSync.mockReturnValueOnce(
+ 'ml:visible_name="example" \n ml:package="com.example"'
+ );
+
+ initUtil.renameComponentsFiles('folderName', null, 'visibleName', [
+ 'LUMIN'
+ ]);
+
+ expect(logger.green).toHaveBeenNthCalledWith(
+ 1,
+ 'new project name: visibleName'
+ );
+ expect(logger.green).toHaveBeenNthCalledWith(
+ 2,
+ 'Lumin manifest file has been updated successfully'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenCalledWith(
+ 'cwd/folderName/lumin/manifest.xml',
+ 'ml:visible_name="visibleName" \n ml:package="com.example"',
+ 'utf8'
+ );
});
test('should rename react native files', () => {
process.cwd = jest.fn().mockReturnValue('cwd');
+ process.chdir = jest.fn();
mockedFs.existsSync.mockReturnValueOnce(false).mockReturnValueOnce(true);
- child_process.spawnSync.mockImplementationOnce((path, args, settings) => {
- let expectedSettings = {"cwd": "cwd/folderName/reactnative", "stdio": "inherit"}
- expect(args).toStrictEqual(["visibleName", "-b", "packageName"]);
- expect(settings).toEqual(expect.objectContaining(expectedSettings));
- return true;
- });
- initUtil.renameComponentsFiles('folderName', 'packageName', 'visibleName', ['ANDROID']);
-
- expect(mockedFs.existsSync).toHaveBeenNthCalledWith(1, 'cwd/folderName/lumin/manifest.xml');
- expect(mockedFs.existsSync).toHaveBeenNthCalledWith(2, 'cwd/folderName/reactnative');
- expect(logger.green).toHaveBeenCalledWith('Prepare project name and package in the project...');
- expect(child_process.spawnSync).toHaveBeenCalled();
+ initUtil.renameComponentsFiles('folderName', 'packageName', 'visibleName', [
+ 'ANDROID'
+ ]);
+
+ expect(mockedFs.existsSync).toHaveBeenNthCalledWith(
+ 1,
+ 'cwd/folderName/lumin/manifest.xml'
+ );
+ expect(mockedFs.existsSync).toHaveBeenNthCalledWith(
+ 2,
+ 'cwd/folderName/reactnative'
+ );
+ expect(logger.green).toHaveBeenCalledWith(
+ 'Prepare project name and package in the project...'
+ );
+ expect(mockedRename.rename).toHaveBeenCalled();
});
test('should not rename files if package or folderName does not exist', () => {
@@ -454,12 +776,14 @@ describe('Test init utils methods', () => {
initUtil.renameComponentsFiles(null, null, 'visibleName', ['ANDROID']);
- expect(logger.yellow).toHaveBeenCalledWith('Renaming of the project could not be processed because the path does not exist!');
+ expect(logger.yellow).toHaveBeenCalledWith(
+ 'Renaming of the project could not be processed because the path does not exist!'
+ );
});
test('should create repository when git is installed/configured', () => {
- const pathToAppFolder = "pathToAppFolder";
- const logSuccess = "Correct log line";
+ const pathToAppFolder = 'pathToAppFolder';
+ const logSuccess = 'Correct log line';
child_process.execSync.mockImplementationOnce((command) => {
const expectedCommand = `cd ${pathToAppFolder} && git init && git add . && git commit -am"Initial commit."`;
expect(command).toStrictEqual(expectedCommand);
@@ -470,8 +794,8 @@ describe('Test init utils methods', () => {
});
test('should not create repository when git is not installed/configured', () => {
- const pathToAppFolder = "pathToAppFolder";
- const logFailure = "Correct log line";
+ const pathToAppFolder = 'pathToAppFolder';
+ const logFailure = 'Correct log line';
child_process.execSync.mockImplementationOnce((command) => {
const expectedCommand = `cd ${pathToAppFolder} && git init && git add . && git commit -am"Initial commit."`;
expect(command).toStrictEqual(expectedCommand);
@@ -481,4 +805,4 @@ describe('Test init utils methods', () => {
initUtil.createGitRepository(pathToAppFolder);
expect(logger.red).toHaveBeenCalledWith(logFailure);
});
-});
\ No newline at end of file
+});
diff --git a/__tests__/renamestepstest.js b/__tests__/renamestepstest.js
new file mode 100644
index 0000000..58ad2f2
--- /dev/null
+++ b/__tests__/renamestepstest.js
@@ -0,0 +1,157 @@
+jest.mock('../lib/rename/renameutils.js');
+jest.mock('../lib/rename/config/bundleIdentifiers');
+jest.mock('path');
+jest.mock('fs');
+jest.mock('../lib/logger.js');
+
+let {
+ copyFiles,
+ copyFileOrDir,
+ deleteFiles,
+ replaceContent
+} = require('../lib/rename/renameutils.js');
+let { bundleIdentifiers } = require('../lib/rename/config/bundleIdentifiers');
+let mockedPath = require('path');
+let mockedFs = require('fs');
+let mockedLogger = require('../lib/logger');
+const renameSteps = require('../lib/rename/renamesteps');
+
+afterEach(() => {
+ jest.resetAllMocks();
+});
+
+describe('Test init utils methods', () => {
+ test('should resolve folders and files', () => {
+ const listOfFoldersAndFiles = ['file1'];
+ const noSpaceCurrentAppName = 'appname';
+ const noSpaceNewName = 'newname';
+ const dirname = 'dirname';
+ mockedPath.join.mockReturnValue('path');
+
+ const params = {
+ listOfFoldersAndFiles,
+ noSpaceCurrentAppName,
+ noSpaceNewName,
+ dirname
+ };
+
+ renameSteps.resolveFoldersAndFiles(params);
+
+ expect(copyFileOrDir).toHaveBeenCalledWith('path', 'path');
+ expect(deleteFiles).toHaveBeenCalledWith('path');
+ });
+
+ test('should resolve files to modify content', () => {
+ const regex = 'regex';
+ const replacement = 'replacement';
+ const paths = ['path'];
+ const listOfFilesToModifyContent = [{ regex, replacement, paths }];
+ const bundleID = 'com.bundle.id';
+ const dirname = 'dirname';
+ mockedPath.join.mockReturnValue('path');
+ mockedFs.existsSync.mockReturnValueOnce(true);
+
+ const params = {
+ listOfFilesToModifyContent,
+ dirname,
+ bundleID
+ };
+
+ const result = renameSteps.resolveFilesToModifyContent(params);
+
+ expect(replaceContent).toHaveBeenCalledWith(regex, replacement, ['path']);
+ expect(result).toBe(bundleID);
+ });
+
+ test('should resolve java files', () => {
+ const currentAppName = 'currName';
+ const newName = 'newName';
+ const newPackageName = 'com.new.name';
+ const bundleID = 'com.new.name';
+ const lowcaseNoSpaceNewAppName = 'newname';
+ const templateBundleId = 'com.magicscript.template';
+ let newJavaPath = 'com.new.name';
+ const dirname = 'dirname';
+ const params = {
+ currentAppName,
+ newName,
+ newPackageName,
+ bundleID,
+ lowcaseNoSpaceNewAppName,
+ templateBundleId,
+ newJavaPath,
+ dirname
+ };
+ newJavaPath = '/android/app/src/main/java/com/new/name';
+ const newBundleID = newPackageName;
+
+ mockedPath.join.mockReturnValue('path');
+ mockedFs.existsSync.mockReturnValueOnce(false);
+
+ const result = renameSteps.resolveJavaFiles(params);
+
+ expect(mockedFs.mkdirSync).toHaveBeenCalledWith('path', {
+ recursive: true
+ });
+ expect(copyFiles).toHaveBeenCalledWith('path', 'path');
+ expect(deleteFiles).toHaveBeenCalledWith('path');
+ const expectedResult = {
+ currentAppName,
+ newName,
+ templateBundleId,
+ dirname,
+ newBundleID,
+ newJavaPath
+ };
+ expect(result).toEqual(expectedResult);
+ });
+
+ test('should resolve bundle identifiers', () => {
+ const currentAppName = 'currName';
+ const newName = 'newName';
+ const templateBundleId = 'com.magicscript.template';
+ const dirname = 'dirname';
+ const newBundleID = 'com.new.name';
+ const newJavaPath = '/android/app/src/main/java/com/new/name';
+ const params = {
+ currentAppName,
+ newName,
+ templateBundleId,
+ dirname,
+ newBundleID,
+ newJavaPath
+ };
+
+ bundleIdentifiers.mockReturnValueOnce([
+ {
+ paths: ['path'],
+ regex: 'regex',
+ replacement: 'replacement'
+ }
+ ]);
+ mockedPath.join.mockReturnValue('path');
+ mockedFs.existsSync.mockReturnValueOnce(true);
+
+ renameSteps.resolveBundleIdentifiers(params);
+
+ expect(bundleIdentifiers).toHaveBeenCalledWith(
+ currentAppName,
+ newName,
+ templateBundleId,
+ newBundleID,
+ newJavaPath
+ );
+ expect(replaceContent).toHaveBeenCalledWith('regex', 'replacement', [
+ 'path'
+ ]);
+ });
+
+ test('should delete previous bundle directory', () => {
+ renameSteps.deletePreviousBundleDirectory('com.previous.dir');
+
+ expect(deleteFiles).toHaveBeenCalledWith('com/previous/dir');
+ expect(mockedLogger.green).toHaveBeenCalledWith(
+ 'Done removing previous bundle directory.'
+ );
+ });
+});
diff --git a/__tests__/renametest.js b/__tests__/renametest.js
new file mode 100644
index 0000000..aec8955
--- /dev/null
+++ b/__tests__/renametest.js
@@ -0,0 +1,86 @@
+jest.mock('../lib/rename/renamesteps');
+jest.mock('../lib/rename/config/filesToModifyContent');
+jest.mock('../lib/rename/config/foldersAndFiles');
+jest.mock('fs');
+jest.mock('path');
+jest.mock('../lib/logger');
+
+const renameSteps = require('../lib/rename/renamesteps');
+const configFiles = require('../lib/rename/config/filesToModifyContent');
+const foldersAndFiles = require('../lib/rename/config/foldersAndFiles');
+const mockedFs = require('fs');
+const mockedPath = require('path');
+const mockedLogger = require('../lib/logger');
+const rename = require('../lib/rename/rename');
+
+afterEach(() => {
+ jest.resetAllMocks();
+});
+
+describe('Test init utils methods', () => {
+ test('should rename react native files', () => {
+ const dirname = 'dirname';
+ const newName = 'newName';
+ const noSpaceNewName = newName;
+ const newPackageName = 'com.new.package';
+ const listOfFoldersAndFiles = ['folderAndFile'];
+ const noSpaceCurrentAppName = 'Template';
+ const listOfFilesToModifyContent = ['configFile'];
+ const bundleID = newPackageName;
+ const parameters = {};
+ configFiles.filesToModifyContent.mockReturnValueOnce(
+ listOfFilesToModifyContent
+ );
+ foldersAndFiles.foldersAndFiles.mockReturnValueOnce(listOfFoldersAndFiles);
+ renameSteps.resolveJavaFiles.mockReturnValueOnce(parameters);
+ mockedFs.existsSync.mockReturnValueOnce(true);
+
+ rename.rename(dirname, newName, newPackageName);
+
+ expect(renameSteps.resolveFoldersAndFiles).toHaveBeenCalledWith({
+ listOfFoldersAndFiles,
+ noSpaceCurrentAppName,
+ noSpaceNewName,
+ dirname
+ });
+ expect(renameSteps.resolveFilesToModifyContent).toHaveBeenCalledWith({
+ listOfFilesToModifyContent,
+ dirname,
+ bundleID
+ });
+ expect(renameSteps.resolveBundleIdentifiers).toHaveBeenCalledWith(
+ parameters
+ );
+ expect(renameSteps.deletePreviousBundleDirectory).toHaveBeenCalledWith(
+ 'com.magicscript.template'
+ );
+ expect(mockedLogger.green).toHaveBeenCalledWith(
+ 'APP SUCCESSFULLY RENAMED TO "newName"! 🎉 🎉 🎉'
+ );
+ expect(mockedPath.join).toHaveBeenCalledWith(dirname, 'ios', 'Podfile');
+ expect(mockedLogger.yellow).toHaveBeenCalledWith(
+ 'Podfile has been modified, please run "pod install" inside ios directory.'
+ );
+ expect(mockedLogger.yellow).toHaveBeenCalledWith(
+ 'Please make sure to run "watchman watch-del-all" and "npm start --reset-cache" before running the app.'
+ );
+ });
+
+ test('should not rename if new name is Template', () => {
+ let newName = 'Template';
+ const newPackageName = 'com.new.package';
+ const dirname = 'dirname';
+
+ rename.rename(dirname, newName, newPackageName);
+ expect(mockedLogger.red).toHaveBeenCalledWith(
+ 'Please try a different name.'
+ );
+
+ newName = 'template';
+
+ rename.rename(dirname, newName, newPackageName);
+ expect(mockedLogger.red).toHaveBeenCalledWith(
+ 'Please try a different name.'
+ );
+ });
+});
diff --git a/__tests__/renameutilstest.js b/__tests__/renameutilstest.js
new file mode 100644
index 0000000..726549d
--- /dev/null
+++ b/__tests__/renameutilstest.js
@@ -0,0 +1,179 @@
+jest.mock('fs');
+jest.mock('../lib/logger');
+jest.mock('node-replace');
+jest.mock('path');
+
+const mockedFs = require('fs');
+const renameUtils = require('../lib/rename/renameutils');
+const logger = require('../lib/logger');
+const mockedReplace = require('node-replace');
+
+afterEach(() => {
+ jest.resetAllMocks();
+});
+
+describe('Test init utils methods', () => {
+ function createStat(isFile) {
+ var statObject = {};
+ statObject.isFile = function () {
+ return isFile;
+ };
+ statObject.isDirectory = function () {
+ return !isFile;
+ };
+ return statObject;
+ }
+
+ test('should copy files with utf8', () => {
+ mockedFs.existsSync.mockReturnValueOnce(false);
+ mockedFs.readdirSync.mockReturnValueOnce(['manifest.xml', 'file']);
+ mockedFs.statSync
+ .mockReturnValueOnce(createStat(true))
+ .mockReturnValueOnce(createStat(true));
+ mockedFs.readFileSync
+ .mockReturnValueOnce('content')
+ .mockReturnValueOnce('fileContent');
+
+ renameUtils.copyFiles('srcPath', 'destPath');
+
+ expect(mockedFs.mkdirSync).toHaveBeenCalledWith('destPath');
+ expect(mockedFs.writeFileSync).toHaveBeenCalledWith(
+ 'destPath/manifest.xml',
+ 'content',
+ 'utf8'
+ );
+ expect(mockedFs.writeFileSync).toHaveBeenCalledWith(
+ 'destPath/file',
+ 'fileContent',
+ 'utf8'
+ );
+ });
+
+ test('should recursively call copy files when is directory', () => {
+ mockedFs.existsSync.mockReturnValueOnce(false).mockReturnValueOnce(false);
+ mockedFs.readdirSync
+ .mockReturnValueOnce(['directory'])
+ .mockReturnValueOnce([]);
+ mockedFs.statSync.mockReturnValueOnce(createStat(false));
+ mockedFs.readFileSync.mockReturnValueOnce('');
+
+ renameUtils.copyFiles('srcPath', 'destPath');
+
+ expect(mockedFs.mkdirSync).toHaveBeenCalledWith('destPath');
+ expect(mockedFs.mkdirSync).toHaveBeenCalledWith('destPath/directory');
+ });
+
+ test('should write to file when copyFileOrDir operates on file', () => {
+ mockedFs.statSync.mockReturnValueOnce(createStat(true));
+ mockedFs.readFileSync.mockReturnValueOnce('content');
+
+ renameUtils.copyFileOrDir('file', 'destPath');
+
+ expect(mockedFs.readFileSync).toHaveBeenCalledWith('file', 'utf8');
+ expect(mockedFs.writeFileSync).toHaveBeenCalledWith(
+ 'destPath',
+ 'content',
+ 'utf8'
+ );
+ });
+
+ test('should call copyFiles when copyFileOrDir operates on directory', () => {
+ mockedFs.statSync.mockReturnValueOnce(createStat(false));
+ mockedFs.readFileSync.mockReturnValueOnce('content');
+ renameUtils.copyFiles = jest.fn();
+
+ renameUtils.copyFileOrDir('directory', 'destPath');
+
+ expect(renameUtils.copyFiles).toHaveBeenCalled();
+ });
+
+ it('should not delete directory if bundle was not changed', () => {
+ const oldBundleNameDir = 'oldBundleName';
+ const shouldDelete = false;
+ const payload = {
+ oldBundleNameDir,
+ shouldDelete
+ };
+
+ renameUtils.deletePreviousBundleDirectory(payload);
+
+ expect(mockedFs.unlinkSync).not.toHaveBeenCalled();
+ expect(logger.yellow).toHaveBeenCalledWith(
+ 'Bundle directory was not changed. Keeping...'
+ );
+ });
+
+ it('should delete directory if bundle was changed', () => {
+ const oldBundleNameDir = 'oldBundleName';
+ const shouldDelete = true;
+ const payload = {
+ oldBundleNameDir,
+ shouldDelete
+ };
+
+ renameUtils.deletePreviousBundleDirectory(payload);
+
+ expect(mockedFs.unlinkSync).toHaveBeenCalledWith(oldBundleNameDir);
+ expect(logger.green).toHaveBeenCalledWith(
+ 'Done removing previous bundle directory.'
+ );
+ });
+
+ it('should replace content', () => {
+ const regex = 'regex';
+ const replacement = 'replacement';
+ const paths = ['path1', 'path2'];
+
+ renameUtils.replaceContent(regex, replacement, paths);
+
+ expect(mockedReplace).toHaveBeenCalled();
+ });
+
+ it('should unlink if is file', () => {
+ const path = 'path';
+ mockedFs.existsSync.mockReturnValueOnce(true);
+ mockedFs.lstatSync.mockReturnValueOnce(createStat(true));
+
+ renameUtils.deleteFiles(path);
+
+ expect(mockedFs.existsSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.lstatSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.unlinkSync).toHaveBeenCalledWith(path);
+ });
+
+ it('should unlink new path if is directory', () => {
+ const path = 'path';
+ mockedFs.existsSync.mockReturnValueOnce(true);
+ mockedFs.lstatSync
+ .mockReturnValueOnce(createStat(false))
+ .mockReturnValueOnce(createStat(true));
+ mockedFs.readdirSync.mockReturnValueOnce(['file1']);
+
+ renameUtils.deleteFiles(path);
+
+ expect(mockedFs.existsSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.lstatSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.lstatSync).toHaveBeenCalledWith('path/file1');
+ expect(mockedFs.readdirSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.unlinkSync).toHaveBeenCalledWith('path/file1');
+ expect(mockedFs.rmdirSync).toHaveBeenCalledWith(path);
+ });
+
+ it('should recurrent new path if is directory', () => {
+ const path = 'path';
+ mockedFs.existsSync.mockReturnValueOnce(true).mockImplementationOnce(false);
+ mockedFs.lstatSync
+ .mockReturnValueOnce(createStat(false))
+ .mockReturnValueOnce(createStat(false));
+ mockedFs.readdirSync.mockReturnValueOnce(['innerPath']);
+
+ renameUtils.deleteFiles(path);
+
+ expect(mockedFs.existsSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.lstatSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.lstatSync).toHaveBeenCalledWith('path/innerPath');
+ expect(mockedFs.readdirSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.rmdirSync).toHaveBeenCalledWith(path);
+ expect(mockedFs.existsSync).toHaveBeenCalledWith('path/innerPath');
+ });
+});
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..135cd68
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,13 @@
+// babel.config.js
+module.exports = {
+ presets: [
+ [
+ '@babel/preset-env',
+ {
+ targets: {
+ node: 'current'
+ }
+ }
+ ]
+ ]
+};
diff --git a/commands/build.js b/commands/build.js
index 466f3f8..9b23f44 100644
--- a/commands/build.js
+++ b/commands/build.js
@@ -1,33 +1,235 @@
// Copyright (c) 2019 Magic Leap, Inc. All Rights Reserved
// Distributed under Apache 2.0 License. See LICENSE file in the project root for full license information.
-const buildUtil = require('../lib/buildutils');
-const logger = require('../lib/logger');
-const multiplatformIndexContent = "#!/system/bin/script/mxs\nimport './lumin/src/main.js';\n";
-const vanillaIndexContent = "#!/system/bin/script/mxs\nimport './src/main.js';\n";
+const { exec, spawn } = require('child_process');
+const fs = require('fs');
+const util = require('../lib/util');
+
+function npmInstallIfNeeded(path, callback) {
+ if (fs.existsSync(`${path}/node_modules`)) {
+ callback();
+ } else {
+ console.log('npm install: installing');
+
+ const proc = spawn('npm', ['install'], {
+ cwd: `${path}`,
+ stdio: 'inherit',
+ shell: process.platform === 'win32'
+ });
+ proc.on('message', function (message) {
+ console.log(message);
+ });
+ proc.on('error', function (err) {
+ throw err;
+ });
+ proc.on('exit', function (code, signal) {
+ if (signal !== null) {
+ throw Error(`npm install failed with signal: ${signal}`);
+ }
+ if (code !== 0) {
+ throw Error(`npm install failed with code: ${code}`);
+ }
+ console.log('npm install: success');
+ callback();
+ });
+ }
+}
+
+function buildLuminComponents(argv) {
+ let path = process.cwd();
+ if (fs.existsSync(`${path}/lumin`)) {
+ process.chdir('lumin/');
+ buildLumin(
+ argv,
+ "#!/system/bin/script/mxs\nimport './lumin/src/main.js';\n"
+ );
+ }
+}
+
+function buildLumin(argv, indexContent) {
+ let packagePath = 'app.package';
+ try {
+ for (let name of fs.readdirSync('.')) {
+ let m = name.match(/([^/]+)\.package$/);
+ if (!m) continue;
+ let [, base] = m;
+ packagePath = `${base}.package`;
+ }
+ } catch (err) {
+ throw err;
+ }
+
+ var device = argv.debug !== false ? 'device' : 'release_device';
+ var buildCommand = `mabu -t ${argv.host ? 'host' : device} ${packagePath}`;
+
+ // create bin/index.js if needed
+ try {
+ fs.mkdirSync('bin');
+ } catch (error) {
+ if (error.code !== 'EEXIST') {
+ throw error;
+ }
+ }
+ fs.writeFileSync('bin/index.js', indexContent, { mode: 0o755 });
+
+ exec('npm run build', (err, stdout, stderr) => {
+ if (err) {
+ process.stdout.write(stdout);
+ process.stderr.write(stderr);
+ throw err;
+ }
+ util.createDigest(argv.debug);
+ if (argv.host && fs.existsSync('app.package')) {
+ let packageFile = fs.openSync('app.package', 'a+');
+ let buffer = fs.readFileSync(packageFile, 'utf8');
+ if (buffer && !buffer.includes('USES = mxs_lumin_runtime')) {
+ fs.appendFileSync(packageFile, '\nUSES = mxs_lumin_runtime\n');
+ }
+ }
+ exec(buildCommand, (err, stdout, stderr) => {
+ if (err) {
+ process.stdout.write(stdout);
+ process.stderr.write(stderr);
+ throw err;
+ }
+
+ let mpkFile;
+ let outLines = stdout.split('\n');
+
+ let theLine = outLines.find((line) => line.includes('mpk'));
+ if (theLine !== undefined) {
+ mpkFile = theLine.substring(
+ theLine.indexOf("'") + 1,
+ theLine.lastIndexOf("'")
+ );
+ console.log('built package: ' + mpkFile);
+ } else {
+ theLine = outLines.find((line) => line.includes('output in'));
+ console.log(
+ theLine.substring(theLine.indexOf("'"), theLine.lastIndexOf("'") + 1)
+ );
+ }
+
+ if (argv.install) {
+ argv.path = mpkFile;
+ util.installPackage(argv);
+ }
+ });
+ });
+}
module.exports = (argv) => {
- if (buildUtil.isTargetSpecified(argv)) {
- buildUtil.npmInstallIfNeeded(`${process.cwd()}`, () => {
- if (argv.target === 'lumin') {
- if (buildUtil.isMultiplatformStructure()) {
- buildUtil.npmInstallIfNeeded(`${process.cwd()}/lumin`, () => {
- buildUtil.navigateToLuminDirectory();
- buildUtil.buildLumin(argv, multiplatformIndexContent);
- });
- } else {
- buildUtil.buildLumin(argv, vanillaIndexContent);
- }
- } else if (buildUtil.isReactNativeTarget(argv)) {
- buildUtil.npmInstallIfNeeded(`${process.cwd()}/reactnative`, () => {
- if (argv.target === 'android') {
- buildUtil.buildAndroid(argv);
- } else if (argv.target === 'ios') {
- buildUtil.buildiOS(argv);
- }
+ npmInstallIfNeeded(`${process.cwd()}`, () => {
+ if (argv.target === 'lumin') {
+ if (isMultiplatformStructure()) {
+ npmInstallIfNeeded(`${process.cwd()}/lumin`, () => {
+ buildLuminComponents(argv);
});
}
+ } else if (argv.target === 'android') {
+ npmInstallIfNeeded(`${process.cwd()}/reactnative`, () => {
+ buildAndroid(argv);
+ });
+ } else if (argv.target === 'ios') {
+ npmInstallIfNeeded(`${process.cwd()}/reactnative`, () => {
+ buildiOS(argv);
+ });
+ } else {
+ console.error('The target must be either lumin, ios or android!');
+ }
+ });
+};
+
+function isMultiplatformStructure() {
+ let path = process.cwd();
+ return fs.existsSync(`${path}/lumin/rollup.config.js`);
+}
+
+function buildAndroid() {
+ var path = process.cwd();
+ if (fs.existsSync(`${path}/reactnative/android`)) {
+ fs.chmodSync(`${path}/reactnative/android/gradlew`, '755');
+ var runProcess = spawn('npx', ['react-native', 'run-android'], {
+ stdio: 'inherit',
+ cwd: `${path}/reactnative`,
+ shell: process.platform === 'win32'
+ });
+ runProcess.on('message', (message) => {
+ console.log(message);
+ });
+ runProcess.on('error', function (err) {
+ throw err;
+ });
+ runProcess.on('exit', function (code, signal) {
+ if (signal !== null) {
+ throw Error(`react-native run-android failed with signal: ${signal}`);
+ }
+ if (code !== 0) {
+ throw Error(`react-native run-android failed with code: ${code}`);
+ }
+ });
+ } else {
+ console.error(
+ "Cannot build the app for Android because the project wasn't set up to support this platform!"
+ );
+ }
+}
+
+function buildiOS() {
+ var path = process.cwd();
+ if (fs.existsSync(`${path}/reactnative/ios`)) {
+ installPods(path, () => {
+ runiOS();
});
} else {
logger.red('The target must be either lumin, ios or android!');
}
-};
+}
+
+function installPods(path, onInstallFinish) {
+ console.log('start installing pods');
+
+ var podProcess = spawn('pod', ['install'], {
+ stdio: 'inherit',
+ cwd: `${path}/reactnative/ios`,
+ shell: process.platform === 'win32'
+ });
+ podProcess.on('message', function (message) {
+ console.log(message);
+ });
+ podProcess.on('error', function (err) {
+ throw err;
+ });
+ podProcess.on('exit', function (code, signal) {
+ if (signal) {
+ throw Error(`pod install failed with signal: ${signal}`);
+ }
+ if (code !== 0) {
+ throw Error(`pod install failed with code: ${code}`);
+ }
+ console.log('pod install: success');
+ onInstallFinish();
+ });
+}
+
+function runiOS() {
+ console.log('run ios app');
+ var runProcess = spawn('npx', ['react-native', 'run-ios'], {
+ stdio: 'inherit',
+ cwd: `${process.cwd()}/reactnative`,
+ shell: process.platform === 'win32'
+ });
+ runProcess.on('message', (message) => {
+ console.log(message);
+ });
+ runProcess.on('error', function (err) {
+ throw err;
+ });
+ runProcess.on('exit', function (code, signal) {
+ if (signal !== null) {
+ throw Error(`react-native run-ios failed with signal: ${signal}`);
+ }
+ if (code !== 0) {
+ throw Error(`react-native run-ios failed with code: ${code}`);
+ }
+ });
+}
diff --git a/commands/init.js b/commands/init.js
index b4d24d9..78314cf 100644
--- a/commands/init.js
+++ b/commands/init.js
@@ -97,45 +97,83 @@ module.exports = (argv) => {
let destDirectory;
immersive = argv.appType === 'Immersive' || argv.immersive;
isComponents = argv.isComponents;
- if ((typeof isComponents !== 'undefined') && isComponents === false) {
- logger.green(`Start creating Vanilla Magic Script project for ${appType} app type`);
+ if (typeof isComponents !== 'undefined' && isComponents === false) {
+ logger.green(
+ `Start creating Vanilla Magic Script project for ${appType} app type`
+ );
destDirectory = path.join(currentDirectory, folderName);
- initUtil.copyVanillaFiles(templatePath, destDirectory, immersive, packageName, visibleName);
+ initUtil.copyVanillaFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName,
+ visibleName
+ );
if (argv.typeScript) {
initUtil.prepareTypescript(currentDirectory, folderName);
// Copy typescript template overlay over existing template files
templatePath = path.join(__dirname, '../template_overlay_typescript');
- initUtil.copyVanillaFiles(templatePath, destDirectory, immersive, packageName, visibleName);
+ initUtil.copyVanillaFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName,
+ visibleName
+ );
}
- logger.green(`Vanilla Magic Script project successfully created for ${appType} app type`);
+ logger.green(
+ `Vanilla Magic Script project successfully created for ${appType} app type`
+ );
resetValues();
return;
}
- if ((typeof isComponents !== 'undefined') && isComponents === true) {
+ if (typeof isComponents !== 'undefined' && isComponents === true) {
destDirectory = path.join(currentDirectory, folderName);
setTarget(argv.target);
- logger.green(`Start creating project for Components type, target: ${target}`);
- templatePath = path.join(__dirname, '../template_multiplatform_components');
- initUtil.copyComponentFiles(templatePath, destDirectory, immersive, packageName);
- if (argv.typeScript) {
- initUtil.prepareComponentsTypescript(currentDirectory, folderName);
- // Copy typescript template overlay over existing template files
- templatePath = path.join(__dirname, '../template_overlay_typescript_components');
- initUtil.copyComponentFiles(templatePath, destDirectory, immersive, packageName);
- }
- initUtil.renameComponentsFiles(folderName, packageName, visibleName, target);
- let symlinkSuccess = initUtil.createSymlink(currentDirectory, folderName);
- if (!symlinkSuccess) {
- logger.yellow('Couldn\'t create symlink for resources directory. Please do it manually if you want to use resources in your project. For more information check: https:///magicscript.org/');
- }
- initUtil.preparePlatforms(destDirectory, target);
- logger.green(`Project successfully created for platforms: ${target}`);
- resetValues();
- return;
+ logger.green(
+ `Start creating project for Components type, target: ${target}`
+ );
+ templatePath = path.join(__dirname, '../template_multiplatform_components');
+ initUtil.copyComponentFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName
+ );
+ if (argv.typeScript) {
+ initUtil.prepareComponentsTypescript(currentDirectory, folderName);
+ // Copy typescript template overlay over existing template files
+ templatePath = path.join(
+ __dirname,
+ '../template_overlay_typescript_components'
+ );
+ initUtil.copyComponentFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName
+ );
+ }
+ initUtil.renameComponentsFiles(
+ folderName,
+ packageName,
+ visibleName,
+ target
+ );
+ let symlinkSuccess = initUtil.createSymlink(currentDirectory, folderName);
+ if (!symlinkSuccess) {
+ logger.yellow(
+ "Couldn't create symlink for resources directory. Please do it manually if you want to use resources in your project. For more information check: https:///magicscript.org/"
+ );
+ }
+ initUtil.preparePlatforms(destDirectory, target);
+ logger.green(`Project successfully created for platforms: ${target}`);
+ resetValues();
+ return;
}
let answerPromise = askQuestions();
answerPromise
- .then(answers => {
+ .then((answers) => {
packageName = answers['APPID'];
folderName = answers['FOLDERNAME'];
visibleName = answers['APPNAME'];
@@ -148,37 +186,78 @@ module.exports = (argv) => {
destDirectory = path.join(currentDirectory, folderName);
if (isComponents) {
setTarget(target);
- logger.green(`Start creating project for Components type, target: ${target}`);
- templatePath = path.join(__dirname, '../template_multiplatform_components');
- initUtil.copyComponentFiles(templatePath, destDirectory, immersive, packageName);
+ logger.green(
+ `Start creating project for Components type, target: ${target}`
+ );
+ templatePath = path.join(
+ __dirname,
+ '../template_multiplatform_components'
+ );
+ initUtil.copyComponentFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName
+ );
if (typeScript) {
initUtil.prepareComponentsTypescript(currentDirectory, folderName);
// Copy typescript template overlay over existing template files
- templatePath = path.join(__dirname, '../template_overlay_typescript_components');
- initUtil.copyComponentFiles(templatePath, destDirectory, immersive, packageName);
+ templatePath = path.join(
+ __dirname,
+ '../template_overlay_typescript_components'
+ );
+ initUtil.copyComponentFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName
+ );
}
- initUtil.renameComponentsFiles(folderName, packageName, visibleName, target);
+ initUtil.renameComponentsFiles(
+ folderName,
+ packageName,
+ visibleName,
+ target
+ );
if (!initUtil.createSymlink(currentDirectory, folderName)) {
- logger.yellow('Couldn\'t create symlink for resources directory. Please do it manually if you want to use resources in your project. For more information check: https:///magicscript.org/');
+ logger.yellow(
+ "Couldn't create symlink for resources directory. Please do it manually if you want to use resources in your project. For more information check: https:///magicscript.org/"
+ );
}
initUtil.preparePlatforms(destDirectory, target);
logger.green(`Project successfully created for platforms: ${target}`);
} else {
- logger.green(`Start creating Vanilla Magic Script project for ${appType} app type`);
- initUtil.copyVanillaFiles(templatePath, destDirectory, immersive, packageName, visibleName);
+ logger.green(
+ `Start creating Vanilla Magic Script project for ${appType} app type`
+ );
+ initUtil.copyVanillaFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName,
+ visibleName
+ );
if (typeScript) {
initUtil.prepareTypescript(currentDirectory, folderName);
// Copy typescript template overlay over existing template files
templatePath = path.join(__dirname, '../template_overlay_typescript');
- initUtil.copyVanillaFiles(templatePath, destDirectory, immersive, packageName, visibleName);
+ initUtil.copyVanillaFiles(
+ templatePath,
+ destDirectory,
+ immersive,
+ packageName,
+ visibleName
+ );
}
- logger.green(`Vanilla Magic Script project successfully created for ${appType} app type`);
+ logger.green(
+ `Vanilla Magic Script project successfully created for ${appType} app type`
+ );
}
if (gitRepository) {
initUtil.createGitRepository(folderName);
}
})
- .catch(err => logger.red(err))
+ .catch((err) => logger.red(err))
// Add this callback for testing purpose - inquirer doesn't provide functionality to reset values
// after every test and caches them
.finally(() => {
@@ -215,11 +294,13 @@ function setPackageName(name) {
function setTarget(argTarget) {
if (argTarget && Array.isArray(argTarget)) {
- target = argTarget.map(string => {
+ target = argTarget.map((string) => {
return string.toUpperCase();
});
} else {
- logger.yellow('There is no proper target passed, project will generate Lumin files structure for Components app');
+ logger.yellow(
+ 'There is no proper target passed, project will generate Lumin files structure for Components app'
+ );
target = ['LUMIN'];
}
}
diff --git a/commands/install.js b/commands/install.js
index 0e72e27..cc09835 100644
--- a/commands/install.js
+++ b/commands/install.js
@@ -3,7 +3,7 @@
const util = require('../lib/util');
const fs = require('fs');
-module.exports = argv => {
+module.exports = (argv) => {
util.navigateIfComponents();
let mpkPath = util.findMPKPath();
if (mpkPath && mpkPath !== '') {
@@ -12,6 +12,8 @@ module.exports = argv => {
if (fs.existsSync(argv.path)) {
util.installPackage(argv);
} else {
- console.log(`MPK doesn't exist at ${argv.path}, please build it and try again.`);
+ console.log(
+ `MPK doesn't exist at ${argv.path}, please build it and try again.`
+ );
}
};
diff --git a/commands/remove.js b/commands/remove.js
index 4e5e49a..237da02 100644
--- a/commands/remove.js
+++ b/commands/remove.js
@@ -3,12 +3,12 @@
const { exec } = require('child_process');
const util = require('../lib/util');
-module.exports = argv => {
+module.exports = (argv) => {
util.navigateIfComponents();
remove(argv);
};
-function remove (argv) {
+function remove(argv) {
let packageName = util.findPackageName();
let removeCommand = 'mldb uninstall ' + packageName;
console.log(removeCommand);
diff --git a/commands/run.js b/commands/run.js
index 69b68d8..bb7e624 100644
--- a/commands/run.js
+++ b/commands/run.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-inner-declarations */
// Copyright (c) 2019 Magic Leap, Inc. All Rights Reserved
// Distributed under Apache 2.0 License. See LICENSE file in the project root for full license information.
let { exec, spawn } = require('child_process');
@@ -10,11 +11,11 @@ let packageName;
let debug;
let port;
-function getPortFromPackageName () {
+function getPortFromPackageName() {
return hash(packageName, 65535 - 1024) + 1024;
}
-function isRunning (callback) {
+function isRunning(callback) {
exec('mldb ps', (err, stdout, stderr) => {
var running = null;
if (err) {
@@ -38,7 +39,7 @@ function isRunning (callback) {
});
}
-function launchFunction (callback) {
+function launchFunction(callback) {
let autoPrivilege = debug ? ' --auto-net-privs' : '';
let portNumber = port > 0 && port < 65536 ? port : getPortFromPackageName();
let portArg = !debug ? ' -v INSPECTOR_PORT=' + portNumber : '';
@@ -51,7 +52,7 @@ function launchFunction (callback) {
return;
}
if (stdout.includes('Success')) {
- function cb (result) {
+ function cb(result) {
callback(result);
}
isRunning(cb);
@@ -59,7 +60,7 @@ function launchFunction (callback) {
});
}
-function terminateFunction (callback) {
+function terminateFunction(callback) {
let launchCommand = 'mldb terminate ' + packageName;
console.info('Terminating:', packageName);
exec(launchCommand, (err, stdout, stderr) => {
@@ -67,7 +68,7 @@ function terminateFunction (callback) {
});
}
-function launchCallback (pid) {
+function launchCallback(pid) {
if (pid == null) {
console.error('Failed to launch:', packageName);
return;
@@ -100,7 +101,7 @@ function launchCallback (pid) {
console.info(packageName, 'launched with PID:', pid);
}
-function runLumin (argv) {
+function runLumin(argv) {
let localArguments = argv._;
debug = argv.debug;
port = argv.port;
@@ -110,18 +111,20 @@ function runLumin (argv) {
packageName = util.findPackageName();
}
if (packageName) {
- function installedCallback (installed) {
+ function installedCallback(installed) {
if (installed) {
isRunning(runningCallback);
} else {
- console.warn(`Package: ${packageName} is not installed. Please install it.`);
+ console.warn(
+ `Package: ${packageName} is not installed. Please install it.`
+ );
}
}
- function runningCallback (pid) {
+ function runningCallback(pid) {
if (pid == null) {
launchFunction(launchCallback);
} else {
- function launchMe () {
+ function launchMe() {
launchFunction(launchCallback);
}
terminateFunction(launchMe);
@@ -131,7 +134,7 @@ function runLumin (argv) {
}
}
-module.exports = argv => {
+module.exports = (argv) => {
if (argv.target === 'lumin') {
util.navigateIfComponents();
runLumin(argv);
diff --git a/jest.config.js b/jest.config.js
index b39b33a..ea3d47b 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -10,6 +10,7 @@ module.exports = {
collectCoverageFrom: [
'commands/*.js',
'lib/*.js',
+ 'lib/rename/*.js',
'util/*.js'
],
testEnvironment: 'node',
diff --git a/lib/initutils.js b/lib/initutils.js
index ec9b575..bde9828 100644
--- a/lib/initutils.js
+++ b/lib/initutils.js
@@ -3,8 +3,9 @@
let fs = require('fs');
const logger = require('../lib/logger');
const util = require('../lib/util');
-const rename = require.resolve('react-native-rename');
-let { spawnSync, execSync } = require('child_process');
+// const rename = require.resolve('react-native-rename');
+let { rename } = require('../lib/rename/rename');
+let { execSync } = require('child_process');
module.exports.updateManifest = function (
contents,
@@ -14,7 +15,7 @@ module.exports.updateManifest = function (
) {
logger.yellow('Updating manifest file');
let replaced = contents
- .replace('com.magicleap.magicscript.hello-sample', packageName)
+ .replace('com.magicleap.magicscript.hello-sample', packageName)
.replace(new RegExp('MagicScript Hello Sample', 'g'), visibleName);
if (immersive) {
replaced = replaced
@@ -29,37 +30,51 @@ module.exports.updateManifest = function (
};
module.exports.updateComponentManifest = function (contents) {
- let replaced = contents.replace('universe', 'fullscreen')
- .replace('Universe', 'Fullscreen')
- .replace(
- '',
- '\n '
- );
- return replaced
+ let replaced = contents
+ .replace('universe', 'fullscreen')
+ .replace('Universe', 'Fullscreen')
+ .replace(
+ '',
+ '\n '
+ );
+ return replaced;
};
-module.exports.copyComponentFiles = function (srcPath, destPath, immersive, packageName) {
+module.exports.copyComponentFiles = function (
+ srcPath,
+ destPath,
+ immersive,
+ packageName
+) {
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}
const filesToCreate = fs.readdirSync(srcPath);
- filesToCreate.forEach(file => {
+ filesToCreate.forEach((file) => {
const origFilePath = `${srcPath}/${file}`;
const stats = fs.statSync(origFilePath);
if (stats.isFile()) {
- if(immersive && file === 'manifest.xml') {
+ if (immersive && file === 'manifest.xml') {
var contents = fs.readFileSync(origFilePath, 'utf8');
contents = this.updateComponentManifest(contents);
const writePath = `${destPath}/${file}`;
fs.writeFileSync(writePath, contents, 'utf8');
- } else if(immersive && (file === 'main.js' || file === 'main.tsx')) {
+ } else if (immersive && (file === 'main.js' || file === 'main.tsx')) {
var contents = fs.readFileSync(origFilePath, 'utf8');
contents = contents.replace('landscape', 'immersive');
const writePath = `${destPath}/${file}`;
fs.writeFileSync(writePath, contents, 'utf8');
- } else if (file === 'model.fbx' || file === 'model.kmat' || file === 'portal.fbx' || file === 'portal.kmat') {
+ } else if (
+ file === 'model.fbx' ||
+ file === 'model.kmat' ||
+ file === 'portal.fbx' ||
+ file === 'portal.kmat'
+ ) {
var contents = fs.readFileSync(origFilePath, 'utf8');
- contents = contents.replace(new RegExp('com_magicscript_template', 'g'), packageName.replace(/\./g, '_'));
+ contents = contents.replace(
+ new RegExp('com_magicscript_template', 'g'),
+ packageName.replace(/\./g, '_')
+ );
const writePath = `${destPath}/${file}`;
fs.writeFileSync(writePath, contents, 'utf8');
} else {
@@ -69,36 +84,69 @@ module.exports.copyComponentFiles = function (srcPath, destPath, immersive, pack
}
} else if (stats.isDirectory()) {
let newDestPath = `${destPath}/${file}`;
- this.copyComponentFiles(origFilePath, newDestPath, immersive, packageName);
+ this.copyComponentFiles(
+ origFilePath,
+ newDestPath,
+ immersive,
+ packageName
+ );
}
});
-}
+};
-module.exports.copyVanillaFiles = function (srcPath, destPath, immersive, packageName, visibleName) {
+module.exports.copyVanillaFiles = function (
+ srcPath,
+ destPath,
+ immersive,
+ packageName,
+ visibleName
+) {
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}
const filesToCreate = fs.readdirSync(srcPath);
- filesToCreate.forEach(file => {
+ filesToCreate.forEach((file) => {
const origFilePath = `${srcPath}/${file}`;
const stats = fs.statSync(origFilePath);
if (stats.isFile()) {
var contents = fs.readFileSync(origFilePath, 'utf8');
if (file === 'manifest.xml') {
- contents = this.updateManifest(contents, packageName, visibleName, immersive);
+ contents = this.updateManifest(
+ contents,
+ packageName,
+ visibleName,
+ immersive
+ );
fs.writeFileSync(`${destPath}/${file}`, contents, 'utf8');
} else if (immersive && (file === 'app.js' || file === 'app.ts')) {
- contents = contents.replace(new RegExp('LandscapeApp', 'g'), 'ImmersiveApp');
+ contents = contents.replace(
+ new RegExp('LandscapeApp', 'g'),
+ 'ImmersiveApp'
+ );
fs.writeFileSync(`${destPath}/${file}`, contents, 'utf8');
- } else if (file === 'model.fbx' || file === 'model.kmat' || file === 'portal.fbx' || file === 'portal.kmat') {
- contents = contents.replace(new RegExp('com_magicleap_magicscript_hello-sample', 'g'), packageName.replace(/\./g, '_'));
+ } else if (
+ file === 'model.fbx' ||
+ file === 'model.kmat' ||
+ file === 'portal.fbx' ||
+ file === 'portal.kmat'
+ ) {
+ contents = contents.replace(
+ new RegExp('com_magicleap_magicscript_hello-sample', 'g'),
+ packageName.replace(/\./g, '_')
+ );
fs.writeFileSync(`${destPath}/${file}`, contents, 'utf8');
} else {
fs.writeFileSync(`${destPath}/${file}`, fs.readFileSync(origFilePath));
}
} else if (stats.isDirectory()) {
let newDestPath = `${destPath}/${file}`;
- this.copyVanillaFiles(origFilePath, newDestPath, immersive, packageName, visibleName);
+ this.copyVanillaFiles(
+ origFilePath,
+ newDestPath,
+ immersive,
+ packageName,
+ visibleName
+ );
}
});
};
@@ -132,36 +180,45 @@ module.exports.preparePlatforms = function (destPath, target) {
}
};
-
module.exports.isComponentsAppType = function (answers) {
return answers.ISCOMPONENTS === true;
};
module.exports.createSymlink = function (currentDirectory, folderName) {
try {
- fs.symlinkSync(`../assets`, `${currentDirectory}/${folderName}/reactnative/assets`, 'dir');
+ fs.symlinkSync(
+ `../assets`,
+ `${currentDirectory}/${folderName}/reactnative/assets`,
+ 'dir'
+ );
return true;
} catch (error) {
return false;
}
};
-module.exports.prepareComponentsTypescript = function(currentDirectory, folderName) {
+module.exports.prepareComponentsTypescript = function (
+ currentDirectory,
+ folderName
+) {
fs.unlinkSync(`${currentDirectory}/${folderName}/lumin/src/main.js`);
fs.unlinkSync(`${currentDirectory}/${folderName}/src/app.js`);
-}
+};
module.exports.prepareTypescript = function (currentDirectory, folderName) {
fs.unlinkSync(`${currentDirectory}/${folderName}/src/main.js`);
fs.unlinkSync(`${currentDirectory}/${folderName}/src/app.js`);
};
-module.exports.renameComponentsFiles = function (folderName, packageName, visibleName, target) {
+module.exports.renameComponentsFiles = function (
+ folderName,
+ packageName,
+ visibleName,
+ target
+) {
let projectPath = process.cwd();
if (!visibleName) {
- logger.red(
- 'You have to specify the project name to rename the project!'
- );
+ logger.red('You have to specify the project name to rename the project!');
} else {
let manifestPath = `${projectPath}/${folderName}/lumin/manifest.xml`;
if (fs.existsSync(manifestPath)) {
@@ -192,19 +249,12 @@ module.exports.renameComponentsFiles = function (folderName, packageName, visibl
}
}
let isReact = target.includes('IOS') || target.includes('ANDROID');
- if(isReact) {
- var renameCommand = rename;
- if (process.platform === 'win32') {
- renameCommand = `node ${rename}`;
- }
+ if (isReact) {
var reactNativeProjectPath = `${process.cwd()}/${folderName}/reactnative`;
if (fs.existsSync(reactNativeProjectPath)) {
logger.green('Prepare project name and package in the project...');
- spawnSync(renameCommand, [`${visibleName}`, '-b', `${packageName}`], {
- cwd: `${reactNativeProjectPath}`,
- shell: process.platform === 'win32',
- stdio: 'inherit'
- });
+ process.chdir(reactNativeProjectPath);
+ rename(reactNativeProjectPath, folderName, packageName);
} else {
logger.yellow(
'Renaming of the project could not be processed because the path does not exist!'
@@ -212,7 +262,7 @@ module.exports.renameComponentsFiles = function (folderName, packageName, visibl
}
}
}
-}
+};
module.exports.createAndroidLocalProperties = function (projPath) {
if (!fs.existsSync(`${projPath}/reactnative/android/local.properties`)) {
@@ -222,7 +272,11 @@ module.exports.createAndroidLocalProperties = function (projPath) {
androidHome = androidHome.replace(/\\/g, '\\\\');
}
let sdkDir = 'sdk.dir=' + androidHome;
- fs.writeFileSync(`${projPath}/reactnative/android/local.properties`, sdkDir, 'utf-8');
+ fs.writeFileSync(
+ `${projPath}/reactnative/android/local.properties`,
+ sdkDir,
+ 'utf-8'
+ );
logger.green('Successfully created local.properties file!');
} else {
logger.yellow(
@@ -236,9 +290,11 @@ module.exports.createAndroidLocalProperties = function (projPath) {
module.exports.createGitRepository = function (repositoryPath) {
try {
- execSync(`cd ${repositoryPath} && git init && git add . && git commit -am"Initial commit."`);
- logger.green("git repository initialised.");
+ execSync(
+ `cd ${repositoryPath} && git init && git add . && git commit -am"Initial commit."`
+ );
+ logger.green('git repository initialised.');
} catch (error) {
- logger.red("git repository not initialised - you have to do it manually.");
+ logger.red('git repository not initialised - you have to do it manually.');
}
};
diff --git a/lib/logger.js b/lib/logger.js
index 531d472..8b5431b 100644
--- a/lib/logger.js
+++ b/lib/logger.js
@@ -4,17 +4,17 @@ const yellow = '\x1b[33m';
const normal = '\x1b[0m';
module.exports.red = function (text) {
- console.log(red, text);
+ console.log(red, text);
};
module.exports.green = function (text) {
- console.log(green, text);
+ console.log(green, text);
};
module.exports.yellow = function (text) {
- console.log(yellow, text);
+ console.log(yellow, text);
};
module.exports.normal = function (text) {
- console.log(normal, text);
-};
\ No newline at end of file
+ console.log(normal, text);
+};
diff --git a/lib/rename/config/bundleIdentifiers.js b/lib/rename/config/bundleIdentifiers.js
new file mode 100644
index 0000000..27fccec
--- /dev/null
+++ b/lib/rename/config/bundleIdentifiers.js
@@ -0,0 +1,57 @@
+// nS - No Space
+// lC - Lowercase
+let path = require('path');
+
+module.exports.bundleIdentifiers = function (
+ currentAppName,
+ newName,
+ currentBundleID,
+ newBundleID,
+ newBundlePath
+) {
+ const noSpaceCurrentAppName = currentAppName.replace(/\s/g, '');
+ const noSpaceNewName = newName.replace(/\s/g, '');
+ const lowcaseNoSpaceCurrentBundleID = currentBundleID.toLowerCase();
+ const lowcaseNoSpaceNewBundleID = newBundleID.toLowerCase();
+
+ return [
+ {
+ regex: currentBundleID,
+ replacement: newBundleID,
+ paths: [
+ 'android/app/BUCK',
+ 'android/app/build.gradle',
+ 'android/app/src/main/AndroidManifest.xml'
+ ]
+ },
+ {
+ regex: currentBundleID,
+ replacement: newBundleID,
+ paths: [
+ path.join(`${newBundlePath}`, 'MainActivity.java'),
+ path.join(`${newBundlePath}`, 'MainApplication.java')
+ ]
+ },
+ {
+ regex: lowcaseNoSpaceCurrentBundleID,
+ replacement: lowcaseNoSpaceNewBundleID,
+ paths: [path.join(`${newBundlePath}`, 'MainApplication.java')]
+ },
+ {
+ // App name (probably) doesn't start with `.`, but the bundle ID will
+ // include the `.`. This fixes a possible issue where the bundle ID
+ // also contains the app name and prevents it from being inappropriately
+ // replaced by an update to the app name with the same bundle ID
+ regex: new RegExp(`(?!\\.)(.|^)${noSpaceCurrentAppName}`, 'g'),
+ replacement: `$1${noSpaceNewName}`,
+ paths: [path.join(`${newBundlePath}`, 'MainActivity.java')]
+ },
+ {
+ regex: currentBundleID,
+ replacement: newBundleID,
+ paths: [
+ path.join('ios', `${noSpaceNewName}.xcodeproj`, 'project.pbxproj')
+ ]
+ }
+ ];
+};
diff --git a/lib/rename/config/filesToModifyContent.js b/lib/rename/config/filesToModifyContent.js
new file mode 100644
index 0000000..a48d599
--- /dev/null
+++ b/lib/rename/config/filesToModifyContent.js
@@ -0,0 +1,66 @@
+// nS - No Space
+// lC - Lowercase
+let path = require('path');
+
+module.exports.filesToModifyContent = function (currentAppName, newName) {
+ const noSpaceCurrentAppName = currentAppName.replace(/\s/g, '');
+ const noSpaceNewName = newName.replace(/\s/g, '');
+
+ return [
+ {
+ regex: `${currentAppName}`,
+ replacement: `${newName}`,
+ paths: ['android/app/src/main/res/values/strings.xml']
+ },
+ {
+ regex: noSpaceCurrentAppName,
+ replacement: noSpaceNewName,
+ paths: [
+ 'index.js',
+ 'index.android.js',
+ 'index.ios.js',
+ path.join('ios', `${noSpaceNewName}.xcodeproj`, 'project.pbxproj'),
+ path.join(
+ 'ios',
+ `${noSpaceNewName}.xcworkspace`,
+ 'contents.xcworkspacedata'
+ ),
+ path.join(
+ 'ios',
+ `${noSpaceNewName}.xcodeproj`,
+ 'xcshareddata',
+ 'xcschemes',
+ `${noSpaceNewName}.xcscheme`
+ ),
+ path.join('ios', `${noSpaceNewName}`, 'AppDelegate.m'),
+ path.join('android', 'settings.gradle'),
+ path.join('ios', `${noSpaceNewName}Tests`, `${noSpaceNewName}Tests.m`),
+ path.join('ios', 'build', 'info.plist'),
+ path.join('ios', 'Podfile'),
+ 'app.json'
+ ]
+ },
+ {
+ regex: `text="${currentAppName}"`,
+ replacement: `text="${newName}"`,
+ paths: [
+ path.join('ios', `${noSpaceNewName}`, 'Base.lproj', 'LaunchScreen.xib')
+ ]
+ },
+ {
+ regex: currentAppName,
+ replacement: newName,
+ paths: [path.join('ios', `${noSpaceNewName}`, 'Info.plist')]
+ },
+ {
+ regex: `"name": "${noSpaceCurrentAppName}"`,
+ replacement: `"name": "${noSpaceNewName}"`,
+ paths: ['package.json']
+ },
+ {
+ regex: `"displayName": "${currentAppName}"`,
+ replacement: `"displayName": "${newName}"`,
+ paths: ['app.json']
+ }
+ ];
+};
diff --git a/lib/rename/config/foldersAndFiles.js b/lib/rename/config/foldersAndFiles.js
new file mode 100644
index 0000000..9e2e39e
--- /dev/null
+++ b/lib/rename/config/foldersAndFiles.js
@@ -0,0 +1,14 @@
+module.exports.foldersAndFiles = function (currentAppName, newName) {
+ const noSpaceCurrentAppName = currentAppName.replace(/\s/g, '');
+ const noSpaceNewName = newName.replace(/\s/g, '');
+
+ return [
+ `ios/${noSpaceCurrentAppName}`,
+ `ios/${noSpaceCurrentAppName}.xcodeproj`,
+ `ios/${noSpaceNewName}.xcodeproj/xcshareddata/xcschemes/${noSpaceCurrentAppName}.xcscheme`,
+ `ios/${noSpaceCurrentAppName}Tests`,
+ `ios/${noSpaceNewName}Tests/${noSpaceCurrentAppName}Tests.m`,
+ `ios/${noSpaceCurrentAppName}.xcworkspace`,
+ `ios/${noSpaceCurrentAppName}-Bridging-Header.h`
+ ];
+};
diff --git a/lib/rename/rename.js b/lib/rename/rename.js
new file mode 100644
index 0000000..d0f5971
--- /dev/null
+++ b/lib/rename/rename.js
@@ -0,0 +1,68 @@
+let {
+ resolveFoldersAndFiles,
+ resolveFilesToModifyContent,
+ resolveJavaFiles,
+ deletePreviousBundleDirectory,
+ resolveBundleIdentifiers
+} = require('./renamesteps');
+let { filesToModifyContent } = require('./config/filesToModifyContent');
+let { foldersAndFiles } = require('./config/foldersAndFiles');
+let fs = require('fs');
+let path = require('path');
+let logger = require('../logger');
+const templateAppName = 'Template';
+const templateBundleId = 'com.magicscript.template';
+
+// We are not validating name or package name at this point - it is validated when passing data via CLI in the first place.
+module.exports.rename = function (dirname, newName, newPackageName) {
+ const currentAppName = templateAppName;
+ const noSpaceCurrentAppName = templateAppName;
+ const lowcaseNoSpaceCurrentAppName = templateAppName.toLowerCase();
+ const noSpaceNewName = newName.replace(/\s/g, '');
+ const lowcaseNoSpaceNewAppName = noSpaceNewName.toLowerCase();
+ const bundleID = newPackageName.toLowerCase();
+ const listOfFoldersAndFiles = foldersAndFiles(currentAppName, newName);
+ const listOfFilesToModifyContent = filesToModifyContent(
+ currentAppName,
+ newName
+ );
+
+ if (
+ newName === currentAppName ||
+ newName === noSpaceCurrentAppName ||
+ newName === lowcaseNoSpaceCurrentAppName
+ ) {
+ return logger.red('Please try a different name.');
+ }
+ resolveFoldersAndFiles({
+ listOfFoldersAndFiles,
+ noSpaceCurrentAppName,
+ noSpaceNewName,
+ dirname
+ });
+ resolveFilesToModifyContent({
+ listOfFilesToModifyContent,
+ dirname,
+ bundleID
+ });
+ const parameters = resolveJavaFiles({
+ currentAppName,
+ newName,
+ newPackageName,
+ bundleID,
+ lowcaseNoSpaceNewAppName,
+ templateBundleId,
+ dirname
+ });
+ resolveBundleIdentifiers(parameters);
+ deletePreviousBundleDirectory(templateBundleId);
+ logger.green(`APP SUCCESSFULLY RENAMED TO "${newName}"! 🎉 🎉 🎉`);
+ if (fs.existsSync(path.join(dirname, 'ios', 'Podfile'))) {
+ logger.yellow(
+ 'Podfile has been modified, please run "pod install" inside ios directory.'
+ );
+ }
+ logger.yellow(
+ 'Please make sure to run "watchman watch-del-all" and "npm start --reset-cache" before running the app.'
+ );
+};
diff --git a/lib/rename/renamesteps.js b/lib/rename/renamesteps.js
new file mode 100644
index 0000000..6b0ddd1
--- /dev/null
+++ b/lib/rename/renamesteps.js
@@ -0,0 +1,111 @@
+let {
+ copyFiles,
+ copyFileOrDir,
+ deleteFiles,
+ replaceContent
+} = require('./renameutils');
+let { bundleIdentifiers } = require('./config/bundleIdentifiers');
+let path = require('path');
+let fs = require('fs');
+let logger = require('../logger');
+
+module.exports.resolveFoldersAndFiles = function (params) {
+ const {
+ listOfFoldersAndFiles,
+ noSpaceCurrentAppName,
+ noSpaceNewName,
+ dirname
+ } = params;
+ listOfFoldersAndFiles.forEach((element, index) => {
+ const dest = element.replace(
+ new RegExp(noSpaceCurrentAppName, 'i'),
+ noSpaceNewName
+ );
+ copyFileOrDir(path.join(dirname, element), path.join(dirname, dest));
+ deleteFiles(path.join(dirname, element));
+ });
+};
+
+module.exports.resolveFilesToModifyContent = function (params) {
+ const { listOfFilesToModifyContent, dirname, bundleID } = params;
+ listOfFilesToModifyContent.map((file) => {
+ file.paths.map((filePath, index) => {
+ const newPaths = [];
+ if (fs.existsSync(path.join(dirname, filePath))) {
+ newPaths.push(path.join(dirname, filePath));
+ replaceContent(file.regex, file.replacement, newPaths);
+ }
+ });
+ });
+ return bundleID;
+};
+
+module.exports.resolveJavaFiles = function (params) {
+ let {
+ currentAppName,
+ newName,
+ newPackageName,
+ bundleID,
+ lowcaseNoSpaceNewAppName,
+ templateBundleId,
+ dirname
+ } = params;
+ const newBundleID = bundleID;
+ const javaFileBase = '/android/app/src/main/java';
+ const newJavaPath = `${javaFileBase}/${newPackageName.replace(/\./g, '/')}`;
+ const currentJavaPath = `${javaFileBase}/${templateBundleId.replace(
+ /\./g,
+ '/'
+ )}`;
+
+ const fullCurrentBundlePath = path.join(dirname, currentJavaPath);
+ const fullNewBundlePath = path.join(dirname, newJavaPath);
+
+ // Create new bundle folder if doesn't exist yet
+ if (!fs.existsSync(fullNewBundlePath)) {
+ fs.mkdirSync(fullNewBundlePath, { recursive: true });
+ copyFiles(fullCurrentBundlePath, fullNewBundlePath);
+ deleteFiles(fullCurrentBundlePath);
+ }
+
+ return {
+ currentAppName,
+ newName,
+ templateBundleId,
+ dirname,
+ newBundleID,
+ newJavaPath
+ };
+};
+
+module.exports.deletePreviousBundleDirectory = function (templateBundleId) {
+ const dir = templateBundleId.replace(/\./g, '/');
+ deleteFiles(dir);
+ logger.green('Done removing previous bundle directory.');
+};
+
+module.exports.resolveBundleIdentifiers = function (params) {
+ const {
+ currentAppName,
+ newName,
+ templateBundleId,
+ dirname,
+ newBundleID,
+ newJavaPath
+ } = params;
+ bundleIdentifiers(
+ currentAppName,
+ newName,
+ templateBundleId,
+ newBundleID,
+ newJavaPath
+ ).map((file) => {
+ file.paths.map((filePath, index) => {
+ const newPaths = [];
+ if (fs.existsSync(path.join(dirname, filePath))) {
+ newPaths.push(path.join(dirname, filePath));
+ replaceContent(file.regex, file.replacement, newPaths);
+ }
+ });
+ });
+};
diff --git a/lib/rename/renameutils.js b/lib/rename/renameutils.js
new file mode 100644
index 0000000..db9b28a
--- /dev/null
+++ b/lib/rename/renameutils.js
@@ -0,0 +1,79 @@
+let fs = require('fs');
+let logger = require('../logger');
+let replace = require('node-replace');
+
+const replaceOptions = {
+ recursive: true,
+ silent: true
+};
+
+module.exports.copyFiles = function (srcPath, destPath) {
+ if (!fs.existsSync(destPath)) {
+ fs.mkdirSync(destPath);
+ }
+ const filesToCreate = fs.readdirSync(srcPath);
+ filesToCreate.forEach((file) => {
+ const origFilePath = `${srcPath}/${file}`;
+ const stats = fs.statSync(origFilePath);
+ if (stats.isFile()) {
+ var contents = fs.readFileSync(origFilePath, 'utf8');
+ const writePath = `${destPath}/${file}`;
+ fs.writeFileSync(writePath, contents, 'utf8');
+ } else if (stats.isDirectory()) {
+ let newDestPath = `${destPath}/${file}`;
+ module.exports.copyFiles(origFilePath, newDestPath);
+ }
+ });
+};
+
+module.exports.copyFileOrDir = function (element, destPath) {
+ const stats = fs.statSync(element);
+ if (stats.isFile()) {
+ var contents = fs.readFileSync(element, 'utf8');
+ fs.writeFileSync(destPath, contents, 'utf8');
+ } else if (stats.isDirectory()) {
+ module.exports.copyFiles(element, destPath);
+ }
+};
+
+module.exports.deletePreviousBundleDirectory = function ({
+ oldBundleNameDir,
+ shouldDelete
+}) {
+ if (shouldDelete) {
+ const dir = oldBundleNameDir.replace(/\./g, '/');
+ fs.unlinkSync(dir);
+ logger.green('Done removing previous bundle directory.');
+ } else {
+ logger.yellow('Bundle directory was not changed. Keeping...');
+ }
+};
+
+module.exports.replaceContent = function (regex, replacement, paths) {
+ replace({
+ regex,
+ replacement,
+ paths,
+ ...replaceOptions
+ });
+};
+
+module.exports.deleteFiles = function (path) {
+ var files = [];
+ if (fs.existsSync(path)) {
+ if (fs.lstatSync(path).isFile()) {
+ fs.unlinkSync(path);
+ } else {
+ files = fs.readdirSync(path);
+ files.forEach(function (file, index) {
+ var curPath = path + '/' + file;
+ if (fs.lstatSync(curPath).isDirectory()) {
+ module.exports.deleteFiles(curPath);
+ } else {
+ fs.unlinkSync(curPath);
+ }
+ });
+ fs.rmdirSync(path);
+ }
+ }
+};
diff --git a/lib/util.js b/lib/util.js
index 45b1add..900df57 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -2,9 +2,8 @@
// Distributed under Apache 2.0 License. See LICENSE file in the project root for full license information.
let fs = require('fs');
let glob = require('glob');
-let { exec, execFile, execSync, spawnSync, spawn } = require('child_process');
+let { exec, execFile, execSync, spawn } = require('child_process');
const path = require('path');
-const rename = require.resolve('react-native-rename');
module.exports.findPackageName = function () {
let manifestPath = 'manifest.xml';
@@ -80,7 +79,7 @@ module.exports.installPackage = function (argv) {
if (argv.target === 'lumin') {
let packageName = this.findPackageName();
navigateIfComponents();
- this.isInstalled(packageName, installed => {
+ this.isInstalled(packageName, (installed) => {
var args = ['install'];
if (installed) {
args.push('-u');
@@ -91,13 +90,13 @@ module.exports.installPackage = function (argv) {
shell: process.platform === 'win32'
});
if (child) {
- child.stdout.on('data', data => {
+ child.stdout.on('data', (data) => {
process.stdout.write(data);
});
- child.stderr.on('data', data => {
+ child.stderr.on('data', (data) => {
process.stderr.write(data);
});
- child.on('error', err => {
+ child.on('error', (err) => {
throw err;
});
}
@@ -144,8 +143,7 @@ module.exports.validateFolderName = function (folderName) {
module.exports.validateAppName = function (appName) {
if (!module.exports.isValidAppName(appName)) {
return (
- 'Invalid app name. Must match ' +
- module.exports.AppNameRegex.toString()
+ 'Invalid app name. Must match ' + module.exports.AppNameRegex.toString()
);
}
return true;
@@ -158,7 +156,7 @@ module.exports.isValidAppType = function (appType) {
module.exports.navigateIfComponents = navigateIfComponents;
-function navigateIfComponents () {
+function navigateIfComponents() {
const path = process.cwd();
if (fs.existsSync(`${path}/lumin`)) {
process.chdir('lumin');
@@ -167,9 +165,9 @@ function navigateIfComponents () {
module.exports.removeFilesRecursively = removeFilesRecursively;
-function removeFilesRecursively (path) {
+function removeFilesRecursively(path) {
const filesToDelete = fs.readdirSync(path);
- filesToDelete.forEach(file => {
+ filesToDelete.forEach((file) => {
const curPath = `${path}/${file}`;
if (fs.lstatSync(curPath).isDirectory()) {
removeFilesRecursively(curPath);
@@ -186,7 +184,8 @@ module.exports.findMPKPath = function () {
if (!fs.existsSync(packagePath)) {
console.error('Cannot file: app.package');
} else {
- var output = '' + execSync('mabu -t device --print-package-outputs app.package');
+ var output =
+ '' + execSync('mabu -t device --print-package-outputs app.package');
let tokenized = output.split('\t');
if (tokenized && tokenized.length > 1) {
mpkName = tokenized[1].trim();
diff --git a/package.json b/package.json
index eacaf53..af56ca5 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"glob": "^7.1.3",
"hash-index": "^3.0.0",
"inquirer": "^6.3.1",
+ "node-replace": "^0.3.3",
"react-native-rename": "github:magic-script/react-native-rename",
"which": "^1.3.1",
"yargs": "^12.0.2"
@@ -24,6 +25,9 @@
"testEnvironment": "node"
},
"devDependencies": {
+ "@babel/core": "^7.10.2",
+ "@babel/preset-env": "^7.10.2",
+ "babel-jest": "^26.0.1",
"eslint": "^5.12.1",
"eslint-config-semistandard": "^13.0.0",
"eslint-config-standard": "^12.0.0",
@@ -32,7 +36,7 @@
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
- "jest": "^24.8.0",
+ "jest": "^26.0.1",
"semistandard": "^13.0.1"
},
"engines": {
@@ -41,6 +45,7 @@
"files": [
"/bin",
"/lib",
+ "/lib/rename",
"/commands",
"/template",
"/template_components",