Skip to content
This repository was archived by the owner on Aug 7, 2023. It is now read-only.

Commit 47151f7

Browse files
authored
Merge pull request #119 from takbal/master
a rewrite of the Julia side to use StaticLint.jl
2 parents 1f69228 + b17ce0b commit 47151f7

File tree

10 files changed

+1042
-466
lines changed

10 files changed

+1042
-466
lines changed

.circleci/config.yml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,16 @@ defaults: &defaults
99
- attach_workspace:
1010
at: /tmp
1111
- run:
12-
name: Install Julia v1.2.0
12+
name: Install Julia v1.5.3
1313
command: |
1414
curl -o julia.tar.gz --location --silent --show-error \
15-
https://julialang-s3.julialang.org/bin/linux/x64/1.2/julia-1.2.0-linux-x86_64.tar.gz && \
15+
https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.3-linux-x86_64.tar.gz && \
1616
mkdir julia && \
1717
tar --extract --gzip --strip 1 --directory=julia --file=julia.tar.gz && \
1818
echo 'export PATH="/tmp/project/julia/bin:$PATH"' >> $BASH_ENV
1919
- run:
2020
name: Julia version
2121
command: julia --version
22-
- run:
23-
name: Install Lint.jl
24-
# Note the "using Lint" is to pre-compile the cache
25-
# Also, we are using the `master` branch directly since a working
26-
# version isn't currently released.
27-
command: |
28-
julia -E 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/tonyhffong/Lint.jl", rev="master")); using Lint;'
29-
- run:
30-
name: Lint.jl version
31-
command: julia -E 'using Pkg; Pkg.status("Lint");'
3222
- run:
3323
name: Create VFB for Atom to run in
3424
command: /usr/local/bin/xvfb_start

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
npm-debug.log
33
node_modules
4+
.package.json.full

README.md

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,60 @@
11
# linter-julia
22

3-
:warning: This linter currently uses the old Lint.jl which does not work on the latest versions of Julia :warning:
4-
5-
63
This linter plugin for [AtomLinter](https://atomlinter.github.io/)
7-
provides an interface to [Lint.jl](https://github.com/tonyhffong/Lint.jl).
4+
provides an interface to [StaticLint.jl](https://github.com/julia-vscode/StaticLint.jl).
85
It will be used with files that have the `Julia` syntax.
96

10-
![screenshot](https://raw.githubusercontent.com/AtomLinter/linter-julia/master/Screenshot.gif)
7+
This is a fork that replaces Lint.jl with StaticLint.jl from the Julia VSCode plugin.
118

12-
## Installation
9+
![screenshot](https://raw.githubusercontent.com/takbal/linter-julia/master/Screenshot.gif)
1310

14-
- Install the package through Atom's UI and install the package.
11+
## Developed on
1512

16-
You can also use the `apm` tool in the CLI:
17-
```bash
18-
$ apm install linter-julia
19-
```
13+
* julia-1.5.3
14+
* [linter-ui-default](https://atom.io/packages/linter-ui-default)
15+
* [linter](https://atom.io/packages/linter)
16+
* tested on Ubuntu 18.04 and Windows
17+
18+
## Caveats
2019

21-
- You need to tell linter-julia where to find the julia executable
22-
(i.e. `/usr/bin/julia` or `C:\Julia-1.3.0-rc4\bin\julia.exe`). See Settings below.
20+
* The server needs a minute to spin up, then also some time to parse new Julia environments that this Atom instance
21+
have not seen before. A pop-up is shown when parsing a new environment starts (but not when it ends). After parsing finishes, you need to
22+
edit or reopen those files that are already in the editor for linting to start. If the environment had been already parsed, linting new files is immediate.
23+
* The edited file has to be saved at least once for linting to start. This is by design of the linter package (https://github.com/steelbrain/linter/issues/1235)
24+
* The environment for each file is guessed from its path. If this fails, Julia's default environment is assumed.
25+
* The symbols are rebuilt if the modification time of the Project.toml or the Manifest.toml files change, for example,
26+
you add, remove or update packages. Linting is not available during this rebuild.
2327

24-
- This package installs the master branch of Lint.jl automatically, to make it activated just restart Atom one more time! (two time total)
28+
## Internals
2529

30+
The code generates its private shared environment at the Julia depot in 'environments/linter-julia'. It also places a logfile there.
2631

27-
- Note: if you have't installed [Juno](http://junolab.org/), and [Julia]( http://julialang.org/downloads/)
32+
Guessing the environment works by walking upwards in the path and looking for Project.toml. If nothing found, the default
33+
environment is assumed. The project's root file is then looked for at the canonical X/src/X.jl etc. locations.
2834

29-
- Note: If after two restarts the linter didn't work, add the Lint.jl manually:
30-
```julia
31-
] add https://github.com/tonyhffong/Lint.jl
35+
I know nothing of Atom development or js, so the changes are likely messy there, please revise. Atom seems to be
36+
unable to shut down the server process, so the server exits by polling Atom's PID right now.
37+
38+
## Installation
39+
40+
- Install the package through Atom's UI. You can also use the `apm` tool in the CLI:
41+
```bash
42+
$ apm install takbal/linter-julia
3243
```
3344

45+
- You may need to tell linter-julia where to find the Julia executable
46+
(i.e. `/usr/bin/julia` or `C:\Julia-1.5.3\bin\julia.exe`). The default assumes 'julia' just works.
47+
48+
- Julia must have the General registry added.
49+
3450
## Settings
3551

3652
![screenshot](https://raw.githubusercontent.com/AtomLinter/linter-julia/master/settings.png)
3753

3854
## Features
3955

40-
* By default linter-julia uses Juno's `julia`
41-
* You can give a path to the `julia` executable that you want to use for Linting
42-
* You can ignore the messages you don't need
56+
* You can ignore the messages you don't need in settings. Provide the codes with a comma separated list.
57+
The codes can be found by expanding the hover of the error message if 'show error codes' is set.
4358

4459
[Issues](https://github.com/AtomLinter/linter-julia/issues) and [pull requests]
4560
(https://github.com/AtomLinter/linter-julia/pulls) are welcome.

Screenshot.gif

-69.2 KB
Loading

lib/index.js

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/* @flow */
22

33
import net from 'net';
4+
import FS from 'fs';
45
import { CompositeDisposable } from 'atom';
5-
import { spawnServer, terminateServer } from './server';
6-
import type { Server } from './types';
6+
import { spawnServer, getPipePath } from './server';
7+
8+
const pipepath = getPipePath();
79

8-
let spawnedServer: ?Server = null;
910
let subscriptions: ?Object = null;
1011

1112
let executablePath;
@@ -14,25 +15,54 @@ let ignoreWarning;
1415
let showErrorCodes;
1516
let ignoreIssueCodes;
1617

18+
function timeout(ms) {
19+
return new Promise((resolve) => setTimeout(resolve, ms));
20+
}
21+
22+
async function pipeup() {
23+
if (!FS.existsSync(pipepath)) {
24+
await timeout(1000);
25+
await pipeup();
26+
}
27+
}
28+
29+
async function unlock() {
30+
if (global.linter_julia_locked === true) {
31+
await timeout(200);
32+
await unlock();
33+
return;
34+
}
35+
global.linter_julia_locked = true;
36+
}
37+
1738
export function activate() {
1839
// eslint-disable-next-line global-require
1940
require('atom-package-deps').install('linter-julia');
2041
subscriptions = new CompositeDisposable();
2142
subscriptions.add(
2243
atom.config.observe('linter-julia.executablePath', async (value) => {
2344
executablePath = value;
24-
if (spawnedServer) {
45+
// taken out: terminateServer() just does not work for some reason
46+
/*
47+
if (global.linter_julia_spawnedServer) {
2548
try {
26-
await terminateServer(spawnedServer);
27-
spawnedServer = null;
28-
spawnedServer = await spawnServer(executablePath);
49+
await terminateServer(global.linter_julia_spawnedServer);
50+
global.linter_julia_spawnedServer = spawnServer(executablePath);
51+
global.linter_julia_started = true;
52+
global.linter_julia_locked = false;
53+
atom.notifications.addInfo(
54+
'linter-julia: it is likely safer to restart Atom after this change');
2955
} catch (e) {
3056
const message = '[Linter-Julia] '
3157
+ 'Unable to spawn server after config change';
3258
atom.notifications.addError(`${message}. See console for details.`);
3359
// eslint-disable-next-line no-console
3460
console.error(`${message}: `, e);
3561
}
62+
}
63+
*/
64+
if (global.linter_julia_started) {
65+
atom.notifications.addInfo('[Linter-Julia] please restart Atom for this change to work');
3666
}
3767
}),
3868
atom.config.observe('linter-julia.ignoreInfo', (value) => {
@@ -48,12 +78,23 @@ export function activate() {
4878
ignoreIssueCodes = value;
4979
}),
5080
);
81+
82+
// start only one server
83+
if (typeof global.linter_julia_started === 'undefined') {
84+
global.linter_julia_spawnedServer = spawnServer(executablePath);
85+
global.linter_julia_started = true;
86+
global.linter_julia_locked = false;
87+
}
5188
}
5289

5390
export function deactivate() {
54-
if (spawnedServer) {
55-
terminateServer(spawnedServer);
56-
spawnedServer = null;
91+
if (global.linter_julia_spawnedServer !== null) {
92+
// terminateServer() just does not work
93+
// terminateServer(global.linter_julia_spawnedServer);
94+
// global.linter_julia_spawnedServer = null;
95+
// global.linter_julia_started = false;
96+
// server stays alive, just try not to deadlock
97+
global.linter_julia_locked = false;
5798
}
5899
if (subscriptions) {
59100
subscriptions.dispose();
@@ -67,10 +108,14 @@ export function provideLinter() {
67108
lintsOnChange: true,
68109
grammarScopes: ['source.julia'],
69110
async lint(textEditor: Object) {
70-
if (!spawnedServer) {
71-
spawnedServer = await spawnServer(executablePath);
72-
}
73-
const connection = net.createConnection(spawnedServer.path);
111+
// wait for the pipe to appear
112+
await pipeup();
113+
114+
// only one connection at one time
115+
await unlock();
116+
117+
const connection = net.createConnection(pipepath);
118+
74119
connection.on('connect', function writeData() {
75120
this.write(JSON.stringify({
76121
file: textEditor.getPath(),
@@ -87,7 +132,7 @@ export function provideLinter() {
87132
// This is the timeout because net.Socket doesn't have one for connections
88133
reject(new Error('Request timed out'));
89134
connection.end();
90-
}, 60 * 1000);
135+
}, 300 * 1000);
91136
connection.on('error', reject);
92137

93138
const data = [];
@@ -100,13 +145,21 @@ export function provideLinter() {
100145
try {
101146
parsed = JSON.parse(merged);
102147
} catch (_) {
103-
const msg = '[Linter-Julia] Server returned non-JSON response';
104-
atom.notifications.addError(`${msg}. See console for more info`);
148+
atom.notifications.addError(`[Linter-Julia] server has likely crashed. Please check symbolserver.log.${process.pid}
149+
in the "linter-julia" shared Julia environment, and restart Atom.`);
105150
// eslint-disable-next-line no-console
106-
console.error(`${msg}: `, merged);
151+
console.error('server returned: ', merged);
107152
resolve(null);
108153
return;
109154
}
155+
if (parsed.length > 0) {
156+
if (parsed[0].description === 'I000') {
157+
atom.notifications.addInfo(`[Linter-Julia] generating symbols for the environment ${parsed[0].excerpt}, please wait ...`);
158+
parsed = [];
159+
}
160+
}
161+
162+
global.linter_julia_locked = false;
110163
resolve(parsed);
111164
});
112165
}));

0 commit comments

Comments
 (0)