summaryrefslogtreecommitdiffstats
path: root/front/odiparpack/internals/scripts
diff options
context:
space:
mode:
authorDayana31 <[email protected]>2022-04-21 17:27:08 -0500
committerDayana31 <[email protected]>2022-04-21 17:27:08 -0500
commit67c50667678dd0ce4709b29a854f6a47093a1ac5 (patch)
treeb6f9f39092ad54bf6b815984d32b37d7c7ca67ab /front/odiparpack/internals/scripts
parent91140b24f0d49a9f89a080ee063e9eb023a4b73a (diff)
parente13e630cd6e4fc0b1ff92098a28a770794c7bb9a (diff)
downloadDP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.tar.gz
DP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.tar.bz2
DP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.zip
Merge branch 'gabshr' into dayana
Diffstat (limited to 'front/odiparpack/internals/scripts')
-rw-r--r--front/odiparpack/internals/scripts/analyze.js27
-rw-r--r--front/odiparpack/internals/scripts/clean.js63
-rw-r--r--front/odiparpack/internals/scripts/dependencies.js52
-rw-r--r--front/odiparpack/internals/scripts/extract-intl.js187
-rw-r--r--front/odiparpack/internals/scripts/generate-templates-for-linting.js119
-rw-r--r--front/odiparpack/internals/scripts/helpers/checkmark.js11
-rw-r--r--front/odiparpack/internals/scripts/helpers/progress.js25
-rw-r--r--front/odiparpack/internals/scripts/helpers/xmark.js11
-rw-r--r--front/odiparpack/internals/scripts/npmcheckversion.js8
9 files changed, 503 insertions, 0 deletions
diff --git a/front/odiparpack/internals/scripts/analyze.js b/front/odiparpack/internals/scripts/analyze.js
new file mode 100644
index 0000000..2144e5a
--- /dev/null
+++ b/front/odiparpack/internals/scripts/analyze.js
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+
+const shelljs = require('shelljs');
+const animateProgress = require('./helpers/progress');
+const chalk = require('chalk');
+const addCheckMark = require('./helpers/checkmark');
+
+const progress = animateProgress('Generating stats');
+
+// Generate stats.json file with webpack
+shelljs.exec(
+ 'webpack --config internals/webpack/webpack.prod.babel.js --profile --json > stats.json',
+ addCheckMark.bind(null, callback), // Output a checkmark on completion
+);
+
+// Called after webpack has finished generating the stats.json file
+function callback() {
+ clearInterval(progress);
+ process.stdout.write(
+ '\n\nOpen ' +
+ chalk.magenta('http://webpack.github.io/analyse/') +
+ ' in your browser and upload the stats.json file!' +
+ chalk.blue(
+ '\n(Tip: ' + chalk.italic('CMD + double-click') + ' the link!)\n\n',
+ ),
+ );
+}
diff --git a/front/odiparpack/internals/scripts/clean.js b/front/odiparpack/internals/scripts/clean.js
new file mode 100644
index 0000000..52a93e0
--- /dev/null
+++ b/front/odiparpack/internals/scripts/clean.js
@@ -0,0 +1,63 @@
+const shell = require('shelljs');
+const addCheckMark = require('./helpers/checkmark.js');
+
+if (!shell.which('git')) {
+ shell.echo('Sorry, this script requires git');
+ shell.exit(1);
+}
+
+if (!shell.test('-e', 'internals/templates')) {
+ shell.echo('The example is deleted already.');
+ shell.exit(1);
+}
+
+process.stdout.write('Cleanup started...');
+
+// Reuse existing LanguageProvider and i18n tests
+shell.mv(
+ 'app/containers/LanguageProvider/tests',
+ 'internals/templates/containers/LanguageProvider',
+);
+shell.cp('app/tests/i18n.test.js', 'internals/templates/tests/i18n.test.js');
+
+// Cleanup components/
+shell.rm('-rf', 'app/components/*');
+
+// Handle containers/
+shell.rm('-rf', 'app/containers');
+shell.mv('internals/templates/containers', 'app');
+
+// Handle tests/
+shell.mv('internals/templates/tests', 'app');
+
+// Handle translations/
+shell.rm('-rf', 'app/translations');
+shell.mv('internals/templates/translations', 'app');
+
+// Handle utils/
+shell.rm('-rf', 'app/utils');
+shell.mv('internals/templates/utils', 'app');
+
+// Replace the files in the root app/ folder
+shell.cp('internals/templates/app.js', 'app/app.js');
+shell.cp('internals/templates/global-styles.js', 'app/global-styles.js');
+shell.cp('internals/templates/i18n.js', 'app/i18n.js');
+shell.cp('internals/templates/index.html', 'app/index.html');
+shell.cp('internals/templates/reducers.js', 'app/reducers.js');
+shell.cp('internals/templates/configureStore.js', 'app/configureStore.js');
+
+// Remove the templates folder
+shell.rm('-rf', 'internals/templates');
+
+addCheckMark();
+
+// Commit the changes
+if (
+ shell.exec('git add . --all && git commit -qm "Remove default example"')
+ .code !== 0
+) {
+ shell.echo('\nError: Git commit failed');
+ shell.exit(1);
+}
+
+shell.echo('\nCleanup done. Happy Coding!!!');
diff --git a/front/odiparpack/internals/scripts/dependencies.js b/front/odiparpack/internals/scripts/dependencies.js
new file mode 100644
index 0000000..4f9f1ed
--- /dev/null
+++ b/front/odiparpack/internals/scripts/dependencies.js
@@ -0,0 +1,52 @@
+// No need to build the DLL in production
+if (process.env.NODE_ENV === 'production') {
+ process.exit(0);
+}
+
+require('shelljs/global');
+
+const path = require('path');
+const fs = require('fs');
+const exists = fs.existsSync;
+const writeFile = fs.writeFileSync;
+
+const defaults = require('lodash/defaultsDeep');
+const pkg = require(path.join(process.cwd(), 'package.json'));
+const config = require('../config');
+const dllConfig = defaults(pkg.dllPlugin, config.dllPlugin.defaults);
+const outputPath = path.join(process.cwd(), dllConfig.path);
+const dllManifestPath = path.join(outputPath, 'package.json');
+
+/**
+ * I use node_modules/react-boilerplate-dlls by default just because
+ * it isn't going to be version controlled and babel wont try to parse it.
+ */
+mkdir('-p', outputPath);
+
+echo('Building the Webpack DLL...');
+
+/**
+ * Create a manifest so npm install doesn't warn us
+ */
+if (!exists(dllManifestPath)) {
+ writeFile(
+ dllManifestPath,
+ JSON.stringify(
+ defaults({
+ name: 'react-boilerplate-dlls',
+ private: true,
+ author: pkg.author,
+ repository: pkg.repository,
+ version: pkg.version,
+ }),
+ null,
+ 2,
+ ),
+ 'utf8',
+ );
+}
+
+// the BUILDING_DLL env var is set to avoid confusing the development environment
+exec(
+ 'cross-env BUILDING_DLL=true webpack --display-chunks --color --config internals/webpack/webpack.dll.babel.js --hide-modules',
+);
diff --git a/front/odiparpack/internals/scripts/extract-intl.js b/front/odiparpack/internals/scripts/extract-intl.js
new file mode 100644
index 0000000..087b04e
--- /dev/null
+++ b/front/odiparpack/internals/scripts/extract-intl.js
@@ -0,0 +1,187 @@
+/* eslint-disable */
+/**
+ * This script will extract the internationalization messages from all components
+ and package them in the translation json files in the translations file.
+ */
+const fs = require('fs');
+const nodeGlob = require('glob');
+const transform = require('babel-core').transform;
+
+const animateProgress = require('./helpers/progress');
+const addCheckmark = require('./helpers/checkmark');
+
+const pkg = require('../../package.json');
+const presets = pkg.babel.presets;
+const plugins = pkg.babel.plugins || [];
+
+const i18n = require('../../app/i18n');
+
+const DEFAULT_LOCALE = i18n.DEFAULT_LOCALE;
+
+require('shelljs/global');
+
+// Glob to match all js files except test files
+const FILES_TO_PARSE = 'app/**/!(*.test).js';
+const locales = i18n.appLocales;
+
+const newLine = () => process.stdout.write('\n');
+
+// Progress Logger
+let progress;
+const task = message => {
+ progress = animateProgress(message);
+ process.stdout.write(message);
+
+ return error => {
+ if (error) {
+ process.stderr.write(error);
+ }
+ clearTimeout(progress);
+ return addCheckmark(() => newLine());
+ };
+};
+
+// Wrap async functions below into a promise
+const glob = pattern =>
+ new Promise((resolve, reject) => {
+ nodeGlob(
+ pattern,
+ (error, value) => (error ? reject(error) : resolve(value)),
+ );
+ });
+
+const readFile = fileName =>
+ new Promise((resolve, reject) => {
+ fs.readFile(
+ fileName,
+ (error, value) => (error ? reject(error) : resolve(value)),
+ );
+ });
+
+const writeFile = (fileName, data) =>
+ new Promise((resolve, reject) => {
+ fs.writeFile(
+ fileName,
+ data,
+ (error, value) => (error ? reject(error) : resolve(value)),
+ );
+ });
+
+// Store existing translations into memory
+const oldLocaleMappings = [];
+const localeMappings = [];
+
+// Loop to run once per locale
+for (const locale of locales) {
+ oldLocaleMappings[locale] = {};
+ localeMappings[locale] = {};
+ // File to store translation messages into
+ const translationFileName = `app/translations/${locale}.json`;
+ try {
+ // Parse the old translation message JSON files
+ const messages = JSON.parse(fs.readFileSync(translationFileName));
+ const messageKeys = Object.keys(messages);
+ for (const messageKey of messageKeys) {
+ oldLocaleMappings[locale][messageKey] = messages[messageKey];
+ }
+ } catch (error) {
+ if (error.code !== 'ENOENT') {
+ process.stderr.write(
+ `There was an error loading this translation file: ${translationFileName}
+ \n${error}`,
+ );
+ }
+ }
+}
+
+/* push `react-intl` plugin to the existing plugins that are already configured in `package.json`
+ Example:
+ ```
+ "babel": {
+ "plugins": [
+ ["transform-object-rest-spread", { "useBuiltIns": true }]
+ ],
+ "presets": [
+ "env",
+ "react"
+ ]
+ }
+ ```
+*/
+plugins.push(['react-intl']);
+
+const extractFromFile = fileName => {
+ return readFile(fileName)
+ .then(code => {
+ // Use babel plugin to extract instances where react-intl is used
+ const { metadata: result } = transform(code, { presets, plugins });
+
+ for (const message of result['react-intl'].messages) {
+ for (const locale of locales) {
+ const oldLocaleMapping = oldLocaleMappings[locale][message.id];
+ // Merge old translations into the babel extracted instances where react-intl is used
+ const newMsg =
+ locale === DEFAULT_LOCALE ? message.defaultMessage : '';
+ localeMappings[locale][message.id] = oldLocaleMapping
+ ? oldLocaleMapping
+ : newMsg;
+ }
+ }
+ })
+ .catch(error => {
+ process.stderr.write(`Error transforming file: ${fileName}\n${error}`);
+ });
+};
+
+const memoryTask = glob(FILES_TO_PARSE);
+const memoryTaskDone = task('Storing language files in memory');
+
+memoryTask.then(files => {
+ memoryTaskDone();
+
+ const extractTask = Promise.all(
+ files.map(fileName => extractFromFile(fileName)),
+ );
+ const extractTaskDone = task('Run extraction on all files');
+ // Run extraction on all files that match the glob on line 16
+ extractTask.then(result => {
+ extractTaskDone();
+
+ // Make the directory if it doesn't exist, especially for first run
+ mkdir('-p', 'app/translations');
+
+ let localeTaskDone;
+ let translationFileName;
+
+ for (const locale of locales) {
+ translationFileName = `app/translations/${locale}.json`;
+ localeTaskDone = task(
+ `Writing translation messages for ${locale} to: ${translationFileName}`,
+ );
+
+ // Sort the translation JSON file so that git diffing is easier
+ // Otherwise the translation messages will jump around every time we extract
+ let messages = {};
+ Object.keys(localeMappings[locale])
+ .sort()
+ .forEach(function(key) {
+ messages[key] = localeMappings[locale][key];
+ });
+
+ // Write to file the JSON representation of the translation messages
+ const prettified = `${JSON.stringify(messages, null, 2)}\n`;
+
+ try {
+ fs.writeFileSync(translationFileName, prettified);
+ localeTaskDone();
+ } catch (error) {
+ localeTaskDone(
+ `There was an error saving this translation file: ${translationFileName}
+ \n${error}`,
+ );
+ }
+ }
+
+ process.exit();
+ });
+});
diff --git a/front/odiparpack/internals/scripts/generate-templates-for-linting.js b/front/odiparpack/internals/scripts/generate-templates-for-linting.js
new file mode 100644
index 0000000..cb3904a
--- /dev/null
+++ b/front/odiparpack/internals/scripts/generate-templates-for-linting.js
@@ -0,0 +1,119 @@
+/**
+ * This script is for internal `react-boilerplate`'s usage. The only purpose of generating all of these templates is
+ * to be able to lint them and detect critical errors. Every generated component's name has to start with
+ * 'RbGenerated' so it can be easily excluded from the test coverage reports.
+ */
+
+const nodePlop = require('node-plop');
+const path = require('path');
+const chalk = require('chalk');
+const rimraf = require('rimraf');
+
+const xmark = require('./helpers/xmark');
+
+process.chdir(path.join(__dirname, '../generators'));
+
+const prettyStringify = data => JSON.stringify(data, null, 2);
+
+const checkForErrors = result => {
+ if (Array.isArray(result.failures) && result.failures.length > 0) {
+ throw result.failures;
+ }
+};
+
+const reportErrorsFor = title => err => {
+ // TODO Replace with our own helpers/log that is guaranteed to be blocking?
+ xmark(() =>
+ console.error(
+ chalk.red(` ERROR generating '${title}': `),
+ prettyStringify(err),
+ ),
+ );
+ process.exit(1);
+};
+
+// Generated tests are designed to fail, which would in turn fail CI builds
+const removeTestsDirFrom = relativePath => () =>
+ rimraf.sync(path.join(__dirname, '/../../app/', relativePath, '/tests'));
+
+const plop = nodePlop('./index.js');
+
+const componentGen = plop.getGenerator('component');
+componentGen
+ .runActions({
+ name: 'RbGeneratedComponentEsclass',
+ type: 'React.Component',
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('components/RbGeneratedComponentEsclass'))
+ .catch(reportErrorsFor('component/React.Component'));
+
+componentGen
+ .runActions({
+ name: 'RbGeneratedComponentEsclasspure',
+ type: 'React.PureComponent',
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('components/RbGeneratedComponentEsclasspure'))
+ .catch(reportErrorsFor('component/React.PureComponent'));
+
+componentGen
+ .runActions({
+ name: 'RbGeneratedComponentStatelessfunction',
+ type: 'Stateless Function',
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('components/RbGeneratedComponentStatelessfunction'))
+ .catch(reportErrorsFor('component/Stateless Function'));
+
+const containerGen = plop.getGenerator('container');
+containerGen
+ .runActions({
+ name: 'RbGeneratedContainerPureComponent',
+ type: 'React.PureComponent',
+ wantHeaders: true,
+ wantActionsAndReducer: true,
+ wantSagas: true,
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('containers/RbGeneratedContainerPureComponent'))
+ .catch(reportErrorsFor('container/React.PureComponent'));
+
+containerGen
+ .runActions({
+ name: 'RbGeneratedContainerComponent',
+ type: 'React.Component',
+ wantHeaders: true,
+ wantActionsAndReducer: true,
+ wantSagas: true,
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('containers/RbGeneratedContainerComponent'))
+ .catch(reportErrorsFor('container/React.Component'));
+
+containerGen
+ .runActions({
+ name: 'RbGeneratedContainerStateless',
+ type: 'Stateless Function',
+ wantHeaders: true,
+ wantActionsAndReducer: true,
+ wantSagas: true,
+ wantMessages: true,
+ wantLoadable: true,
+ })
+ .then(checkForErrors)
+ .then(removeTestsDirFrom('containers/RbGeneratedContainerStateless'))
+ .catch(reportErrorsFor('container/Stateless'));
+
+const languageGen = plop.getGenerator('language');
+languageGen.runActions({ language: 'fr' }).catch(reportErrorsFor('language'));
diff --git a/front/odiparpack/internals/scripts/helpers/checkmark.js b/front/odiparpack/internals/scripts/helpers/checkmark.js
new file mode 100644
index 0000000..ac30dbc
--- /dev/null
+++ b/front/odiparpack/internals/scripts/helpers/checkmark.js
@@ -0,0 +1,11 @@
+const chalk = require('chalk');
+
+/**
+ * Adds mark check symbol
+ */
+function addCheckMark(callback) {
+ process.stdout.write(chalk.green(' ✓'));
+ if (callback) callback();
+}
+
+module.exports = addCheckMark;
diff --git a/front/odiparpack/internals/scripts/helpers/progress.js b/front/odiparpack/internals/scripts/helpers/progress.js
new file mode 100644
index 0000000..4353f20
--- /dev/null
+++ b/front/odiparpack/internals/scripts/helpers/progress.js
@@ -0,0 +1,25 @@
+'use strict';
+
+const readline = require('readline');
+
+/**
+ * Adds an animated progress indicator
+ *
+ * @param {string} message The message to write next to the indicator
+ * @param {number} amountOfDots The amount of dots you want to animate
+ */
+function animateProgress(message, amountOfDots) {
+ if (typeof amountOfDots !== 'number') {
+ amountOfDots = 3;
+ }
+
+ let i = 0;
+ return setInterval(function() {
+ readline.cursorTo(process.stdout, 0);
+ i = (i + 1) % (amountOfDots + 1);
+ const dots = new Array(i + 1).join('.');
+ process.stdout.write(message + dots);
+ }, 500);
+}
+
+module.exports = animateProgress;
diff --git a/front/odiparpack/internals/scripts/helpers/xmark.js b/front/odiparpack/internals/scripts/helpers/xmark.js
new file mode 100644
index 0000000..59d137d
--- /dev/null
+++ b/front/odiparpack/internals/scripts/helpers/xmark.js
@@ -0,0 +1,11 @@
+const chalk = require('chalk');
+
+/**
+ * Adds mark cross symbol
+ */
+function addXMark(callback) {
+ process.stdout.write(chalk.red(' ✘'));
+ if (callback) callback();
+}
+
+module.exports = addXMark;
diff --git a/front/odiparpack/internals/scripts/npmcheckversion.js b/front/odiparpack/internals/scripts/npmcheckversion.js
new file mode 100644
index 0000000..e3ecd0c
--- /dev/null
+++ b/front/odiparpack/internals/scripts/npmcheckversion.js
@@ -0,0 +1,8 @@
+const exec = require('child_process').exec;
+exec('npm -v', function(err, stdout, stderr) {
+ if (err) throw err;
+ if (parseFloat(stdout) < 3) {
+ throw new Error('[ERROR: React Boilerplate] You need npm version @>=3');
+ process.exit(1);
+ }
+});