@toptal/davinci-syntax 14.0.9-alpha-fx-try-engines-version-dependency.7 → 15.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +0 -10
- package/bin/davinci-syntax.js +0 -2
- package/dist-package/package.json +70 -0
- package/package.json +5 -6
- package/src/__tests__/__snapshots__/eslint.test.ts.snap +1144 -0
- package/src/__tests__/eslint.test.ts +347 -0
- package/src/__tests__/no-relative-packages.test.js +107 -0
- package/src/index.js +0 -2
- package/src/commands/init.js +0 -183
- package/src/configs/to-copy/root.editorconfig +0 -15
- package/src/configs/to-copy/root.eslintignore +0 -2
- package/src/configs/to-copy/root.eslintrc +0 -3
- package/src/configs/to-copy/root.prettierrc.js +0 -3
- package/src/configs/to-copy/root.stylelintrc +0 -3
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { ESLint, Linter } from 'eslint'
|
|
4
|
+
import json5 from 'json5'
|
|
5
|
+
|
|
6
|
+
const getConfig = () => {
|
|
7
|
+
const pathToEslintrc = path.join(__dirname, '../../src/configs/.eslintrc')
|
|
8
|
+
|
|
9
|
+
return new ESLint({
|
|
10
|
+
useEslintrc: false, // don't use any other eslintrc files (higher in the folder tree)
|
|
11
|
+
overrideConfigFile: pathToEslintrc, // use this exact eslintrc file
|
|
12
|
+
}).calculateConfigForFile(pathToEslintrc)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Eslint config file snapshot file to prevent unexpected updates
|
|
16
|
+
describe('eslint config', () => {
|
|
17
|
+
let fileConfig: Record<string, unknown>
|
|
18
|
+
|
|
19
|
+
beforeAll(async () => {
|
|
20
|
+
fileConfig = await getConfig()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('verifies eslint rules are not updated silently', () => {
|
|
24
|
+
const serializedRules = json5.stringify(fileConfig.rules, null, 2)
|
|
25
|
+
|
|
26
|
+
expect(serializedRules).toMatchSnapshot()
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
/* eslint-disable max-statements */
|
|
31
|
+
/* eslint-disable max-lines-per-function */
|
|
32
|
+
// Testing basic rules with the davinci eslint
|
|
33
|
+
describe('eslint rules', () => {
|
|
34
|
+
let engine: ESLint
|
|
35
|
+
|
|
36
|
+
beforeAll(async () => {
|
|
37
|
+
engine = new ESLint({ baseConfig: await getConfig() })
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const findMessage = (ruleId: string, results: ESLint.LintResult[]) => {
|
|
41
|
+
return results.reduce<Linter.LintMessage | undefined>(
|
|
42
|
+
(_, result) => result.messages.find(message => message.ruleId === ruleId),
|
|
43
|
+
undefined
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface TestRulesArgs {
|
|
48
|
+
ruleId: string
|
|
49
|
+
validCases?: string[]
|
|
50
|
+
invalidCases?: string[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const testRule = ({
|
|
54
|
+
ruleId,
|
|
55
|
+
validCases = [],
|
|
56
|
+
invalidCases = [],
|
|
57
|
+
}: TestRulesArgs) => {
|
|
58
|
+
it(`verifies that ${ruleId} works`, async () => {
|
|
59
|
+
for (const validText of validCases) {
|
|
60
|
+
const results = await engine.lintText(validText)
|
|
61
|
+
|
|
62
|
+
expect(findMessage(ruleId, results)).toBeUndefined()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (const invalidText of invalidCases) {
|
|
66
|
+
const results = await engine.lintText(invalidText)
|
|
67
|
+
|
|
68
|
+
expect(findMessage(ruleId, results)).toBeDefined()
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
testRule({
|
|
74
|
+
ruleId: '@typescript-eslint/space-before-function-paren',
|
|
75
|
+
invalidCases: [
|
|
76
|
+
'function withoutSpace (x) {}',
|
|
77
|
+
'var anonymousWithoutSpace = function() {};',
|
|
78
|
+
],
|
|
79
|
+
validCases: [
|
|
80
|
+
'function withoutSpace(x) {}',
|
|
81
|
+
'var anonymousWithoutSpace = function () {};',
|
|
82
|
+
'var anonymousWithoutSpace = function <T>() {};',
|
|
83
|
+
],
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
testRule({
|
|
87
|
+
ruleId: 'padding-line-between-statements',
|
|
88
|
+
invalidCases: [
|
|
89
|
+
`
|
|
90
|
+
function foo() {
|
|
91
|
+
bar();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
`,
|
|
95
|
+
],
|
|
96
|
+
validCases: [
|
|
97
|
+
`
|
|
98
|
+
function foo() {
|
|
99
|
+
bar();
|
|
100
|
+
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
`,
|
|
104
|
+
],
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
testRule({
|
|
108
|
+
ruleId: 'prefer-const',
|
|
109
|
+
invalidCases: [
|
|
110
|
+
`
|
|
111
|
+
let a = 3
|
|
112
|
+
console.log(a)
|
|
113
|
+
`,
|
|
114
|
+
],
|
|
115
|
+
validCases: [
|
|
116
|
+
`
|
|
117
|
+
let a = 3
|
|
118
|
+
a = 0
|
|
119
|
+
console.log(a)
|
|
120
|
+
`,
|
|
121
|
+
],
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
testRule({
|
|
125
|
+
ruleId: 'id-length',
|
|
126
|
+
invalidCases: ['const x = 5'],
|
|
127
|
+
validCases: [
|
|
128
|
+
'var ok = 5',
|
|
129
|
+
'const foo = { ok: 1 }',
|
|
130
|
+
`const _ = 'unused'`,
|
|
131
|
+
`
|
|
132
|
+
try {
|
|
133
|
+
throw new Error();
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error(e)
|
|
136
|
+
}
|
|
137
|
+
`,
|
|
138
|
+
],
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
testRule({
|
|
142
|
+
ruleId: 'quotes',
|
|
143
|
+
invalidCases: ['const foo = "bar"'],
|
|
144
|
+
validCases: [`const foo = 'bar'`],
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
testRule({
|
|
148
|
+
ruleId: 'no-else-return',
|
|
149
|
+
invalidCases: [
|
|
150
|
+
`
|
|
151
|
+
function foo() {
|
|
152
|
+
if (x) {
|
|
153
|
+
return y
|
|
154
|
+
} else {
|
|
155
|
+
return z
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
],
|
|
160
|
+
validCases: [
|
|
161
|
+
`
|
|
162
|
+
function foo() {
|
|
163
|
+
if (x) {
|
|
164
|
+
return y
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return z
|
|
168
|
+
}
|
|
169
|
+
`,
|
|
170
|
+
],
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
testRule({
|
|
174
|
+
ruleId: 'import/no-extraneous-dependencies',
|
|
175
|
+
invalidCases: [`import { ESLint } from 'eslint'`],
|
|
176
|
+
validCases: [`import fs from 'fs'`],
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
testRule({
|
|
180
|
+
ruleId: '@typescript-eslint/array-type',
|
|
181
|
+
invalidCases: [`const foo: Array<string> = ['a', 'b']`],
|
|
182
|
+
validCases: [`const foo: string[] = ['a', 'b']`],
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
testRule({
|
|
186
|
+
ruleId: '@typescript-eslint/array-type',
|
|
187
|
+
invalidCases: [`const foo: Array<string> = ['a', 'b']`],
|
|
188
|
+
validCases: [`const foo: string[] = ['a', 'b']`],
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
testRule({
|
|
192
|
+
ruleId: '@typescript-eslint/array-type',
|
|
193
|
+
invalidCases: [`const foo: Array<string> = ['a', 'b']`],
|
|
194
|
+
validCases: [`const foo: string[] = ['a', 'b']`],
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
testRule({
|
|
198
|
+
ruleId: '@typescript-eslint/explicit-function-return-type',
|
|
199
|
+
validCases: [`const foo = (): number => 1`, `const foo = () => 1`],
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
testRule({
|
|
203
|
+
ruleId: '@typescript-eslint/no-use-before-define',
|
|
204
|
+
invalidCases: [
|
|
205
|
+
`
|
|
206
|
+
foo()
|
|
207
|
+
|
|
208
|
+
const foo = () => {}
|
|
209
|
+
`,
|
|
210
|
+
],
|
|
211
|
+
validCases: [
|
|
212
|
+
`
|
|
213
|
+
const foo = () => {}
|
|
214
|
+
|
|
215
|
+
foo()
|
|
216
|
+
`,
|
|
217
|
+
],
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
testRule({
|
|
221
|
+
ruleId: '@typescript-eslint/no-unused-vars',
|
|
222
|
+
invalidCases: ['const foo = 1'],
|
|
223
|
+
validCases: [
|
|
224
|
+
`
|
|
225
|
+
const foo = 1
|
|
226
|
+
|
|
227
|
+
console.log(foo)
|
|
228
|
+
`,
|
|
229
|
+
],
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
testRule({
|
|
233
|
+
ruleId: '@typescript-eslint/func-call-spacing',
|
|
234
|
+
invalidCases: ['foo ()', 'foo<T> ()'],
|
|
235
|
+
validCases: ['foo()', 'foo<T>()'],
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
testRule({
|
|
239
|
+
ruleId: '@typescript-eslint/no-unused-expressions',
|
|
240
|
+
invalidCases: ['if (0) null'],
|
|
241
|
+
validCases: ['if (0) return null'],
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
testRule({
|
|
245
|
+
ruleId: '@typescript-eslint/ban-types',
|
|
246
|
+
invalidCases: [`const foo: String = 'foo'`, 'const foo: Number = 1'],
|
|
247
|
+
validCases: [
|
|
248
|
+
'const foo: Function = () => 1',
|
|
249
|
+
'const foo: object = {}',
|
|
250
|
+
'const foo: {} = {}',
|
|
251
|
+
],
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
testRule({
|
|
255
|
+
ruleId: 'func-style',
|
|
256
|
+
invalidCases: ['function foo() {}'],
|
|
257
|
+
validCases: ['const foo = function() {}'],
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
testRule({
|
|
261
|
+
ruleId: 'curly',
|
|
262
|
+
invalidCases: ['if (foo) foo++'],
|
|
263
|
+
validCases: ['if (foo) { foo++ }'],
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
testRule({
|
|
267
|
+
ruleId: 'todo-plz/ticket-ref',
|
|
268
|
+
invalidCases: [
|
|
269
|
+
'// TODO:',
|
|
270
|
+
'// TODO: lorem',
|
|
271
|
+
'// TODO :',
|
|
272
|
+
'// TODO: [FX-]',
|
|
273
|
+
'// TODO: [-000]',
|
|
274
|
+
'// TODO: [-AAA]',
|
|
275
|
+
'// TODO [FX-000]',
|
|
276
|
+
'// TODO:[FX-000]',
|
|
277
|
+
'// TODO: FX-000',
|
|
278
|
+
'// TODO: lorem FX-000 ipsum',
|
|
279
|
+
`/**
|
|
280
|
+
* TODO:
|
|
281
|
+
*/`,
|
|
282
|
+
`/**
|
|
283
|
+
* TODO: lorem
|
|
284
|
+
*/`,
|
|
285
|
+
],
|
|
286
|
+
validCases: [
|
|
287
|
+
'// TODO: [FX-000]',
|
|
288
|
+
'// TODO: [SPC-000]',
|
|
289
|
+
'// TODO: [FX-000] [SPC-000]',
|
|
290
|
+
'// TODO: [FX-000], [SPC-000]',
|
|
291
|
+
'// TODO: [FX-000], [SPC-000],',
|
|
292
|
+
'// TODO: [FX-000] [SPC-000],',
|
|
293
|
+
'// TODO: lorem [FX-000] [SPC-000],',
|
|
294
|
+
'// TODO: [FX-000] [SPC-000], lorem',
|
|
295
|
+
`/**
|
|
296
|
+
* TODO: [FX-000] lorem
|
|
297
|
+
*/`,
|
|
298
|
+
`/**
|
|
299
|
+
* TODO: lorem [FX-000] ipsum
|
|
300
|
+
*/`,
|
|
301
|
+
`/**
|
|
302
|
+
* TODO: lorem ipsum
|
|
303
|
+
* lorem [FX-000]
|
|
304
|
+
*/`,
|
|
305
|
+
`/**
|
|
306
|
+
* TODO: lorem ipsum
|
|
307
|
+
* [FX-000]
|
|
308
|
+
*/`,
|
|
309
|
+
],
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
testRule({
|
|
313
|
+
ruleId: 'unused-imports/no-unused-imports',
|
|
314
|
+
invalidCases: [
|
|
315
|
+
`import { unusedImport } from 'something'`,
|
|
316
|
+
`import { unusedImport1, unusedImport2 } from 'something'`,
|
|
317
|
+
],
|
|
318
|
+
validCases: [
|
|
319
|
+
`import { something } from 'something'
|
|
320
|
+
const c = something.usintThis()
|
|
321
|
+
`,
|
|
322
|
+
],
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
testRule({
|
|
326
|
+
ruleId: 'import/no-duplicates',
|
|
327
|
+
invalidCases: [
|
|
328
|
+
`import { component1 } from 'module1';
|
|
329
|
+
import { component2 } from 'module1';`,
|
|
330
|
+
`import component1 from 'module1';
|
|
331
|
+
import { component2 } from 'module1';`,
|
|
332
|
+
],
|
|
333
|
+
validCases: [
|
|
334
|
+
`import { component1, component2 } from 'module1';
|
|
335
|
+
import component3 from 'module2';`,
|
|
336
|
+
`import { component1 } from 'module';
|
|
337
|
+
import * as component2 from 'module';`,
|
|
338
|
+
`import { component1 } from 'module';
|
|
339
|
+
export { component2 } from 'module';`,
|
|
340
|
+
`import { component1, component2 } from 'module';
|
|
341
|
+
export * as component3 from 'module';
|
|
342
|
+
export * from 'module';`,
|
|
343
|
+
`import component1, * as component2 from './module'
|
|
344
|
+
import type componentType1 from './module'`,
|
|
345
|
+
],
|
|
346
|
+
})
|
|
347
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import rule from 'eslint-plugin-import/lib/rules/no-relative-packages'
|
|
4
|
+
|
|
5
|
+
const testFilePath = relativePath =>
|
|
6
|
+
path.join(__dirname, '/eslint-package-structure', relativePath)
|
|
7
|
+
|
|
8
|
+
const FILENAME = testFilePath('foo.js')
|
|
9
|
+
|
|
10
|
+
const testRule = options => ({
|
|
11
|
+
filename: FILENAME,
|
|
12
|
+
parserOptions: {
|
|
13
|
+
sourceType: 'module',
|
|
14
|
+
ecmaVersion: 9,
|
|
15
|
+
...options.parserOptions,
|
|
16
|
+
},
|
|
17
|
+
...options,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const ruleTester = new RuleTester()
|
|
21
|
+
|
|
22
|
+
ruleTester.run('no-relative-packages', rule, {
|
|
23
|
+
valid: [
|
|
24
|
+
testRule({
|
|
25
|
+
code: 'import foo from "./index.js"',
|
|
26
|
+
filename: testFilePath('./package/index.js'),
|
|
27
|
+
}),
|
|
28
|
+
/**
|
|
29
|
+
* Unfortunately, this case is considered valid for the rule,
|
|
30
|
+
* but we cannot influence this. This case should be considered invalid.
|
|
31
|
+
*
|
|
32
|
+
* testRule({
|
|
33
|
+
* code: 'import bar from "../bar"',
|
|
34
|
+
* filename: testFilePath('./package/index.js')
|
|
35
|
+
* }),
|
|
36
|
+
*/
|
|
37
|
+
testRule({
|
|
38
|
+
code: 'import { foo } from "a"',
|
|
39
|
+
filename: testFilePath('./package-named/index.js'),
|
|
40
|
+
}),
|
|
41
|
+
testRule({
|
|
42
|
+
code: 'const bar = require("../bar.js")',
|
|
43
|
+
filename: testFilePath('./package/index.js'),
|
|
44
|
+
}),
|
|
45
|
+
testRule({
|
|
46
|
+
code: 'import "package"',
|
|
47
|
+
filename: testFilePath('./package/index.js'),
|
|
48
|
+
}),
|
|
49
|
+
testRule({
|
|
50
|
+
code: 'require("../bar.js")',
|
|
51
|
+
filename: testFilePath('./package/index.js'),
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
invalid: [
|
|
55
|
+
testRule({
|
|
56
|
+
code: 'import foo from "./package-named"',
|
|
57
|
+
filename: testFilePath('./bar.js'),
|
|
58
|
+
errors: [
|
|
59
|
+
{
|
|
60
|
+
message:
|
|
61
|
+
'Relative import from another package is not allowed. Use `package-named` instead of `./package-named`',
|
|
62
|
+
line: 1,
|
|
63
|
+
column: 17,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
output: 'import foo from "package-named"',
|
|
67
|
+
}),
|
|
68
|
+
testRule({
|
|
69
|
+
code: 'import foo from "../package-named"',
|
|
70
|
+
filename: testFilePath('./package/index.js'),
|
|
71
|
+
errors: [
|
|
72
|
+
{
|
|
73
|
+
message:
|
|
74
|
+
'Relative import from another package is not allowed. Use `package-named` instead of `../package-named`',
|
|
75
|
+
line: 1,
|
|
76
|
+
column: 17,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
output: 'import foo from "package-named"',
|
|
80
|
+
}),
|
|
81
|
+
testRule({
|
|
82
|
+
code: 'import foo from "../package-scoped"',
|
|
83
|
+
filename: testFilePath('./package/index.js'),
|
|
84
|
+
errors: [
|
|
85
|
+
{
|
|
86
|
+
message: `Relative import from another package is not allowed. Use \`@scope/package-named\` instead of \`../package-scoped\``,
|
|
87
|
+
line: 1,
|
|
88
|
+
column: 17,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
output: 'import foo from "@scope/package-named"',
|
|
92
|
+
}),
|
|
93
|
+
testRule({
|
|
94
|
+
code: 'import bar from "../bar"',
|
|
95
|
+
filename: testFilePath('./package-named/index.js'),
|
|
96
|
+
errors: [
|
|
97
|
+
{
|
|
98
|
+
message: `Relative import from another package is not allowed. Use \`@toptal/davinci-syntax/src/__tests__/eslint-package-structure/bar\` instead of \`../bar\``,
|
|
99
|
+
line: 1,
|
|
100
|
+
column: 17,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
output:
|
|
104
|
+
'import bar from "@toptal/davinci-syntax/src/__tests__/eslint-package-structure/bar"',
|
|
105
|
+
}),
|
|
106
|
+
],
|
|
107
|
+
})
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
const initCommandCreator = require('./commands/init')
|
|
2
1
|
const lintCodeCommandCreator = require('./commands/lint-code')
|
|
3
2
|
const lintStylesCommandCreator = require('./commands/lint-styles')
|
|
4
3
|
const lintDirsCommandCreator = require('./commands/lint-dirs')
|
|
5
4
|
|
|
6
5
|
module.exports = {
|
|
7
6
|
commands: [
|
|
8
|
-
initCommandCreator,
|
|
9
7
|
lintCodeCommandCreator,
|
|
10
8
|
lintStylesCommandCreator,
|
|
11
9
|
lintDirsCommandCreator,
|
package/src/commands/init.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { print, prompt } = require('@toptal/davinci-cli-shared')
|
|
4
|
-
|
|
5
|
-
const copyConfigFile = async ({
|
|
6
|
-
copyFromFile,
|
|
7
|
-
copyToFile,
|
|
8
|
-
promptName,
|
|
9
|
-
promptText,
|
|
10
|
-
}) => {
|
|
11
|
-
if (fs.existsSync(copyToFile)) {
|
|
12
|
-
const shouldRewrite = await prompt.confirm(promptName, promptText)
|
|
13
|
-
|
|
14
|
-
if (!shouldRewrite) {
|
|
15
|
-
return
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
fs.copyFileSync(copyFromFile, copyToFile)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const copyLintConfigFile = (rootDir, currentRunningDir) => {
|
|
23
|
-
return copyConfigFile({
|
|
24
|
-
copyFromFile: path.join(rootDir, './src/configs/to-copy/root.eslintrc'),
|
|
25
|
-
copyToFile: path.join(currentRunningDir, './.eslintrc'),
|
|
26
|
-
promptName: 'eslintrc',
|
|
27
|
-
promptText: 'Do you want to override your existing .eslintrc file?',
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const copyLintIgnoreFile = (rootDir, currentRunningDir) => {
|
|
32
|
-
return copyConfigFile({
|
|
33
|
-
copyFromFile: path.join(rootDir, './src/configs/to-copy/root.eslintignore'),
|
|
34
|
-
copyToFile: path.join(currentRunningDir, './.eslintignore'),
|
|
35
|
-
promptName: 'eslintignore',
|
|
36
|
-
promptText: 'Do you want to override your existing .eslintignore file?',
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const copyPrettierConfigFile = (rootDir, currentRunningDir) => {
|
|
41
|
-
return copyConfigFile({
|
|
42
|
-
copyFromFile: path.join(
|
|
43
|
-
rootDir,
|
|
44
|
-
'./src/configs/to-copy/root.prettierrc.js'
|
|
45
|
-
),
|
|
46
|
-
copyToFile: path.join(currentRunningDir, './.prettierrc.js'),
|
|
47
|
-
promptName: 'prettierrc',
|
|
48
|
-
promptText: 'Do you want to override your existing .prettierrc.js file?',
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const copyEditorConfigFile = (rootDir, currentRunningDir) => {
|
|
53
|
-
return copyConfigFile({
|
|
54
|
-
copyFromFile: path.join(rootDir, './src/configs/to-copy/root.editorconfig'),
|
|
55
|
-
copyToFile: path.join(currentRunningDir, './.editorconfig'),
|
|
56
|
-
promptName: 'editorconfig',
|
|
57
|
-
promptText: 'Do you want to override your existing .editorconfig file?',
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const copyStylelintConfigFile = (rootDir, currentRunningDir) => {
|
|
62
|
-
return copyConfigFile({
|
|
63
|
-
copyFromFile: path.join(rootDir, './src/configs/to-copy/root.stylelintrc'),
|
|
64
|
-
copyToFile: path.join(currentRunningDir, './.stylelintrc'),
|
|
65
|
-
promptName: 'stylelintrc',
|
|
66
|
-
promptText: 'Do you want to override your existing .stylelintrc file?',
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const checkPackageJsonExists = currentRunningDir => {
|
|
71
|
-
const packageJsonFile = path.join(currentRunningDir, './package.json')
|
|
72
|
-
|
|
73
|
-
if (!fs.existsSync(packageJsonFile)) {
|
|
74
|
-
print.red(
|
|
75
|
-
'You should run `npm init` in your repo before running davinci-syntax init.'
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
return false
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return true
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const addLintCommands = async currentRunningDir => {
|
|
85
|
-
const packageJsonFile = path.join(currentRunningDir, './package.json')
|
|
86
|
-
|
|
87
|
-
const configData = fs.readFileSync(packageJsonFile)
|
|
88
|
-
const config = JSON.parse(configData)
|
|
89
|
-
|
|
90
|
-
const lintCommand = config.scripts && config.scripts.lint
|
|
91
|
-
|
|
92
|
-
if (lintCommand) {
|
|
93
|
-
const shouldRewrite = await prompt.confirm(
|
|
94
|
-
'lintCommand',
|
|
95
|
-
'You have already a lint command in you package.json. Do you want to override it?'
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
if (!shouldRewrite) {
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// add scripts lint command
|
|
104
|
-
config.scripts.lint =
|
|
105
|
-
'davinci-syntax lint code . && davinci-syntax lint styles .'
|
|
106
|
-
|
|
107
|
-
const modifiedConfigData = JSON.stringify(config, null, 2).concat('\n')
|
|
108
|
-
|
|
109
|
-
fs.writeFileSync(packageJsonFile, modifiedConfigData)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const addLintStagedCommands = async currentRunningDir => {
|
|
113
|
-
const packageJsonFile = path.join(currentRunningDir, './package.json')
|
|
114
|
-
|
|
115
|
-
const configData = fs.readFileSync(packageJsonFile)
|
|
116
|
-
const config = JSON.parse(configData)
|
|
117
|
-
|
|
118
|
-
const lintStagedCommand = config.husky || config['lint-staged']
|
|
119
|
-
|
|
120
|
-
if (lintStagedCommand) {
|
|
121
|
-
const shouldRewrite = await prompt.confirm(
|
|
122
|
-
'lintStagedCommand',
|
|
123
|
-
'You have already a husky or lint-staged in you package.json. Do you want still to override them?'
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
if (!shouldRewrite) {
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// add lint-staged
|
|
132
|
-
config['lint-staged'] = {
|
|
133
|
-
'*.{js,jsx,ts,tsx}': ['davinci-syntax lint code', 'prettier', 'git add'],
|
|
134
|
-
'styles.{js,jsx,ts,tsx}': [
|
|
135
|
-
'davinci syntax lint styles',
|
|
136
|
-
'prettier',
|
|
137
|
-
'git add',
|
|
138
|
-
],
|
|
139
|
-
}
|
|
140
|
-
// add husky
|
|
141
|
-
config.husky = {
|
|
142
|
-
hooks: {
|
|
143
|
-
'pre-commit': 'lint-staged',
|
|
144
|
-
},
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const modifiedConfigData = JSON.stringify(config, null, 2).concat('\n')
|
|
148
|
-
|
|
149
|
-
fs.writeFileSync(packageJsonFile, modifiedConfigData)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const initCommand = async () => {
|
|
153
|
-
print.green('Initializing syntax package...')
|
|
154
|
-
|
|
155
|
-
const currentRunningDir = process.cwd()
|
|
156
|
-
const rootDir = path.join(__dirname, '../..')
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
await copyLintConfigFile(rootDir, currentRunningDir)
|
|
160
|
-
await copyLintIgnoreFile(rootDir, currentRunningDir)
|
|
161
|
-
await copyPrettierConfigFile(rootDir, currentRunningDir)
|
|
162
|
-
await copyStylelintConfigFile(rootDir, currentRunningDir)
|
|
163
|
-
await copyEditorConfigFile(rootDir, currentRunningDir)
|
|
164
|
-
|
|
165
|
-
if (checkPackageJsonExists(currentRunningDir)) {
|
|
166
|
-
await addLintCommands(currentRunningDir)
|
|
167
|
-
await addLintStagedCommands(currentRunningDir)
|
|
168
|
-
}
|
|
169
|
-
} finally {
|
|
170
|
-
// eslint-disable-next-line
|
|
171
|
-
console.log('Done.')
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const initCommandCreator = {
|
|
176
|
-
action: () => {
|
|
177
|
-
initCommand()
|
|
178
|
-
},
|
|
179
|
-
command: 'init',
|
|
180
|
-
description: 'Init the syntax package',
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
module.exports = initCommandCreator
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# top-most EditorConfig file
|
|
2
|
-
root = true
|
|
3
|
-
|
|
4
|
-
# Unix-style newlines with a newline ending every file
|
|
5
|
-
[*]
|
|
6
|
-
end_of_line = lf
|
|
7
|
-
insert_final_newline = true
|
|
8
|
-
|
|
9
|
-
# Consistent 2 space indentation
|
|
10
|
-
[*]
|
|
11
|
-
indent_style = space
|
|
12
|
-
indent_size = 2
|
|
13
|
-
|
|
14
|
-
[*.ejs.t]
|
|
15
|
-
insert_final_newline = false
|