Skip to content

Commit

Permalink
SSCCE for removeRange, replaceRangeBy
Browse files Browse the repository at this point in the history
  • Loading branch information
lue-bird committed Aug 12, 2023
0 parents commit 67516b2
Show file tree
Hide file tree
Showing 19 changed files with 929 additions and 0 deletions.
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/new-rule-idea.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: New rule idea
about: Propose a new rule idea
title: ''
labels: ''
assignees: ''
---

<!-- This template may feel a bit too structured, so feel free to change the sections if they do not fit your style. I think that these questions are useful to think about though!
Also the answer suggestions may feel a bit robotic, so definitely replace them with nice sentences.
Don't forget to be respectful, and to give enough details for others to pitch in or give advice. Don't fret if you can't figure all of these out though, we'll discover these together!
-->

**What the rule should do:**

**What problems does it solve:**

**Example of things the rule would report:**

```elm

```

**Example of things the rule would not report:**

```elm

```

**When (not) to enable this rule:**

<!-- It is useful to think when a rule would be especially valuable, and where it is counter-productive or just not useful.
-->

**I am looking for:**

<!--
- Feedback
- Tips and help on how to implement it
- Someone to implement it with/for me
-->

<!-- Thanks for writing all these helpful details. These are all useful details that you can use in the rule's documentation when you go implementing it, so this was definitely worth your investment.
-->
136 changes: 136 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: [push, pull_request]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
test:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- name: Setup Node.js environment
uses: actions/setup-node@v3
with:
node-version: lts/*

# Re-use node_modules between runs until package-lock.json changes.
- name: Cache node_modules
id: internal-cache-node_modules
uses: actions/cache@v3
with:
path: node_modules
key: internal-node_modules-ubuntu-latest.x-${{ hashFiles('package-lock.json') }}

# Re-use ~/.elm between runs until elm.json, elm-tooling.json or
# review/elm.json changes. The Elm compiler saves downloaded Elm packages
# to ~/.elm, and elm-tooling saves downloaded tool executables there.
- name: Cache ~/.elm
uses: actions/cache@v3
with:
path: ~/.elm
key: elm-${{ hashFiles('elm.json', 'elm-tooling.json', 'review/elm.json') }}

- name: Install npm dependencies
if: steps.cache-node_modules.outputs.cache-hit != 'true'
env:
# If you have a `"postinstall": "elm-tooling install"` script in your
# package.json, this turns it into a no-op. We’ll run it in the next
# step because of the caching. If elm-tooling.json changes but
# package-lock.json does not, the postinstall script needs running
# but this step won’t.
NO_ELM_TOOLING_INSTALL: 1
run: npm ci

# Install tools from elm-tooling.json, unless we restored them from
# cache. package-lock.json and elm-tooling.json can change independently,
# so we need to install separately based on what was restored from cache.
# This is run even if we restored ~/.elm from cache to be 100% sure
# node_modules/.bin/ contains links to all your tools. `elm-tooling
# install` runs very fast when there’s nothing new to download so
# skipping the step doesn’t save much time.
- name: elm-tooling install
run: npx --no-install elm-tooling install

- name: Run tests
run: npm test

publish:
needs: [test] # make sure all your other jobs succeed before trying to publish

# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3

- name: Setup Node.js environment
uses: actions/setup-node@v3
with:
node-version: lts/*

# Re-use node_modules between runs until package-lock.json changes.
- name: Cache node_modules
id: internal-cache-node_modules
uses: actions/cache@v3
with:
path: node_modules
key: internal-node_modules-ubuntu-latest.x-${{ hashFiles('package-lock.json') }}

# Re-use ~/.elm between runs until elm.json, elm-tooling.json or
# review/elm.json changes. The Elm compiler saves downloaded Elm packages
# to ~/.elm, and elm-tooling saves downloaded tool executables there.
- name: Cache ~/.elm
uses: actions/cache@v3
with:
path: ~/.elm
key: elm-${{ hashFiles('elm.json', 'elm-tooling.json', 'review/elm.json') }}

- name: Install npm dependencies
if: steps.cache-node_modules.outputs.cache-hit != 'true'
env:
# If you have a `"postinstall": "elm-tooling install"` script in your
# package.json, this turns it into a no-op. We’ll run it in the next
# step because of the caching. If elm-tooling.json changes but
# package-lock.json does not, the postinstall script needs running
# but this step won’t.
NO_ELM_TOOLING_INSTALL: 1
run: npm ci

# Install tools from elm-tooling.json, unless we restored them from
# cache. package-lock.json and elm-tooling.json can change independently,
# so we need to install separately based on what was restored from cache.
# This is run even if we restored ~/.elm from cache to be 100% sure
# node_modules/.bin/ contains links to all your tools. `elm-tooling
# install` runs very fast when there’s nothing new to download so
# skipping the step doesn’t save much time.
- name: elm-tooling install
run: npx --no-install elm-tooling install

- name: Check if package needs to be published
uses: dillonkearns/elm-publish-action@v1
id: publish
with:
dry-run: true
path-to-elm: ./node_modules/.bin/elm

- name: Check that examples are up to date
if: steps.publish.outputs.is-publishable == 'true'
run: node elm-review-package-tests/check-examples-were-updated.js

# Runs a single command using the runners shell
- name: Elm Publish
if: steps.publish.outputs.is-publishable == 'true'
uses: dillonkearns/elm-publish-action@v1
with:
# Token provided by GitHub
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-elm: ./node_modules/.bin/elm
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
elm-stuff/

# Editors
.idea/
ElmjutsuDumMyM0DuL3.elm
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# elm-review-sscce-negative-range

Provides the [`elm-review`](https://package.elm-lang.org/packages/jfmengels/elm-review/latest/) rule [`Sscce.NegativeRange`](https://package.elm-lang.org/packages/lue-bird/elm-review-sscce-negative-range/1.0.0/Sscce-NegativeRange) - SSCCE for elm-review behavior with negative ranges.

You can run the SSCCE with `elm-test`.
30 changes: 30 additions & 0 deletions elm-review-package-tests/check-examples-were-updated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env node

const Ansi = require('./helpers/ansi');
const {execSync} = require('child_process');
const updateExamplesFromPreview = require('../maintenance/update-examples-from-preview');

const preCheckGitStatus = execSync('git status --porcelain').toString().trim();
if (preCheckGitStatus !== '') {
console.error(
`${Ansi.red(
'✖'
)} Check aborted: There are uncommitted changes in the project.`
);
process.exit(1);
}

updateExamplesFromPreview();

const postCheckGitStatus = execSync('git status --porcelain').toString().trim();
if (postCheckGitStatus !== '') {
console.error('\u001B[31m✖\u001B[39m Your examples were not up to date.');
console.log(
`Please commit the changes I made. If you see this message from GitHub Actions, then run
${Ansi.yellow('node maintenance/update-examples-from-preview.js')}
to update your examples.`
);
process.exit(1);
}

process.exit(0);
113 changes: 113 additions & 0 deletions elm-review-package-tests/check-previews-compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env node

const path = require('path');
const Ansi = require('./helpers/ansi');
const {execSync} = require('child_process');
const {findPreviewConfigurations} = require('./helpers/find-configurations');
const packageDependencies = require('../elm.json').dependencies;

const root = path.dirname(__dirname);

// Find all elm.json files

findPreviewConfigurations().forEach(checkThatExampleCompiles);

function checkThatExampleCompiles(exampleConfiguration) {
const exampleConfigurationElmJson = require(`${exampleConfiguration}/elm.json`);

checkDepsAreCompatible(
path.basename(exampleConfiguration),
exampleConfigurationElmJson.dependencies.direct
);

try {
execSync(`npx elm-review --config ${exampleConfiguration} --report=json`, {
encoding: 'utf8',
stdio: 'pipe',
cwd: path.resolve(__dirname, '..')
}).toString();
success(exampleConfiguration);
} catch (error) {
try {
const output = JSON.parse(error.stdout);
// We don't care whether there were any reported errors.
// If the root type is not "error", then the configuration compiled
// successfully, which is all we care about in this test.
if (output.type !== 'review-errors') {
console.log(
`${Ansi.red('✖')} ${Ansi.yellow(
`${path.relative(root, exampleConfiguration)}/`
)} does not compile.`
);
console.log(
`Please run
${Ansi.yellow(`npx elm-review --config ${exampleConfiguration}/`)}
and make the necessary changes to make it compile.`
);
process.exit(1);
}

success(exampleConfiguration);
return;
} catch {
console.log(
`An error occurred while trying to check whether the ${Ansi.yellow(
path.relative(root, exampleConfiguration)
)} configuration compiles.`
);
console.error(error);
process.exit(1);
}
}
}

function success(config) {
console.log(`${Ansi.green('✔')} ${path.relative(root, config)}/ compiles`);
}

function checkDepsAreCompatible(exampleConfiguration, previewDependencies) {
Object.entries(packageDependencies).forEach(([depName, constraint]) => {
if (!(depName in previewDependencies)) {
console.error(
`Dependency ${depName} is missing in the ${exampleConfiguration}/ configuration`
);
process.exit(1);
}

checkConstraint(
exampleConfiguration,
depName,
constraint,
previewDependencies[depName]
);
delete previewDependencies[depName];
});

const remainingKeys = Object.keys(previewDependencies);
if (remainingKeys.length !== 0) {
console.error(
`There are extraneous dependencies in the ${exampleConfiguration}/ configuration: ${remainingKeys}`
);
process.exit(1);
}
}

function checkConstraint(exampleConfiguration, depName, constraint, version) {
const [minVersion] = constraint.split(' <= v < ').map(splitVersion);
const previewVersion = splitVersion(version);
const isValid =
previewVersion[0] === minVersion[0] &&
(previewVersion[1] > minVersion[1] ||
(previewVersion[1] === minVersion[1] &&
previewVersion[2] >= minVersion[2]));
if (!isValid) {
console.error(
`The constraint for ${depName} in ${exampleConfiguration}/ is not in the expected range. It was ${version} but it should be in ${constraint} to be in sync with the package's elm.json's dependencies.`
);
process.exit(1);
}
}

function splitVersion(version) {
return version.split('.').map((n) => Number.parseInt(n, 10));
}
17 changes: 17 additions & 0 deletions elm-review-package-tests/helpers/ansi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
red,
green,
yellow
};

function red(text) {
return '\u001B[31m' + text + '\u001B[39m';
}

function green(text) {
return '\u001B[32m' + text + '\u001B[39m';
}

function yellow(text) {
return '\u001B[33m' + text + '\u001B[39m';
}
20 changes: 20 additions & 0 deletions elm-review-package-tests/helpers/find-configurations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const path = require('path');
const glob = require('glob');

const root = path
.resolve(__dirname, '../../')
.replace(/.:/, '')
.replace(/\\/g, '/');

module.exports = {
findPreviewConfigurations
};

function findPreviewConfigurations() {
return glob
.sync(`${root}/preview*/**/elm.json`, {
ignore: ['**/elm-stuff/**'],
nodir: true
})
.map(path.dirname);
}
7 changes: 7 additions & 0 deletions elm-tooling.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tools": {
"elm": "0.19.1",
"elm-format": "0.8.7",
"elm-json": "0.2.13"
}
}
Loading

0 comments on commit 67516b2

Please sign in to comment.