Page MenuHomePhabricator

[monorepo] eslint all the js with a single version-pinned flat config
ClosedPublic

Authored by bytesofman on Wed, Mar 5, 18:32.

Details

Summary

All of the js sub-repos in the monorepo have their own lint settings. For eslint before 9, this was best practice. It is difficult to find a "one size fits all" lint approach for JS, since nodejs has different rules from vanilla js, react has its own special rules, the browser has different globals vs node, different test engines also have different globals, different standards have different syntax, some repos have a good reason to use multiple standards, etc.

We want all js to be linted. And we want there to be a maintainable and as-standardized-as-possible approach.

With eslint 9, the "flat config" is introduced which allows a single config file to handle various rulesets across a monorepo. We implement this approach here, deleting all legacy lint settings (many of which were never implemented in arc lint).

We correct all lint issues discovered by this implementation now that arc lint is picking everything up.

Test Plan

CI for all lint changes

arc lint --everything brings up unrelated py and c++ changes that are not easy to back out of this diff and probably related to my local linter settings. Test plan for JS-only impacts.

arc lint -- cashtab/*
arc lint -- modules/**/*
arc lint -- apps/**/*
arc lint -- web/**/*

Event Timeline

Tail of the build log:

5 vulnerabilities (4 moderate, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

> ecash-agora@2.0.0 build
> tsc && tsc -p ./tsconfig.build.json

/work/cashtab /work/abc-ci-builds/cashtab-tests
npm warn deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm warn deprecated @humanwhocodes/config-array@0.11.14: Use @eslint/config-array instead
npm warn deprecated eslint@8.56.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 1403 packages, and audited 3180 packages in 23s

274 packages are looking for funding
  run `npm fund` for details

9 vulnerabilities (8 moderate, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> cashtab@3.17.4 build
> node scripts/build.js

node:internal/modules/cjs/loader:1228
  throw err;
  ^

Error: Cannot find module 'eslint-webpack-plugin'
Require stack:
- /work/cashtab/config/webpack.config.js
- /work/cashtab/scripts/build.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1225:15)
    at Module._load (node:internal/modules/cjs/loader:1051:27)
    at Module.require (node:internal/modules/cjs/loader:1311:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (/work/cashtab/config/webpack.config.js:21:22)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Module.require (node:internal/modules/cjs/loader:1311:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/work/cashtab/config/webpack.config.js',
    '/work/cashtab/scripts/build.js'
  ]
}

Node.js v20.18.3
Build cashtab-tests failed with exit code 1

dep back in, improve exclusions in arclint

Tail of the build log:

5 vulnerabilities (4 moderate, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

> ecash-agora@2.0.0 build
> tsc && tsc -p ./tsconfig.build.json

/work/cashtab /work/abc-ci-builds/cashtab-tests
npm warn deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm warn deprecated @humanwhocodes/config-array@0.11.14: Use @eslint/config-array instead
npm warn deprecated eslint@8.56.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 1406 packages, and audited 2846 packages in 24s

274 packages are looking for funding
  run `npm fund` for details

9 vulnerabilities (8 moderate, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> cashtab@3.17.4 build
> node scripts/build.js

node:internal/modules/cjs/loader:1228
  throw err;
  ^

Error: Cannot find module 'eslint-config-react-app/base'
Require stack:
- /work/cashtab/config/webpack.config.js
- /work/cashtab/scripts/build.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1225:15)
    at Function.resolve (node:internal/modules/helpers:190:19)
    at module.exports (/work/cashtab/config/webpack.config.js:787:37)
    at Object.<anonymous> (/work/cashtab/scripts/build.js:54:16)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:173:12)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/work/cashtab/config/webpack.config.js',
    '/work/cashtab/scripts/build.js'
  ]
}

Node.js v20.18.3
Build cashtab-tests failed with exit code 1

disable eslint plugin for webpack build

emack requested changes to this revision.Thu, Mar 6, 07:21
emack added a subscriber: emack.

/modules/chronik-client/.prettierignore and /.prettierignore be removed as it's similar to .eslintignore

On another note, I'm getting the following from arc lint --everything

image.png (245×1 px, 37 KB)

However, arc lint on the cashtab folder runs fine, which doesn't seem to be a local issue?

image.png (55×512 px, 9 KB)

This revision now requires changes to proceed.Thu, Mar 6, 07:21

/modules/chronik-client/.prettierignore and /.prettierignore be removed as it's similar to .eslintignore

On another note, I'm getting the following from arc lint --everything

image.png (245×1 px, 37 KB)

However, arc lint on the cashtab folder runs fine, which doesn't seem to be a local issue?

image.png (55×512 px, 9 KB)

arc lint on the cashtab folder is the same as arc lint anywhere else: it lints the current commit.

Regarding the mypy issue, what are your mypy and python versions ?

/modules/chronik-client/.prettierignore and /.prettierignore be removed as it's similar to .eslintignore

On another note, I'm getting the following from arc lint --everything

image.png (245×1 px, 37 KB)

However, arc lint on the cashtab folder runs fine, which doesn't seem to be a local issue?

image.png (55×512 px, 9 KB)

will leave these for now as this commit focuses on eslint only

will do another commit to bump the prettier version / standardize prettier rules ... even then tho, we may end up keeping local .prettierignore files. afaik prettier does not have this same "flat config" monorepo-friendly option like eslint.

Regarding the mypy issue, what are your mypy and python versions ?

mypy is 1.10.0 which meets the mypy>=0.910 requirement from the contributing doc
python3 is 3.10.12

patch py lint issue (handled in separate diff), exclude src/ which has .ts files that are not typescript

running arc lint --everything and taking some autofixes

backing out unrelated autofixes from arc lint everything

Tail of the build log:

      data: "abc"
    }
  }
}
time_first_seen: 1741325024
size: 178
])
2025-03-07T05:23:45.109000Z TestFramework (INFO): Stopping nodes
2025-03-07T05:23:45.311000Z TestFramework (WARNING): Not cleaning up dir /work/abc-ci-builds/chronik-client-integration-tests/test/tmp/test_runner_₿₵_🏃_20250307_052340/setup_scripts/chronik-client_plugins_0
2025-03-07T05:23:45.312000Z TestFramework (ERROR): Test failed. Test logging available at /work/abc-ci-builds/chronik-client-integration-tests/test/tmp/test_runner_₿₵_🏃_20250307_052340/setup_scripts/chronik-client_plugins_0/test_framework.log
2025-03-07T05:23:45.312000Z TestFramework (ERROR): 
2025-03-07T05:23:45.312000Z TestFramework (ERROR): Hint: Call /work/test/functional/combine_logs.py '/work/abc-ci-builds/chronik-client-integration-tests/test/tmp/test_runner_₿₵_🏃_20250307_052340/setup_scripts/chronik-client_plugins_0' to consolidate all logs
2025-03-07T05:23:45.312000Z TestFramework (ERROR): 
2025-03-07T05:23:45.313000Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.
2025-03-07T05:23:45.313000Z TestFramework (ERROR): https://github.com/Bitcoin-ABC/bitcoin-abc/issues
2025-03-07T05:23:45.313000Z TestFramework (ERROR): 
Running Unit Tests for Test Framework Modules
setup_scripts/chronik-client_plugins.py started
setup_scripts/chronik-client_plugins.py failed, Duration: 4 s

stdout:

stderr:


TEST                                    | STATUS    | DURATION

setup_scripts/chronik-client_plugins.py | ✖ Failed  | 4 s

ALL                                     | ✖ Failed  | 4 s (accumulated) 
Runtime: 4 s

Test runner for chronik-client_plugins completed with code 1
----------------------|---------|----------|---------|---------|------------------------------------
File                  | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s                  
----------------------|---------|----------|---------|---------|------------------------------------
All files             |   31.16 |    12.27 |   28.39 |   31.13 |                                    
 chronik-client       |     100 |      100 |     100 |     100 |                                    
  index.ts            |     100 |      100 |     100 |     100 |                                    
 chronik-client/proto |   23.53 |     9.16 |   17.05 |   23.74 |                                    
  chronik.ts          |   23.53 |     9.16 |   17.05 |   23.74 | ...4,6520-6523,6529-6571,6607-6616 
 chronik-client/src   |   67.21 |    49.38 |   65.41 |   66.48 |                                    
  ChronikClient.ts    |   60.38 |    48.69 |   63.63 |   60.38 | ...6,1357-1365,1373-1438,1446-1451 
  failoverProxy.ts    |   79.43 |    56.66 |   69.23 |   78.84 | ...282-285,288,297,304,308,313,317 
  hex.ts              |   89.47 |       50 |      75 |   87.87 | 58,66-68                           
  validation.ts       |    75.6 |       40 |      75 |   72.97 | 17,21,33,38-49,62-63               
----------------------|---------|----------|---------|---------|------------------------------------

##teamcity[blockOpened name='Code Coverage Summary']
##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='988']
##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='3170']
##teamcity[buildStatisticValue key='CodeCoverageAbsRCovered' value='257']
##teamcity[buildStatisticValue key='CodeCoverageAbsRTotal' value='2094']
##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='161']
##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='567']
##teamcity[buildStatisticValue key='CodeCoverageAbsLCovered' value='976']
##teamcity[buildStatisticValue key='CodeCoverageAbsLTotal' value='3135']
##teamcity[blockClosed name='Code Coverage Summary']
mv: cannot stat 'test_results/chronik-client-integration-tests-junit.xml': No such file or directory
Build chronik-client-integration-tests failed with exit code 1

newlines to back out unrelated autofixes

newline net.cpp to back out unrelated autofix

actually back out the changes in net.cpp

Tail of the build log:

  ecash_lib_wasm_bg_browser.js |       0 |      100 |     100 |       0 | 1                         
  ecash_lib_wasm_browser.js    |       0 |        0 |       0 |       0 | 3-681                     
  ecash_lib_wasm_nodejs.js     |       0 |        0 |       0 |       0 | 1-611                     
 src                           |   30.06 |    25.52 |   27.27 |   50.96 |                           
  consts.ts                    |       0 |      100 |     100 |       0 | 6-8                       
  ecc.ts                       |   13.11 |     62.5 |    8.51 |    25.8 | 54-90,110-118,131-167     
  hash.ts                      |   41.46 |    83.33 |   26.66 |   80.95 | 26,35,38,41               
  hdwallet.ts                  |       0 |        0 |       0 |       0 | 12-176                    
  hmac.ts                      |       0 |        0 |       0 |       0 | 16-73                     
  index.ts                     |       0 |        0 |       0 |       0 |                           
  indexBrowser.ts              |       0 |        0 |       0 |       0 |                           
  indexNodeJs.ts               |       0 |        0 |       0 |       0 |                           
  initBrowser.ts               |       0 |      100 |       0 |       0 | 11-17                     
  initNodeJs.ts                |   54.54 |      100 |     100 |      80 | 10                        
  mnemonic.ts                  |       0 |        0 |       0 |       0 | 9-144                     
  op.ts                        |   20.13 |    23.33 |   36.36 |   39.47 | ...09,111,119-124,135-163 
  opcode.ts                    |    50.2 |    83.33 |     100 |     100 | 1                         
  pbkdf2.ts                    |       0 |      100 |       0 |       0 | 17-51                     
  script.ts                    |   28.44 |    20.58 |   29.03 |   50.87 | ...33-144,150,160,182-193 
  sigHashType.ts               |      40 |       25 |   46.15 |   78.94 | 26-38                     
  tx.ts                        |   47.25 |    45.23 |   47.61 |   87.23 | 110,114,123-125,144       
  txBuilder.ts                 |   40.74 |    33.92 |   54.54 |   80.43 | ...62,181-186,191,261-265 
  unsignedTx.ts                |   25.27 |       16 |   30.76 |   46.15 | ...12,320,326-329,345,357 
 src/address                   |   11.35 |    15.15 |    5.12 |   22.41 |                           
  address.ts                   |   10.95 |    11.36 |    3.22 |   21.05 | ...39-240,255-256,266-344 
  legacyaddr.ts                |   12.04 |    22.72 |    12.5 |      25 | ...9,23-38,70-111,124-128 
 src/ffi                       |   14.37 |    12.87 |    8.25 |   14.54 |                           
  ecash_lib_wasm_bg_browser.js |       0 |      100 |     100 |       0 | 1                         
  ecash_lib_wasm_browser.js    |       0 |        0 |       0 |       0 | 3-681                     
  ecash_lib_wasm_nodejs.js     |    29.9 |    36.11 |   17.64 |   30.09 | ...19,526-591,597-598,602 
 src/io                        |   30.79 |    41.17 |   39.06 |   59.55 |                           
  bytes.ts                     |    8.19 |       60 |   11.76 |   16.12 | 12,23-74                  
  hex.ts                       |   41.55 |       50 |   44.44 |   82.35 | 41-45,50,58               
  int.ts                       |       0 |        0 |       0 |       0 |                           
  str.ts                       |   46.15 |    83.33 |      40 |   85.71 | 15                        
  varsize.ts                   |   16.32 |    21.05 |      40 |      32 | 14-24,40-47               
  writer.ts                    |       0 |        0 |       0 |       0 |                           
  writerbytes.ts               |   42.62 |    40.62 |   53.33 |   83.87 | 34,44,54,64,80            
  writerlength.ts              |   53.33 |    83.33 |   53.84 |     100 | 1                         
 src/test                      |   46.05 |    37.68 |      50 |   89.04 |                           
  testRunner.ts                |   46.05 |    37.68 |      50 |   89.04 | 66-68,81-82,105,114,157   
 src/token                     |   45.48 |    43.96 |      50 |   87.07 |                           
  alp.ts                       |    42.5 |    53.12 |   43.47 |   82.92 | 110-123,142               
  common.ts                    |   54.54 |    83.33 |     100 |     100 | 1                         
  empp.ts                      |   52.17 |       60 |   57.14 |   91.66 | 12                        
  slp.ts                       |   46.97 |    33.82 |      52 |   89.74 | ...61,167,175,178,197,202 
-------------------------------|---------|----------|---------|---------|---------------------------

##teamcity[blockOpened name='Code Coverage Summary']
##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='865']
##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='3773']
##teamcity[buildStatisticValue key='CodeCoverageAbsRCovered' value='263']
##teamcity[buildStatisticValue key='CodeCoverageAbsRTotal' value='1029']
##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='144']
##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='642']
##teamcity[buildStatisticValue key='CodeCoverageAbsLCovered' value='844']
##teamcity[buildStatisticValue key='CodeCoverageAbsLTotal' value='2649']
##teamcity[blockClosed name='Code Coverage Summary']
mv: cannot stat 'test_results/ecash-lib-integration-tests-junit.xml': No such file or directory
Build ecash-lib-integration-tests failed with exit code 1

Failed tests logs:

====== CashTab Unit Tests: <Token /> available actions rendered We can redeem XECX for XEC 1:1 using a workflow unique to XECX ======
Error: expect(element).toBeDisabled()

Received element is not disabled:
  <button class="sc-caSCKo sc-kjoXOD DHATx" style="margin-top: 12px;" />
    at Object.toBeDisabled (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:1985:30)

Each failure log is accessible here:
CashTab Unit Tests: <Token /> available actions rendered We can redeem XECX for XEC 1:1 using a workflow unique to XECX

Failed tests logs:

====== CashTab Unit Tests: <Token /> available actions rendered We can redeem XECX for XEC 1:1 using a workflow unique to XECX ======
Error: expect(element).toBeDisabled()

Received element is not disabled:
  <button class="sc-caSCKo sc-kjoXOD DHATx" style="margin-top: 12px;" />
    at Object.toBeDisabled (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:1985:30)

Each failure log is accessible here:
CashTab Unit Tests: <Token /> available actions rendered We can redeem XECX for XEC 1:1 using a workflow unique to XECX

This is failing on a regular basis, you should investigate

Fabien requested changes to this revision.Fri, Mar 7, 10:51
Fabien added inline comments.
.arclint
315

This should not be necessary because it should already be in the .gitignore

316

dito

317

dito

320

ok, but why ? (can be done in another diff)

cashtab/src/components/Etokens/CreateTokenForm/index.tsx
427

Don't show the raw exception to the user. First most people can't understand it, and it might leak sensitive information.

cashtab/src/config/CashtabCache.ts
53

Do you have to repeat this? I would expect it to be implicit since it's part of the interface

cashtab/src/config/CashtabState.ts
28

Same question

eslint.config.mjs
51

Dito, all these should be in the .gitignore already

modules/ecash-lib/src/ecc.ts
102

Likely this should not be exported and renamed to EccImpl or something like that.
Ok to do this in a follow up as it's outside the scope of this diff.

modules/ecash-lib/src/hdwallet.ts
142

Same this could be easily fixed instead in a follow up

modules/ecash-lib/src/op.ts
37

That's a false positive ?

modules/ecashaddrjs/src/base32.ts
4

You can't just remove the copyright notice like that. If some of this code is from Emilio Almansi then keep the line. Same for the below date, you can't change that

modules/ecashaddrjs/src/cashaddr.ts
4

dito

modules/ecashaddrjs/src/validation.ts
4

dito

modules/ecashaddrjs/test/base32.test.ts
4

dito

modules/ecashaddrjs/test/cashaddr.test.ts
4

dito

modules/ecashaddrjs/test/convertBits.test.ts
4

dito

This revision now requires changes to proceed.Fri, Mar 7, 10:51
bytesofman marked 17 inline comments as done.

preserve attribution headers in ecashaddrjs, keep ignores in the top-level .gitignore

Fabien added inline comments.
.gitignore
96 ↗(On Diff #52965)
bytesofman added inline comments.
.arclint
320

the thinking here was

  • the explorer JS was not linted before
  • the explorer JS has yet another set of specific rules that will need to be worked out and implemented
  • the explorer JS has never been linted so I anticipate a lot of lint-related changes

so yes -- best in another diff related to just the explorer

.gitignore
96 ↗(On Diff #52965)

resolved

cashtab/src/config/CashtabCache.ts
53

it's a ts linter rule

the rule itself -- we need to explicitly keep the interface name distinct from the class -- makes sense. Prevents confusion between the two if we mean one or the other.

When it's implemented, everything in the class throws ts lint errors unless all the types are specified again like so. It does seem pretty silly but I don't know how to keep the linter rule without this.

cashtab/src/config/CashtabState.ts
28

ditto

modules/ecash-lib/src/ecc.ts
102

yes -- I made an attempt at doing this trivially like the Cashtab stuff -- but Ecc is a sui generis thing due to the wasm. I couldn't get it to work. Will need some focused attention to clean this up, or possibly the implementation has to be this way for wasm reasons.

modules/ecash-lib/src/hdwallet.ts
142

I didn't understand the lint fix for this, which required a bit of a code refactor. But yes, should be addressed in its own diff.

modules/ecash-lib/src/op.ts
37

the lint fix for this one was not that bad but complicated enough that I thought "prob does not belong in a lint-only diff"

it doesn't like using .hasOwnProperty on the any-typed input. It's fixable but it is a bit of a refactor for this function.

This revision is now accepted and ready to land.Sat, Mar 8, 04:37