Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions __e2e__/init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ test('init --template', () => {

// make sure we don't leave garbage
expect(fs.readdirSync(DIR)).toEqual(['TestInit']);
expect(fs.readdirSync(path.join(DIR, 'TestInit'))).toEqual(templateFiles);

let dirFiles = fs.readdirSync(path.join(DIR, 'TestInit'));
expect(dirFiles.length).toEqual(templateFiles.length);

for (const templateFile of templateFiles) {
expect(dirFiles.includes(templateFile)).toBe(true);
}

const pkgJson = require(path.join(DIR, 'TestInit', 'package.json'));
expect(pkgJson).toMatchSnapshot(
Expand All @@ -74,11 +80,15 @@ test('init --template file:/tmp/custom/template', () => {
'custom/template/template-dir/package.json': '{}',
'custom/template/template-dir/empty': '',
});
let templatePath = path.resolve(DIR, 'custom', 'template');
if (process.platform === 'win32') {
templatePath = templatePath.split('\\').join('/');
}

const {stdout} = run(DIR, [
'init',
'--template',
`file://${path.resolve(DIR, 'custom', 'template')}`,
`file://${templatePath}`,
'TestInit',
]);

Expand All @@ -100,5 +110,11 @@ test('init --template with custom project path', () => {

// make sure we don't leave garbage
expect(fs.readdirSync(DIR)).toEqual([customPath]);
expect(fs.readdirSync(path.join(DIR, customPath))).toEqual(templateFiles);

let dirFiles = fs.readdirSync(path.join(DIR, customPath));
expect(dirFiles.length).toEqual(templateFiles.length);

for (const templateFile of templateFiles) {
expect(dirFiles.includes(templateFile)).toBe(true);
}
});
9 changes: 7 additions & 2 deletions __e2e__/legacyInit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ test('legacy init through react-native-cli', () => {
'package.json',
'yarn.lock',
];

const {stdout} = execa.sync('npx', ['react-native-cli', 'init', 'TestApp'], {
cwd: DIR,
});
Expand All @@ -43,7 +42,13 @@ test('legacy init through react-native-cli', () => {

// make sure we don't leave garbage
expect(fs.readdirSync(DIR)).toEqual(['TestApp']);
expect(fs.readdirSync(path.join(DIR, 'TestApp'))).toEqual(templateFiles);

let dirFiles = fs.readdirSync(path.join(DIR, 'TestApp'));
expect(dirFiles.length).toEqual(templateFiles.length);

for (const templateFile of templateFiles) {
expect(dirFiles.includes(templateFile)).toBe(true);
}

const pkgJson = require(path.join(DIR, 'TestApp', 'package.json'));
expect(pkgJson).toMatchObject({
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"react-native": "^0.60.0"
},
"devDependencies": {
"snapshot-diff": "^0.5.0"
"snapshot-diff": "^0.5.0",
"slash": "^3.0.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import os from 'os';
import path from 'path';
import fs from 'fs-extra';
import snapshotDiff from 'snapshot-diff';
import slash from 'slash';
import walk from '../../../tools/walk';
import copyFiles from '../../../tools/copyFiles';
import {changePlaceholderInTemplate} from '../editTemplate';
Expand Down Expand Up @@ -80,6 +81,8 @@ test('should edit template', () => {
snapshotDiff(oldJavaFile, newJavaFile, {contextLines: 1}),
).toMatchSnapshot();
expect(
snapshotDiff(fixtureTree, transformedTree, {contextLines: 1}),
snapshotDiff(fixtureTree.map(slash), transformedTree.map(slash), {
contextLines: 1,
}),
).toMatchSnapshot();
});
4 changes: 4 additions & 0 deletions packages/cli/src/commands/init/__tests__/templateName.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ const RN_NPM_PACKAGE = 'react-native';
const ABS_RN_PATH = '/path/to/react-native';

test('supports file protocol with absolute path', async () => {
if (process.platform === 'win32') {
console.warn('[SKIP] Jest virtual mocks seem to be broken on Windows');
return;
}
jest.mock(
`${ABS_RN_PATH}/package.json`,
() => ({
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/init/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async function setProjectDirectory(directory) {
throw new DirectoryAlreadyExistsError(directory);
}

await fs.emptyDir(directory);
fs.emptyDirSync(directory);
}

try {
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/src/commands/init/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import * as PackageManager from '../../tools/packageManager';
import {logger} from '@react-native-community/cli-tools';
import copyFiles from '../../tools/copyFiles';
import replacePathSepForRegex from '../../tools/replacePathSepForRegex';

export type TemplateConfig = {
placeholderName: string,
Expand Down Expand Up @@ -53,9 +54,9 @@ export async function copyTemplate(
);

logger.debug(`Copying template from ${templatePath}`);

let regexStr = path.resolve(templatePath, 'node_modules');
await copyFiles(templatePath, process.cwd(), {
exclude: [new RegExp(path.resolve(templatePath, 'node_modules'))],
exclude: [new RegExp(replacePathSepForRegex(regexStr))],
});
}

Expand Down
7 changes: 5 additions & 2 deletions packages/cli/src/commands/init/templateName.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ const VERSION_POSTFIX = /(.*)(-\d+\.\d+\.\d+)/;
const VERSIONED_PACKAGE = /(@?.+)(@)(.+)/;

function handleFileProtocol(filePath: string) {
const uri = new URL(filePath).pathname;

let uri = new URL(filePath).pathname;
if (process.platform === 'win32') {
// On Windows, the pathname has an extra leading / so remove that
uri = uri.substring(1);
}
return {
uri,
name: require(path.join(uri, 'package.json')).name,
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/src/tools/__tests__/copyFiles.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'fs';
import path from 'path';
import copyFiles from '../copyFiles';
import {cleanup, getTempDirectory} from '../../../../../jest/helpers';
import replacePathSepForRegex from '../replacePathSepForRegex';

const DIR = getTempDirectory('copyFiles-test');

Expand Down Expand Up @@ -47,10 +48,10 @@ test('copies text and binary files from source to destination', async () => {

test('copies files from source to destination excluding directory', async () => {
const src = path.resolve(__dirname, './__fixtures__');
let regexStr = path.join(src, 'extraDir');
await copyFiles(src, DIR, {
exclude: [new RegExp(path.join(src, 'extraDir'))],
exclude: [new RegExp(replacePathSepForRegex(regexStr))],
});

expect(fs.readdirSync(DIR)).toMatchInlineSnapshot(`
Array [
"binary.keystore",
Expand Down
44 changes: 28 additions & 16 deletions packages/cli/src/tools/config/__tests__/index-test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
/**
* @flow
*/

import path from 'path';
import slash from 'slash';
import loadConfig from '..';

import {logger} from '@react-native-community/cli-tools';
import {
cleanup,
writeFiles,
getTempDirectory,
} from '../../../../../../jest/helpers';

import {logger} from '@react-native-community/cli-tools';

jest.mock('../resolveNodeModuleDir');

const DIR = getTempDirectory('resolve_config_path_test');

// Removes string from all key/values within an object
const removeString = (config, str) =>
JSON.parse(
JSON.stringify(config).replace(new RegExp(str, 'g'), '<<REPLACED>>'),
JSON.stringify(config, (_key, value) =>
typeof value === 'string'
? slash(value.replace(str, '<<REPLACED>>'))
: value,
),
);

beforeEach(() => {
Expand Down Expand Up @@ -302,21 +305,30 @@ test('does not use restricted "react-native" key to resolve config from package.
});

test('supports dependencies from user configuration with custom root and properties', () => {
const escapePathSeparator = (value: string) =>
path.sep === '\\' ? value.replace(/(\/|\\)/g, '\\\\') : value;

writeFiles(DIR, {
'node_modules/react-native/package.json': '{}',
'native-libs/local-lib/ios/LocalRNLibrary.xcodeproj/project.pbxproj': '',
'react-native.config.js': `module.exports = {
dependencies: {
'local-lib': {
root: "${DIR}/native-libs/local-lib",
platforms: {
ios: {
podspecPath: "custom-path"
}
}
},
'react-native.config.js': `
const path = require('path');
const root = path.resolve('${escapePathSeparator(
DIR,
)}', 'native-libs', 'local-lib');

module.exports = {
dependencies: {
'local-lib': {
root,
platforms: {
ios: {
podspecPath: "custom-path"
}
}
}`,
},
}
}`,
'package.json': `{
"dependencies": {
"react-native": "0.0.1"
Expand Down
9 changes: 7 additions & 2 deletions packages/cli/src/tools/config/findAssets.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
import glob from 'glob';
import path from 'path';

const findAssetsInFolder = folder =>
glob.sync(path.join(folder, '**'), {nodir: true});
const findAssetsInFolder = folder => {
const assets = glob.sync(path.join(folder, '**'), {nodir: true});
if (process.platform === 'win32') {
return assets.map(asset => asset.split('/').join('\\'));
}
return assets;
};

/**
* Given an array of assets folders, e.g. ['Fonts', 'Images'],
Expand Down
12 changes: 12 additions & 0 deletions packages/cli/src/tools/replacePathSepForRegex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @flow
import path from 'path';

export default function replacePathSepForRegex(string: string) {
if (path.sep === '\\') {
return string.replace(
/(\/|(.)?\\(?![[\]{}()*+?.^$|\\]))/g,
(_match, _, p2) => (p2 && p2 !== '\\' ? p2 + '\\\\' : '\\\\'),
);
}
return string;
}