From 30fe8aefa88dedced6bc5f746b36b2a5509b0c43 Mon Sep 17 00:00:00 2001 From: Joe Hildebrand Date: Sun, 2 Jul 2023 13:14:22 -0600 Subject: [PATCH] Optionally process 'unset' properties. Fixes #123 --- CHANGELOG.md | 13 +++++++++++++ src/cli.ts | 2 ++ src/index.test.ts | 17 +++++++++++++++++ src/index.ts | 24 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7292bf0..b24fdc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 2.0.0 + +- **Breaking**: Now requires Node v16+ +- Enable extended globbing from minimatch. This means that some patterns will + work in this version might not work in other editorconfig implementations. + Fixes #84. +- Add `unset` option to API and CLI. When enabled, properties with the value + "unset" will be removed from the returned object. Defaults to false in all + cases, since according to the core team, this is something that the editor + plugin is supposed to do, and the tests reinforce this. An `unset()` + function is now exported if you'd like to call it explicitly. + Fixes #123. + ## 1.0.3 - Updated all dependencies, including security fixes for semver 7.3.8 diff --git a/src/cli.ts b/src/cli.ts index 0475b94..f630fa2 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -54,6 +54,7 @@ export default async function cli( .option('-f ', 'Specify conf filename other than \'.editorconfig\'') .option('-b ', 'Specify version (used by devs to test compatibility)') .option('--files', 'Output file names that contributed to the configuration, rather than the configuation itself') + .option('--unset', 'Remove all properties whose final value is \'unset\'') .parse(args) const files = program.args @@ -73,6 +74,7 @@ export default async function cli( version: opts.b as string, files: visited ? visited[i++] : undefined, cache, + unset: Boolean(opts.unset), })) } return p diff --git a/src/index.test.ts b/src/index.test.ts index 9de2124..5b0ea50 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -200,3 +200,20 @@ indent_size = 3`)) matcher(path.join(__dirname, 'foo.json')).should.match({ indent_size: 3 }) }) }) + +describe('unset', () => { + it('pair witht the value `unset`', () => { + const matcher = editorconfig.matcher({ + root: __dirname, + unset: true, + }, Buffer.from(`\ +[*] +indent_size = 4 + +[*.json] +indent_size = unset +`)) + matcher(path.join(__dirname, 'index.js')).should.match({ indent_size: 4 }) + matcher(path.join(__dirname, 'index.json')).should.be.eql({ }) + }) +}) diff --git a/src/index.ts b/src/index.ts index fc260fd..346aff1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,6 +61,7 @@ export interface ParseOptions { root?: string files?: Visited[] cache?: Cache + unset?: boolean } const knownPropNames: (keyof KnownProps)[] = [ @@ -426,6 +427,7 @@ function opts(filepath: string, options: ParseOptions = {}): [ root: path.resolve(options.root || path.parse(resolvedFilePath).root), files: options.files, cache: options.cache, + unset: options.unset, }, ] } @@ -507,11 +509,33 @@ function combine( } } } + return props }, {}) + + if (options.unset) { + unset(ret) + } + return processMatches(ret, options.version as string) } +/** + * For any pair, a value of `unset` removes the effect of that pair, even if + * it has been set before. This method modifies the properties object in + * place to remove any property that has a value of `unset`. + * + * @param props Properties object to modify. + */ +export function unset(props: Props): void { + const keys = Object.keys(props) + for (const k of keys) { + if (props[k] === 'unset') { + delete props[k] + } + } +} + /** * Find all of the properties from matching sections in config files in the * same directory or toward the root of the filesystem.