Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Upgrade stack #36

Merged
merged 1 commit into from
Nov 19, 2017
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
/lib
93 changes: 54 additions & 39 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,86 @@
module.exports = {
// So parent files don't get applied
root: true,
globals: {
preval: false,
},
env: {
es6: true,
browser: true,
node: true,
mocha: true,
},
extends: 'airbnb',
extends: ['plugin:import/recommended', 'airbnb'],
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 7,
sourceType: 'module',
},
plugins: [
'babel',
'mocha'
],
plugins: ['babel', 'import', 'jsx-a11y', 'mocha', 'prettier'],
rules: {
'array-bracket-spacing': 'off', // use babel plugin rule
'arrow-body-style': 'off',
'arrow-parens': ['error', 'always'], // airbnb use as-needed
'linebreak-style': 'off', // Don't play nicely with Windows.
'arrow-body-style': 'off', // Not our taste?
'arrow-parens': 'off', // Incompatible with prettier
'object-curly-newline': 'off', // Incompatible with prettier
'function-paren-newline': 'off', // Incompatible with prettier
indent: 'off', // Incompatible with prettier
'space-before-function-paren': 'off', // Incompatible with prettier
'no-mixed-operators': 'off', // Incompatible with prettier
'consistent-this': ['error', 'self'],
'max-len': ['error', 110], // airbnb use 100, wishlist, one day
'no-console': 'error', // airbnb is using warn
'no-param-reassign': 'off',
'no-prototype-builtins': 'off',
'max-len': [
'error',
100,
2,
{
ignoreUrls: true,
},
], // airbnb is allowing some edge cases
'no-console': 'off', // airbnb is using warn
'no-alert': 'error', // airbnb is using warn
'no-param-reassign': 'off', // Not our taste?
'no-prototype-builtins': 'off', // airbnb use error
'object-curly-spacing': 'off', // use babel plugin rule
'operator-linebreak': ['error', 'after'], // aibnb is disabling this rule
'no-restricted-properties': 'off', // To remove once react-docgen support ** operator.
'prefer-destructuring': 'off', // To remove once react-docgen support ** operator.

'babel/object-curly-spacing': ['error', 'always'],
'babel/array-bracket-spacing': ['error', 'never'],

'import/unambiguous': 'off', // scripts
'import/namespace': ['error', { allowComputed: true }],
'import/no-extraneous-dependencies': 'off',
'import/no-unresolved': 'off',
'import/no-named-as-default': 'off',
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
'import/prefer-default-export': 'off',
'react/jsx-handler-names': ['error', { // airbnb is disabling this rule
eventHandlerPrefix: 'handle',
eventHandlerPropPrefix: 'on',
}],

'react/jsx-indent': 'off', // Incompatible with prettier
'react/jsx-closing-bracket-location': 'off', // Incompatible with prettier
'react/jsx-wrap-multilines': 'off', // Incompatible with prettier
'react/jsx-indent-props': 'off', // Incompatible with prettier
'react/jsx-handler-names': [
'error',
{
// airbnb is disabling this rule
eventHandlerPrefix: 'handle',
eventHandlerPropPrefix: 'on',
},
],
'react/require-default-props': 'off', // airbnb use error
'react/forbid-prop-types': 'off', // airbnb use error
'react/jsx-filename-extension': ['error', {extensions: ['.js']}], // airbnb is using .jsx
'react/jsx-max-props-per-line': ['error', {maximum: 3}], // airbnb is disabling this rule
'react/jsx-filename-extension': ['error', { extensions: ['.js'] }], // airbnb is using .jsx
'react/no-danger': 'error', // airbnb is using warn
'react/no-direct-mutation-state': 'error', // airbnb is disabling this rule
'react/no-find-dom-node': 'warn', // wishlist, one day
'react/no-find-dom-node': 'off', // I don't know
'react/no-unused-prop-types': 'off', // Is still buggy
'react/sort-prop-types': 'error', // airbnb do nothing here.
'react/sort-comp': [2, {
order: [
'static-methods',
'lifecycle',
// 'properties', // not real -- NEEDS A PR!!!
// '/^handle.+$/', // wishlist -- needs above first
// '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/', // wishlist -- needs above first
'everything-else',
'/^render.+$/',
'render'
],
}],
'jsx-a11y/label-has-for': 'warn', // wishlist, one day
'react/default-props-match-prop-types': 'off', // Buggy
'react/jsx-curly-brace-presence': 'off', // Buggy
'react/jsx-no-bind': 'off', // Buggy

'mocha/handle-done-callback': 'error',
'mocha/no-exclusive-tests': 'error',
'mocha/no-global-tests': 'error',
'mocha/no-pending-tests': 'error',
'mocha/no-skipped-tests': 'error',

// Overrides
'no-console': 'off',
'prettier/prettier': ['error'],
},
};
12 changes: 2 additions & 10 deletions examples/polyglot.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import {
extractFromFiles,
findMissing,
findUnused,
findDuplicated,
flatten,
} from 'i18n-extract';
import { extractFromFiles, findMissing, findUnused, findDuplicated, flatten } from 'i18n-extract';
import frLocale from './src/locale/frLocale';

const frLocaleFlattened = flatten(frLocale);

const keys = extractFromFiles([
'src/**/*.js',
], {
const keys = extractFromFiles(['src/**/*.js'], {
marker: 'polyglot.t',
});

Expand Down
30 changes: 17 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
"main": "lib/index.js",
"scripts": {
"lint": "eslint . && echo \"eslint: no lint errors\"",
"test:unit": "babel-node test/unit.js",
"test": "npm run lint && npm run test:unit",
"test:unit": "mocha src/{,**/}*.spec.js",
"test:watch": "yarn test:unit -- -w",
"build": "rm -rf lib && mkdir lib && babel src --out-dir lib",
"prettier": "find . -name \"*.js\" | grep -v -f .eslintignore | xargs prettier --write",
"version": "npm run build && pkgfiles"
},
"repository": {
Expand All @@ -25,27 +27,29 @@
"author": "Olivier Tassinari <[email protected]> (https://github.com/oliviertassinari)",
"license": "MIT",
"dependencies": {
"babel-traverse": "^6.16.0",
"babylon": "^6.11.5",
"babel-traverse": "^6.26.0",
"babylon": "^6.18.0",
"gettext-parser": "^1.2.0",
"glob": "^7.1.1"
},
"devDependencies": {
"babel-cli": "^6.16.0",
"babel-eslint": "^7.0.0",
"babel-cli": "^6.26.0",
"babel-eslint": "^8.0.2",
"babel-preset-es2015": "^6.16.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
"chai": "^4.1.0",
"eslint": "^3.9.1",
"eslint-config-airbnb": "^13.0.0",
"chai": "^4.1.2",
"eslint": "^4.11.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-babel": "^4.0.0",
"eslint-plugin-import": "^2.1.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-mocha": "^4.7.0",
"eslint-plugin-react": "^6.6.0",
"mocha": "^3.1.2",
"pkgfiles": "^2.3.0"
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-react": "^7.5.0",
"mocha": "^4.0.1",
"pkgfiles": "^2.3.0",
"prettier": "^1.8.2"
},
"bugs": {
"url": "https://github.com/oliviertassinari/i18n-extract/issues"
Expand Down
9 changes: 9 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
printWidth: 100,
singleQuote: true,
trailingComma: 'all',
bracketSpacing: true,
jsxBracketSameLine: false,
parser: 'babylon',
semi: true,
};
38 changes: 11 additions & 27 deletions src/extractFromCode.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { parse } from 'babylon';
import traverse from 'babel-traverse';

const noInformationTypes = [
'CallExpression',
'Identifier',
'MemberExpression',
];
const noInformationTypes = ['CallExpression', 'Identifier', 'MemberExpression'];

function getKey(node) {
if (node.type === 'StringLiteral') {
return node.value;
} else if (node.type === 'BinaryExpression' && node.operator === '+') {
return getKey(node.left) + getKey(node.right);
} else if (node.type === 'TemplateLiteral') {
return node.quasis
.map((quasi) => quasi.value.cooked)
.join('*');
return node.quasis.map(quasi => quasi.value.cooked).join('*');
} else if (noInformationTypes.includes(node.type)) {
return '*'; // We can't extract anything.
}
Expand All @@ -29,10 +23,7 @@ const commentRegExp = /i18n-extract (.+)/;
const commentIgnoreRegExp = /i18n-extract-disable-line/;

export default function extractFromCode(code, options = {}) {
const {
marker = 'i18n',
keyLoc = 0,
} = options;
const { marker = 'i18n', keyLoc = 0 } = options;

const ast = parse(code, {
sourceType: 'module',
Expand Down Expand Up @@ -61,7 +52,7 @@ export default function extractFromCode(code, options = {}) {
const ignoredLines = [];

// Look for keys in the comments.
ast.comments.forEach((comment) => {
ast.comments.forEach(comment => {
let match = commentRegExp.exec(comment.value);
if (match) {
keys.push({
Expand All @@ -80,26 +71,19 @@ export default function extractFromCode(code, options = {}) {
// Look for keys in the source code.
traverse(ast, {
CallExpression(path) {
const {
node,
} = path;
const { node } = path;

if (ignoredLines.includes(node.loc.end.line)) {
// Skip ignored lines
return;
}

const {
callee: {
name,
type,
},
} = node;

if ((type === 'Identifier' && name === marker) ||
path.get('callee').matchesPattern(marker)) {
const key = getKey(keyLoc < 0 ? node.arguments[node.arguments.length + keyLoc] :
node.arguments[keyLoc]);
const { callee: { name, type } } = node;

if ((type === 'Identifier' && name === marker) || path.get('callee').matchesPattern(marker)) {
const key = getKey(
keyLoc < 0 ? node.arguments[node.arguments.length + keyLoc] : node.arguments[keyLoc],
);

if (key) {
keys.push({
Expand Down
Loading