Skip to content

Commit

Permalink
Merge pull request #19 from philips-forks/feature/add-file-or-directo…
Browse files Browse the repository at this point in the history
…ry-exists-rule

Add file-or-directory-existence rule
  • Loading branch information
drgs authored Sep 12, 2022
2 parents 22c89e3 + 0e0152a commit 1421fa5
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 1 deletion.
11 changes: 11 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Below is a complete list of rules that Repolinter can run, along with their conf
- [`license-detectable-by-licensee`](#license-detectable-by-licensee)
- [`best-practices-badge-present`](#best-practices-badge-present)
- [`any-file-contents`](#any-file-contents)
- [`file-or-directory-existence`](#file-or-directory-existence)

## Reference

Expand Down Expand Up @@ -218,3 +219,13 @@ Checks if the contents of at least one file in a given list match a given regula
| `flags` | No | `string` | `""` | The flags to use for the regular expression in `content` (ex. `"i"` for case insensitivity). |
| `human-readable-content` | No | `string` | The regular expression in `content` | The string to print instead of the regular expression when generating human-readable output. |
| `fail-on-non-existent` | No | `boolean` | `false` | Set to `true` to disable passing if no files are found from `globsAll`. |

### `file-or-directory-existence`

Checks the existence of a given file OR directory.

| Input | Required | Type | Default | Description |
| -------------- | -------- | ---------- | ------- | -------------------------------------------------------------------------------------------------- |
| `globsAny` | **Yes** | `string[]` | | A list of globs to search for. This rule passes if at least one glob returns a file or directory. |
| `nocase` | No | `boolean` | `false` | Set to `true` to perform an case insensitive search. |
| `fail-message` | No | `string` | `""` | The string to print if file or directory does not exist, used to create human-readable error messages. |
20 changes: 20 additions & 0 deletions rules/file-or-directory-existence-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://raw.githubusercontent.com/todogroup/repolinter/master/rules/file-or-directory-existence-config.json",
"type": "object",
"properties": {
"nocase": {
"type": "boolean",
"default": false
},
"globsAny": {
"type": "array",
"items": { "type": "string" }
},
"fail-message": { "type": "string" }
},
"oneOf": [
{ "required": ["globsAny"] }
]
}

39 changes: 39 additions & 0 deletions rules/file-or-directory-existence.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2017 TODO Group. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

const Result = require('../lib/result')

async function fileOrDirectoryExistence(fs, options) {
const fileOrDirectoryExists = await fs.findFirst(
options.globsAny,
options.nocase
)

const passed = !!fileOrDirectoryExists

return passed
? new Result(
'',
[
{
passed: true,
path: fileOrDirectoryExists,
message: 'Found file or directory matching the specified patterns'
}
],
true
)
: new Result(
`${
options['fail-message'] !== undefined
? options['fail-message'] + '. '
: ''
}Did not find a file or directory matching the specified patterns`,
options.globsAny.map(f => {
return { passed: false, pattern: f }
}),
false
)
}

module.exports = fileOrDirectoryExistence
3 changes: 2 additions & 1 deletion rules/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ module.exports = [
'git-working-tree',
'license-detectable-by-licensee',
'json-schema-passes',
'any-file-contents'
'any-file-contents',
'file-or-directory-existence'
]
12 changes: 12 additions & 0 deletions rulesets/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@
}
}
}
},
{
"if": {
"properties": { "type": { "const": "file-or-directory-existence" } }
},
"then": {
"properties": {
"options": {
"$ref": "../rules/file-or-directory-existence-config.json"
}
}
}
}
]
},
Expand Down
107 changes: 107 additions & 0 deletions tests/rules/file_or_directory_existence_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2017 TODO Group. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

const chai = require('chai')
const path = require('path')
const FileSystem = require('../../lib/file_system')

const expect = chai.expect

describe('rule', () => {
describe('file_or_directory_existence', () => {
const fileOrDirectoryExistence = require('../../rules/file-existence')
const fs = new FileSystem(path.resolve('./tests/rules'), [])

it('returns a passed result if both files and directories exist matching the given pattern', async () => {
/** @type {any} */
const ruleoptsImageFirst = {
globsAny: ['image_for_test.png', 'markup_test_files/']
}

const ruleoptsDirFirst = {
globsAny: ['markup_test_files/', 'image_for_test.png']
}

const actualImageFirst = await fileOrDirectoryExistence(
fs,
ruleoptsImageFirst
)

expect(actualImageFirst.passed).to.equal(true)
expect(actualImageFirst.targets).to.have.length(1)
expect(actualImageFirst.targets[0]).to.deep.include({
passed: true,
path: 'image_for_test.png'
})

const actualDirFirst = await fileOrDirectoryExistence(
fs,
ruleoptsDirFirst
)

expect(actualDirFirst.passed).to.equal(true)
expect(actualDirFirst.targets).to.have.length(1)
expect(actualDirFirst.targets[0]).to.deep.include({
passed: true,
path: 'markup_test_files/'
})
})

it('returns a passed result if only files exist matching the given pattern', async () => {
/** @type {any} */
const ruleopts = {
globsAny: ['markup_test_files_nonexistent/', 'image_for_test.png']
}

const actual = await fileOrDirectoryExistence(fs, ruleopts)

expect(actual.passed).to.equal(true)
expect(actual.targets).to.have.length(1)
expect(actual.targets[0]).to.deep.include({
passed: true,
path: 'image_for_test.png'
})
})

it('returns a passed result if only directories exist matching the given pattern', async () => {
/** @type {any} */
const ruleopts = {
globsAny: [
'image_for_test_nonexistent.png',
'another_nonexistent_image.jpg',
'markup_test_files/'
]
}

const actual = await fileOrDirectoryExistence(fs, ruleopts)

expect(actual.passed).to.equal(true)
expect(actual.targets).to.have.length(1)
expect(actual.targets[0]).to.deep.include({
passed: true,
path: 'markup_test_files/'
})
})

it('returns a failed result if neither files or directories exist matching the given pattern', async () => {
/** @type {any} */
const ruleopts = {
globsAny: [
'image_for_test_nonexistent.png',
'a_nonexistent_directory/',
'another_nonexistent_image.jpg',
'markup_test_files_nonexistent/'
]
}

const actual = await fileOrDirectoryExistence(fs, ruleopts)

expect(actual.passed).to.equal(false)
expect(actual.targets).to.have.length(4)
expect(actual.targets[0]).to.deep.include({
passed: false,
pattern: 'image_for_test_nonexistent.png'
})
})
})
})

0 comments on commit 1421fa5

Please sign in to comment.