From d98ee2b167bb63c4c7247cf0c365c1fc34c79ecd Mon Sep 17 00:00:00 2001 From: Dawid Goslawski Date: Mon, 13 Aug 2018 17:05:37 +0200 Subject: [PATCH 1/2] First commit --- HOWTO.md | 32 -------------------- README.md | 63 +++++++++++++++++++++++++++++++-------- linter.py | 70 ++++++++++++++++++++++++++++++++++++++++---- messages/install.txt | 9 ++++-- 4 files changed, 121 insertions(+), 53 deletions(-) delete mode 100644 HOWTO.md diff --git a/HOWTO.md b/HOWTO.md deleted file mode 100644 index 305af2c..0000000 --- a/HOWTO.md +++ /dev/null @@ -1,32 +0,0 @@ -Creating a Linter Plugin -======================== - -- Fork this repo to bootstrap your new linter. -- Clone it into Packages. -- Change a linter.py. -- Update the README and replace `__linter__` placeholders. -- Update messages/install.txt and replace `__linter__` placeholders. -- Open a PR in our [package_control repo](https://github.com/SublimeLinter/package_control_channel) to make it available to others. - -Additional documentation can be found at [sublimelinter.com](http://sublimelinter.com). - - -Updating class attributes --------------------------- -Template linter plugins are created with almost all of the Linter class attributes filled in with the default values. To make your new linter plugin functional, at the very least you need to do the following: - -- Change the default `'selector'` to include the scopes you want the linter to lint. - -- Change the `cmd` attribute to include the executable and arguments you want to include on *every* run. Usually this should be a tuple like `('linter', '-fooarg', '-etc', '-')`. You can also make `cmd` a method (or callable in python speak) which returns such a tuple. - -- Change the `regex` attribute to correctly capture the error output from the linter. - -- Change the `multiline` attribute to `True` if the regex parses multiline error messages. - -Other, optional, attributes include: - -- If the linter executable does not accept input via `stdin`, set the `tempfile_suffix` attribute to the filename suffix of the temp files that will be created. - -- If the linter outputs errors only on `stderr` or `stdout`, set `error_stream` to `util.STREAM_STDERR` or `util.STREAM_STDOUT` respectively. - -You should remove attributes that you do not change, as their values will be provided by the superclass. More information can be found in the [docs](https://github.com/SublimeLinter/SublimeLinter/blob/master/docs/linter_attributes.rst). diff --git a/README.md b/README.md index 96f0868..2e6aca1 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,69 @@ -This is a template. For "how to make a linter", please check [the HOWTO](HOWTO.md). - ------------------------------------------------------------------ - -SublimeLinter-contrib-__linter__ +SublimeLinter-contrib-groovyc ================================ -[![Build Status](https://travis-ci.org/SublimeLinter/SublimeLinter-contrib-__linter__.svg?branch=master)](https://travis-ci.org/SublimeLinter/SublimeLinter-contrib-__linter__) +[![Build Status](https://travis-ci.org/SublimeLinter/SublimeLinter-contrib-groovyc.svg?branch=master)](https://travis-ci.org/SublimeLinter/SublimeLinter-contrib-groovyc) -This linter plugin for [SublimeLinter](https://github.com/SublimeLinter/SublimeLinter) provides an interface to [__linter__](__linter_homepage__). It will be used with files that have the “__syntax__” syntax. +This linter plugin for [SublimeLinter](https://github.com/SublimeLinter/SublimeLinter) provides an interface to [groovyc](http://www.groovy-lang.org/download.html). It will be used with files that have the “.groovy” syntax. ## Installation SublimeLinter must be installed in order to use this plugin. Please use [Package Control](https://packagecontrol.io) to install the linter plugin. -Before installing this plugin, you must ensure that `__linter__` is installed on your system. +Before installing this plugin, you must ensure that `groovyc` is installed on your system. -In order for `__linter__` to be executed by SublimeLinter, you must ensure that its path is available to SublimeLinter. The docs cover [troubleshooting PATH configuration](http://sublimelinter.readthedocs.io/en/latest/troubleshooting.html#finding-a-linter-executable). +In order for `groovyc` to be executed by SublimeLinter, you must ensure that its path is available to SublimeLinter. The docs cover [troubleshooting PATH configuration](http://sublimelinter.readthedocs.io/en/latest/troubleshooting.html#finding-a-linter-executable). + +- `GROOVY_HOME` environment variable has to be set to main groovy folder (inside this folder you can find directories like `bin`, `lib` and `conf`) ## Settings - SublimeLinter settings: http://sublimelinter.readthedocs.org/en/latest/settings.html - Linter settings: http://sublimelinter.readthedocs.org/en/latest/linter_settings.html -Additional SublimeLinter-__linter__ settings: +Additional SublimeLinter-groovyc settings: |Setting|Description | |:------|:--------------| -|foo |Something. | -|bar |Something else.| +|classpath |directories to add to classpath (dependencies), project folder is added automatically| +|sourcepath |directories to add as source path| + +# Example SublimeLinter settings + +## Global Settings +```json +{ + "linters": + { + "groovy":{ + "env": { + "GROOVY_HOME": "C:\\groovy\\apache-groovy-binary-2.6.0-alpha-3\\groovy-2.6.0-alpha-3" + } + } + }, + "paths": + { + "linux": + [ + ], + "osx": + [ + ], + "windows": + [ + "C:\\groovy\\apache-groovy-binary-2.6.0-alpha-3\\groovy-2.6.0-alpha-3\\bin" + ] + } +} +``` + +## Project settings + +``` +"SublimeLinter": { + "linters": { + "groovy": { + "classpath": "C:\\code\\project1\\src" + } + } + } +``` \ No newline at end of file diff --git a/linter.py b/linter.py index 4841e0d..71be61f 100644 --- a/linter.py +++ b/linter.py @@ -1,10 +1,68 @@ -from SublimeLinter.lint import Linter # or NodeLinter, PythonLinter, ComposerLinter, RubyLinter +import os +import platform +import tempfile +from SublimeLinter.lint import Linter + +if platform.system() == "Windows": + GROOVY_BINARY = 'groovyc.bat' + CLASSPATH_DIVIDER = ';' +else: + GROOVY_BINARY = "groovyc" + CLASSPATH_DIVIDER = ':' + +class Groovy(Linter): + + tempfile_suffix = "-" + + regex = r'''(?sx)(.*?:\ # Filepath part + \d+:\ # Line part, we ignore it as we have it later + (?P.*?)\s* # Error message till @ + @\ line\ (?P\d+),\ column\ (?P\d+)\. # line and column, ends with dot + ''' \ + '{}'.format(os.linesep) +\ + r'''\s*(?P.*?)\n # Second line - will be whole code snippet of error, it has to ends with unix newline + ''' \ + r'|.*) # The last resort match - if we do not match error, match anything to silence info from SL' + + multiline = True -class __class__(Linter): - cmd = '__cmd__' - regex = r'' - multiline = False defaults = { - 'selector': 'source.python' + 'classpath': None, + 'sourcepath': None, + 'selector': 'source.groovy', } + + on_stderr = None + + def cmd(self): + cmd = (GROOVY_BINARY,) + settings = self.get_view_settings() + # pylint: disable=attribute-defined-outside-init + self._tempdir = tempfile.TemporaryDirectory(prefix="sublimelinter-contrib-groovyc-target-") + + classpaths = [] + classpaths.append(settings.get('classpath') or '') + classpaths.append(self._tempdir.name) + + classpath_str = '"{}'.format(CLASSPATH_DIVIDER) + '{}"'.format(CLASSPATH_DIVIDER.join(classpaths)) + cmd += ('-classpath', classpath_str) + + for opt in ('sourcepath',): + value = settings.get(opt) + if value is not None: + cmd += ('--{}'.format(opt), '"{}"'.format(value),) + + cmd += ('-d', '"{}"'.format(self._tempdir.name)) + return cmd + + def run(self, cmd, code=None): + with self._tempdir: + return super().run(cmd, code) + + def split_match(self, match): + match, line, col, error, warning, message, near = super().split_match(match) + + if line is None: + return match, 0, 0, None, None, None, None + return match, line, col, error, warning, message, near diff --git a/messages/install.txt b/messages/install.txt index 81f2de4..138577a 100644 --- a/messages/install.txt +++ b/messages/install.txt @@ -1,6 +1,9 @@ -SublimeLinter-contrib-__linter__ +SublimeLinter-contrib-groovyc ------------------------------- -This linter plugin for SublimeLinter provides an interface to __linter__. +This linter plugin for SublimeLinter provides an interface to groovyc. + +You have to add groovyc to system PATH, or add it to paths in SublimeLinter settings. GROOVY_HOME +has to be properly set in environment or SublimeLinter settings. For more information, please see: -https://github.com/__user__/SublimeLinter-contrib-__linter__ +https://github.com/alkuzad/SublimeLinter-contrib-groovyc From fe2519ea6fe6a1937fd224fcb64b841a06c0c2b3 Mon Sep 17 00:00:00 2001 From: Dawid Goslawski Date: Mon, 13 Aug 2018 17:15:53 +0200 Subject: [PATCH 2/2] Fix flake errors --- linter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linter.py b/linter.py index 71be61f..73d83f1 100644 --- a/linter.py +++ b/linter.py @@ -11,6 +11,7 @@ GROOVY_BINARY = "groovyc" CLASSPATH_DIVIDER = ':' + class Groovy(Linter): tempfile_suffix = "-" @@ -21,7 +22,7 @@ class Groovy(Linter): @\ line\ (?P\d+),\ column\ (?P\d+)\. # line and column, ends with dot ''' \ '{}'.format(os.linesep) +\ - r'''\s*(?P.*?)\n # Second line - will be whole code snippet of error, it has to ends with unix newline + r'''\s*(?P.*?)\n # 2line - code snippet of error, it has to end with unix newline ''' \ r'|.*) # The last resort match - if we do not match error, match anything to silence info from SL'