Vasili's Blog

eslint

At work we are using Contentful as a headless CMS, and also Adobe DAM as an asset storage platform. Both platforms support localization, but we only want to have it enabled in the DAM as that makes the digital production team's life easier.

However some Contentful models ended up having linked DAM assets fields set to localized: true, which means that the content editor team now needs to link the asset essentially twice, so that's not good.

How do we ensure, that all new changes to the Contentful schema are not going to suffer from the same problem?

ESLint no-restricted-syntax rule to the rescue.

Essentially a migration looks like this

function(migration) {
  migration
    .createContentType("coolImageStorage")
    .createField("coolImage", {
      type: "Link",
      linkType: "Entry",
      localized: true, // <- here's what we want to avoid
      validations: [{ linkContentType: "damAsset" }]
    })
}

A following rule can detect when a field is created as a damAsset link, and also has localized set to true.

CallExpression:has(Property[key.name=localized][value.value=true]) Property[key.name=linkContentType]:has(Literal[value=damAsset])

Wire it up into the .eslintrc file as follows:

{
  "rules": {
    "no-restricted-syntax": ["error", {
      "selector": "CallExpression:has(Property[key.name=localized][value.value=true]) Property[key.name=linkContentType]:has(Literal[value=damAsset])",
    "message": "DAM Asset should not be localized"
    }]
  }
}

and marvel at how technology is sometimes able to save us from ourselves.

AST Explorer with babel-eslint parser and ESLint v8 transform can help you poke around at the AST to figure out how to wire up these rules.

#eslint #contentful #astexplorer

Everybody has a love/hate relationship with ESLint. It guides you in the right ways of code, but it also nags you with all of those mundane asks...

So, sometimes you switch things to “warn”, to be generally appraised of what's happening with a Scout's Honour promise to “fix it later”. Pinky swear. And then the whole thing gets wired up to CI and you never really see those warnings ever again. Once you see that green checkmark of a passing stage – why bother going in and reading console output, right?

Well, we can make GitLab soft-fail a stage. It will not break the build, but it'll show that nagging Yellow Exclamation Mark of Concern.

Sadly there's no command-line option for eslint to say: “exit with a non-successful status code in case there are only warnings”, so we have to improvise.

jq to the rescue (once we manage to crawl though its obtuse syntax).

lint:report_warnings:
  stage: lint
  allow_failure: true
  script:
    - apk add --update --no-cache jq
    - eslint . -f json | jq 'map(.warningCount) | add | if(.>0) then halt_error(5) else halt_error(0) end'

This runs eslint, producing a JSON output where we sum all the warning counts and bail out with an error code if there are any.

Technically we can set the allow_fail to permit only specific status codes.

allow_failure:
  status_codes:
    - 5

I couldn't get it to work naively though. But this works too. You have a stage that soft-fails on warnings.

#gitlab #ci #eslint