From 5f4103fb35ac7776cea5a74c7e04c7004831c13d Mon Sep 17 00:00:00 2001 From: max ulidtko Date: Wed, 6 May 2020 13:07:08 +0300 Subject: [PATCH 1/6] Improve :ALEDetail for dockerfile_lint 1. The often longish `description` moved away from (supposedly short) statusline `message` into the `detail` section. 2. dockerfile_lint sends `reference_url` pointing to issue explanations. Use that. --- ale_linters/dockerfile/dockerfile_lint.vim | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ale_linters/dockerfile/dockerfile_lint.vim b/ale_linters/dockerfile/dockerfile_lint.vim index 95768b12..b3a2aa87 100644 --- a/ale_linters/dockerfile/dockerfile_lint.vim +++ b/ale_linters/dockerfile/dockerfile_lint.vim @@ -32,14 +32,26 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort let l:line = get(l:object, 'line', -1) let l:message = l:object['message'] - if get(l:object, 'description', 'None') isnot# 'None' - let l:message = l:message . '. ' . l:object['description'] + let l:link = get(l:object, 'reference_url', '') + if type(l:link) == type([]) + " Somehow, reference_url is returned as two-part list. + " Anchor markers in that list are sometimes duplicated. + " See https://github.com/projectatomic/dockerfile_lint/issues/134 + let l:link = join(l:link, '') + let l:link = substitute(l:link, '##', '#', '') endif + let l:detail = l:message + if get(l:object, 'description', 'None') isnot# 'None' + let l:detail .= "\n\n" . l:object['description'] + endif + let l:detail .= "\n\n" . l:link + call add(l:messages, { \ 'lnum': l:line, \ 'text': l:message, \ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type), + \ 'detail': l:detail, \}) endfor endfor From c0d74b80944feddc4e8c91e7b1cae47e1533b2c1 Mon Sep 17 00:00:00 2001 From: max ulidtko Date: Wed, 6 May 2020 13:43:20 +0300 Subject: [PATCH 2/6] Fix style and test --- ale_linters/dockerfile/dockerfile_lint.vim | 5 ++++- test/handler/test_dockerfile_lint_handler.vader | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ale_linters/dockerfile/dockerfile_lint.vim b/ale_linters/dockerfile/dockerfile_lint.vim index b3a2aa87..0c0ad533 100644 --- a/ale_linters/dockerfile/dockerfile_lint.vim +++ b/ale_linters/dockerfile/dockerfile_lint.vim @@ -33,7 +33,8 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort let l:message = l:object['message'] let l:link = get(l:object, 'reference_url', '') - if type(l:link) == type([]) + + if type(l:link) == v:t_list " Somehow, reference_url is returned as two-part list. " Anchor markers in that list are sometimes duplicated. " See https://github.com/projectatomic/dockerfile_lint/issues/134 @@ -42,9 +43,11 @@ function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort endif let l:detail = l:message + if get(l:object, 'description', 'None') isnot# 'None' let l:detail .= "\n\n" . l:object['description'] endif + let l:detail .= "\n\n" . l:link call add(l:messages, { diff --git a/test/handler/test_dockerfile_lint_handler.vader b/test/handler/test_dockerfile_lint_handler.vader index 619b7bde..a73db8cd 100644 --- a/test/handler/test_dockerfile_lint_handler.vader +++ b/test/handler/test_dockerfile_lint_handler.vader @@ -26,21 +26,25 @@ Execute(The dockerfile_lint handler should handle a normal example): \ 'lnum': -1, \ 'type': 'E', \ 'text': "Required LABEL name/key 'Name' is not defined", + \ 'detail': "Required LABEL name/key 'Name' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", \ }, \ { \ 'lnum': -1, \ 'type': 'E', \ 'text': "Required LABEL name/key 'Version' is not defined", + \ 'detail': "Required LABEL name/key 'Version' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project", \ }, \ { \ 'lnum': 3, \ 'type': 'I', - \ 'text': "the MAINTAINER command is deprecated. MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0", + \ 'text': "the MAINTAINER command is deprecated", + \ 'detail': "the MAINTAINER command is deprecated\n\nMAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0\n\nhttps://github.com/docker/cli/blob/master/docs/deprecated.md#maintainer-in-dockerfile", \ }, \ { \ 'lnum': -1, \ 'type': 'I', \ 'text': "There is no 'CMD' instruction", + \ 'detail': "There is no 'CMD' instruction\n\nhttps://docs.docker.com/engine/reference/builder/#cmd", \ }, \ ], \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [ From 345daf683b9792dc7b131181585eb0a37a02e853 Mon Sep 17 00:00:00 2001 From: NoNE Date: Fri, 15 May 2020 00:35:15 +0200 Subject: [PATCH 3/6] More docs for beginners to use cloudformation linter --- doc/ale-cloudformation.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/ale-cloudformation.txt b/doc/ale-cloudformation.txt index 59c6af06..81cb9dd9 100644 --- a/doc/ale-cloudformation.txt +++ b/doc/ale-cloudformation.txt @@ -8,7 +8,22 @@ cfn-python-lint *ale-cloudformation-cfn-python-lint* cfn-python-lint is a linter for AWS CloudFormation template file. https://github.com/awslabs/cfn-python-lint +=============================================================================== +Getting it to work: *ale-cloudformation-activate* +To get cloudformation linter to work on only CloudFormation files put + + au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation + +on `ftdetect/cloudformation.vim` + +and + +let b:ale_linter_aliases = {'cloudformation': ['cloudformation', 'yaml']} + +on `after/ftplugin/yaml.vim` + +This will get both cloudformation and yaml linters on work on any file with `template.yaml` ext. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: From 6b8f08f7fcb3b2bc9da87de1ebafd90799ab1573 Mon Sep 17 00:00:00 2001 From: Mohamed hamza Date: Fri, 15 May 2020 03:40:46 +0200 Subject: [PATCH 4/6] Added linter installing methods --- doc/ale-cloudformation.txt | 41 +++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/doc/ale-cloudformation.txt b/doc/ale-cloudformation.txt index 81cb9dd9..9724403b 100644 --- a/doc/ale-cloudformation.txt +++ b/doc/ale-cloudformation.txt @@ -7,23 +7,40 @@ cfn-python-lint *ale-cloudformation-cfn-python-lint* cfn-python-lint is a linter for AWS CloudFormation template file. -https://github.com/awslabs/cfn-python-lint -=============================================================================== -Getting it to work: *ale-cloudformation-activate* +Website: https://github.com/awslabs/cfn-python-lint -To get cloudformation linter to work on only CloudFormation files put +Installation +------------------------------------------------------------------------------- + + +Install cfn-python-lint using either pip or brew: > + +`pip install cfn-lint`. If pip is not available, run +`python setup.py clean --all` then `python setup.py install`. + + Homebrew (macOS): + +`brew install cfn-lint` + +< +Configuration +------------------------------------------------------------------------------- + +To get cloudformation linter to work on only CloudFormation files we must set +the buffer |filetype| to yaml.cloudformation. +This causes ALE to lint the file with linters configured for cloudformation and +yaml files. + +Just put: + +> au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation +< + on `ftdetect/cloudformation.vim` -and - -let b:ale_linter_aliases = {'cloudformation': ['cloudformation', 'yaml']} - -on `after/ftplugin/yaml.vim` - -This will get both cloudformation and yaml linters on work on any file with `template.yaml` ext. +This will get both cloudformation and yaml linters to work on any file with `.template.yaml` ext. =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: - From 1428c7b29e50af56f53ee1d587679d97a027dd72 Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 11 Jun 2020 19:21:17 +0100 Subject: [PATCH 5/6] Update the internal ALE version to 2.7.0 --- autoload/ale.vim | 2 +- test/test_ale_has.vader | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/ale.vim b/autoload/ale.vim index 01e17b15..6251b47b 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -163,7 +163,7 @@ function! ale#Queue(delay, ...) abort endif endfunction -let s:current_ale_version = [2, 6, 0] +let s:current_ale_version = [2, 7, 0] " A function used to check for ALE features in files outside of the project. function! ale#Has(feature) abort diff --git a/test/test_ale_has.vader b/test/test_ale_has.vader index b8a99103..633c7186 100644 --- a/test/test_ale_has.vader +++ b/test/test_ale_has.vader @@ -1,4 +1,5 @@ Execute(Checks for versions below the current version should succeed): + AssertEqual 1, ale#Has('ale-2.7.0') AssertEqual 1, ale#Has('ale-2.6.0') AssertEqual 1, ale#Has('ale-2.5.0') AssertEqual 1, ale#Has('ale-2.4.0') From b3c6db173a019c37c83d4600c0c68872e91086dd Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Wed, 1 Jul 2020 16:00:21 +0000 Subject: [PATCH 6/6] Run ESLint fixer from project root, where possible (#3096) * Split eslint#GetCdString from eslint#GetCommand Move the code for finding the project root and building the cd string into a separate function so that it can be reused in the eslint fixer. Signed-off-by: Kevin Locke * Run ESLint fixer from project root dir To match the ESLint linter, as changed in 9ee57d43 (which I forgot to apply to the fixer, whoops). Fixes: #3094 Closes: #3095 Signed-off-by: Kevin Locke --- autoload/ale/fixers/eslint.vim | 9 ++-- autoload/ale/handlers/eslint.vim | 19 +++++---- test/fixers/test_eslint_fixer_callback.vader | 44 ++++++++++++++------ 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index 62e692b1..f725875c 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -53,7 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " Use --fix-to-stdout with eslint_d if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', @@ -63,7 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " 4.9.0 is the first version with --fix-dry-run if ale#semver#GTE(a:version, [4, 9, 0]) return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -71,7 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort endif return { - \ 'command': ale#node#Executable(a:buffer, l:executable) + \ 'command': ale#handlers#eslint#GetCdString(a:buffer) + \ . ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . ' --fix %t', diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index 156b939f..c7c47d78 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -37,11 +37,9 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort \]) endfunction -function! ale#handlers#eslint#GetCommand(buffer) abort - let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) - - let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - +" Given a buffer, return a command prefix string which changes directory +" as necessary for running ESLint. +function! ale#handlers#eslint#GetCdString(buffer) abort " ESLint 6 loads plugins/configs/parsers from the project root " By default, the project root is simply the CWD of the running process. " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md @@ -50,9 +48,16 @@ function! ale#handlers#eslint#GetCommand(buffer) abort " Note: If node_modules not present yet, can't load local deps anyway. let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' - let l:cd_command = !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' - return l:cd_command + return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' +endfunction + +function! ale#handlers#eslint#GetCommand(buffer) abort + let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) + + let l:options = ale#Var(a:buffer, 'javascript_eslint_options') + + return ale#handlers#eslint#GetCdString(a:buffer) \ . ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -f json --stdin --stdin-filename %s' diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index ad80bdd5..400267ac 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -13,7 +13,9 @@ Execute(The executable path should be correct): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -150,7 +152,9 @@ Execute(The lower priority configuration file in a nested directory should be pr AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc')) \ . ' --fix %t', @@ -164,7 +168,9 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --config /foo.cfg' \ . ' --fix %t', @@ -175,7 +181,9 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c /foo.cfg' \ . ' --fix %t', @@ -187,7 +195,9 @@ Execute(package.json should be used as a last resort): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -199,7 +209,8 @@ Execute(package.json should be used as a last resort): \ { \ 'read_temporary_file': 1, \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -214,7 +225,9 @@ Execute(The version check should be correct): \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --version', \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -223,7 +236,9 @@ Execute(The version check should be correct): AssertFixer [ \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -236,7 +251,9 @@ Execute(--fix-dry-run should be used for 4.9.0 and up): GivenCommandOutput ['4.9.0'] AssertFixer \ { - \ 'command': (has('win32') ? 'node.exe ' : '') + \ 'command': + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) + \ . (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -249,7 +266,8 @@ Execute(--fix-to-stdout should be used for eslint_d): \ { \ 'read_temporary_file': 1, \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -260,7 +278,8 @@ Execute(--fix-to-stdout should be used for eslint_d): AssertFixer \ { \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ } @@ -270,7 +289,8 @@ Execute(--fix-to-stdout should be used for eslint_d): AssertFixer \ { \ 'command': - \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) + \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ }