Insert linter into a package
This commit is contained in:
parent
0df3d30e12
commit
98ddf104e5
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
node_modules
|
43
init.coffee
43
init.coffee
@ -1,43 +0,0 @@
|
||||
{CompositeDisposable} = require 'atom'
|
||||
|
||||
module.exports = AtomLanguageMZN =
|
||||
config:
|
||||
enableLinter:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
description: "Enable linting using `mzn2fzn`"
|
||||
mzn2fznPath:
|
||||
type: 'string'
|
||||
default: 'mzn2fzn'
|
||||
description: 'Path to Minizinc\'s compiler `mzn2fzn`'
|
||||
|
||||
activate: (state) ->
|
||||
console.log 'language-mzn: package loaded,
|
||||
ready to get initialized by AtomLinter.'
|
||||
|
||||
if not atom.packages.getLoadedPackage 'linter'
|
||||
atom.notifications.addError 'Linter package not found',
|
||||
detail: '[language-mzn] `linter` package not found. \
|
||||
Please install https://github.com/AtomLinter/Linter'
|
||||
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@subscriptions.add atom.config.observe 'linter-mzn.mzn2fznPath', (mzn2fznPath) =>
|
||||
@mzn2fznPath = mzn2fznPath
|
||||
|
||||
deactivate: ->
|
||||
@subscriptions.dispose()
|
||||
|
||||
serialize: ->
|
||||
AtomLanguageMZNViewState: @AtomLanguageMZNView.serialize()
|
||||
|
||||
provideLinter: ->
|
||||
LinterMZN = require('./linter-mzn')
|
||||
@provider = new LinterMZN()
|
||||
return {
|
||||
name: 'MiniZinc',
|
||||
grammarScopes: ['source.mzn'],
|
||||
scope: 'file',
|
||||
lintsOnChange: true,
|
||||
lint: @provider.lint
|
||||
}
|
20
lib/init.coffee
Normal file
20
lib/init.coffee
Normal file
@ -0,0 +1,20 @@
|
||||
module.exports =
|
||||
config:
|
||||
compilerPath:
|
||||
type: 'string'
|
||||
default: 'mzn2fzn'
|
||||
description: 'Path to Minizinc\'s compiler `mzn2fzn`'
|
||||
|
||||
activate: (state) ->
|
||||
require('atom-package-deps').install 'linter-mzn'
|
||||
|
||||
provideLinter: ->
|
||||
LinterMZN = require('./linter-mzn')
|
||||
@provider = new LinterMZN()
|
||||
return {
|
||||
name: 'MiniZinc',
|
||||
grammarScopes: ['source.mzn'],
|
||||
scope: 'file',
|
||||
lintsOnChange: false,
|
||||
lint: @provider.lint
|
||||
}
|
@ -1,39 +1,38 @@
|
||||
{BufferedProcess} = require 'atom'
|
||||
{CompositeDisposable} = require 'atom'
|
||||
|
||||
atomLinter = require 'atom-linter'
|
||||
|
||||
class LinterMZN
|
||||
lintProcess: null
|
||||
|
||||
config: (key) ->
|
||||
atom.config.get "language-mzn.#{key}"
|
||||
constructor: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@subscriptions.add atom.config.observe 'linter-mzn.compilerPath',
|
||||
(compilerPath) =>
|
||||
@compilerPath = compilerPath
|
||||
|
||||
lint: (textEditor) =>
|
||||
if @config 'enableLinter'
|
||||
return new Promise (resolve, reject) =>
|
||||
output = ''
|
||||
command = @config 'mzn2fznPath'
|
||||
args = ['--instance-check-only', textEditor.getPath()]
|
||||
options = process.env
|
||||
command = @compilerPath
|
||||
args = ['--instance-check-only', textEditor.getPath()]
|
||||
options =
|
||||
timeout: 10000
|
||||
env: process.env
|
||||
stream: 'both'
|
||||
|
||||
stdout = (data) ->
|
||||
atom.notifications.addWarning data
|
||||
stderr = (data) ->
|
||||
output += data
|
||||
exit = (code) =>
|
||||
if code is 0
|
||||
resolve []
|
||||
else
|
||||
messages = @parse output, textEditor.getPath()
|
||||
resolve messages
|
||||
|
||||
@lintProcess = new BufferedProcess({command, args, options, stdout, stderr, exit})
|
||||
@lintProcess.onWillThrowError ({error, handle}) ->
|
||||
atom.notifications.addError "Failed to run #{command}",
|
||||
detail: "#{error.message}"
|
||||
dismissable: true
|
||||
handle()
|
||||
resolve []
|
||||
else
|
||||
return []
|
||||
atomLinter.exec(@compilerPath, args, options)
|
||||
.then (result) =>
|
||||
{stdout, stderr, exit} = result
|
||||
if exit is 0
|
||||
[]
|
||||
else
|
||||
@parse stderr, textEditor.getPath()
|
||||
.catch (error) ->
|
||||
console.log error
|
||||
atom.notifications.addError "Failed to run #{command}",
|
||||
detail: "#{error.message}"
|
||||
dismissable: true
|
||||
[]
|
||||
|
||||
parse: (output, filePath) =>
|
||||
messages = []
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "linter-mzn",
|
||||
"main": "./lib/init",
|
||||
"version": "0.0.0",
|
||||
"description": "A linter for your MiniZinc models in Atomm using mzn2fzn",
|
||||
"keywords": [
|
||||
],
|
||||
"repository": "https://github.com/Dekker1/linter-mzn",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"atom": ">=1.0.0 <2.0.0"
|
||||
},
|
||||
"providedServices": {
|
||||
"linter": {
|
||||
"versions": {
|
||||
"1.0.0": "provideLinter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-linter": "^10.0.0",
|
||||
"atom-package-deps": "^4.3.1"
|
||||
},
|
||||
"package-deps": [
|
||||
"linter",
|
||||
"linter-mzn"
|
||||
]
|
||||
}
|
62
spec/linter-mzn-spec.coffee
Normal file
62
spec/linter-mzn-spec.coffee
Normal file
@ -0,0 +1,62 @@
|
||||
LinterMzn = require '../lib/linter-mzn'
|
||||
|
||||
# Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs.
|
||||
#
|
||||
# To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit`
|
||||
# or `fdescribe`). Remove the `f` to unfocus the block.
|
||||
|
||||
describe "LinterMzn", ->
|
||||
[workspaceElement, activationPromise] = []
|
||||
|
||||
beforeEach ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
activationPromise = atom.packages.activatePackage('linter-mzn')
|
||||
|
||||
describe "when the linter-mzn:toggle event is triggered", ->
|
||||
it "hides and shows the modal panel", ->
|
||||
# Before the activation event the view is not on the DOM, and no panel
|
||||
# has been created
|
||||
expect(workspaceElement.querySelector('.linter-mzn')).not.toExist()
|
||||
|
||||
# This is an activation event, triggering it will cause the package to be
|
||||
# activated.
|
||||
atom.commands.dispatch workspaceElement, 'linter-mzn:toggle'
|
||||
|
||||
waitsForPromise ->
|
||||
activationPromise
|
||||
|
||||
runs ->
|
||||
expect(workspaceElement.querySelector('.linter-mzn')).toExist()
|
||||
|
||||
linterMznElement = workspaceElement.querySelector('.linter-mzn')
|
||||
expect(linterMznElement).toExist()
|
||||
|
||||
linterMznPanel = atom.workspace.panelForItem(linterMznElement)
|
||||
expect(linterMznPanel.isVisible()).toBe true
|
||||
atom.commands.dispatch workspaceElement, 'linter-mzn:toggle'
|
||||
expect(linterMznPanel.isVisible()).toBe false
|
||||
|
||||
it "hides and shows the view", ->
|
||||
# This test shows you an integration test testing at the view level.
|
||||
|
||||
# Attaching the workspaceElement to the DOM is required to allow the
|
||||
# `toBeVisible()` matchers to work. Anything testing visibility or focus
|
||||
# requires that the workspaceElement is on the DOM. Tests that attach the
|
||||
# workspaceElement to the DOM are generally slower than those off DOM.
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
expect(workspaceElement.querySelector('.linter-mzn')).not.toExist()
|
||||
|
||||
# This is an activation event, triggering it causes the package to be
|
||||
# activated.
|
||||
atom.commands.dispatch workspaceElement, 'linter-mzn:toggle'
|
||||
|
||||
waitsForPromise ->
|
||||
activationPromise
|
||||
|
||||
runs ->
|
||||
# Now we can test for view visibility
|
||||
linterMznElement = workspaceElement.querySelector('.linter-mzn')
|
||||
expect(linterMznElement).toBeVisible()
|
||||
atom.commands.dispatch workspaceElement, 'linter-mzn:toggle'
|
||||
expect(linterMznElement).not.toBeVisible()
|
Reference in New Issue
Block a user