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

Commit 6271d12

Browse files
committed
Prefer pipenv on project when possible
1 parent 1c14e4c commit 6271d12

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

lib/main.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import { CompositeDisposable } from 'atom';
1010
import path from 'path';
1111

12+
import { loadProjectConfig } from './pipenv';
13+
1214
const lazyReq = require('lazy-req')(require);
1315

1416
const { delimiter, dirname } = lazyReq('path')('delimiter', 'dirname');
@@ -111,8 +113,9 @@ export default {
111113
const fileDir = dirname(filePath);
112114
const fileText = editor.getText();
113115
const projectDir = getProjectDir(filePath);
116+
const pipEnvConfig = await loadProjectConfig(projectDir);
114117
const cwd = fixPathString(this.workingDirectory, fileDir, projectDir);
115-
const execPath = fixPathString(this.executablePath, '', projectDir);
118+
const execPath = pipEnvConfig.pylintExecutable || fixPathString(this.executablePath, '', projectDir);
116119
let format = this.messageFormat;
117120
const patterns = {
118121
'%m': 'msg',
@@ -124,10 +127,10 @@ export default {
124127
});
125128
const env = Object.create(process.env, {
126129
PYTHONPATH: {
127-
value: [
130+
value: pipEnvConfig.pythonPath.concat([
128131
process.env.PYTHONPATH,
129132
fixPathString(this.pythonPath, fileDir, projectDir),
130-
].filter(x => !!x).join(delimiter),
133+
]).filter(x => !!x).join(delimiter),
131134
enumerable: true,
132135
},
133136
LANG: { value: 'en_US.UTF-8', enumerable: true },

lib/pipenv.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use babel';
2+
3+
import { promisify } from 'util';
4+
import { stat } from 'fs';
5+
6+
const lazyReq = require('lazy-req')(require);
7+
8+
const { exec } = lazyReq('atom-linter')('exec');
9+
10+
import path from 'path';
11+
12+
let pipEnvAvailable = null;
13+
let pipEnvProjects = {};
14+
15+
const isPipEnvAvailable = async () => {
16+
if (pipEnvAvailable !== null) {
17+
return pipEnvAvailable;
18+
}
19+
pipEnvAvailable = await checkPipEnvAvailable();
20+
return pipEnvAvailable;
21+
};
22+
23+
const checkPipEnvAvailable = async () => {
24+
try {
25+
await exec('pipenv', ['--version']);
26+
return true;
27+
} catch (e) {
28+
return false;
29+
}
30+
};
31+
32+
const getPipEnvProject = projectDir => pipEnvProjects[projectDir] || null;
33+
34+
const readPipEnvVariable = async (lambda, defaultValue = null) => {
35+
try {
36+
return await lambda();
37+
} catch(error) {
38+
return defaultValue;
39+
}
40+
};
41+
42+
const loadProjectConfig = async (projectDir) => {
43+
const existingConfig = getPipEnvProject(projectDir);
44+
if (existingConfig) {
45+
return existingConfig;
46+
}
47+
48+
const config = {
49+
pylintExecutable: null,
50+
pythonPath: [],
51+
pipEnvHome: null,
52+
};
53+
54+
if (!(await isPipEnvAvailable())) {
55+
pipEnvProjects[projectDir] = config;
56+
return config;
57+
}
58+
59+
config.pipEnvHome = await readPipEnvVariable(async () => await exec('pipenv', ['--venv'], {
60+
cwd: projectDir,
61+
}));
62+
config.pythonPath = await readPipEnvVariable(async () => {
63+
const pipEnvArgs = [
64+
'run',
65+
'python',
66+
'-c',
67+
'import sys; import json; print(json.dumps(sys.path))'
68+
];
69+
return JSON.parse(await exec('pipenv', pipEnvArgs, {
70+
cwd: projectDir,
71+
}));
72+
}, []);
73+
config.pylintExecutable = config.pipEnvHome
74+
? await readPipEnvVariable(async () => {
75+
const path = path.join(config.pipEnvHome, 'bin', 'pylint');
76+
const stat = await promisify(stat)(path);
77+
return stat ? path : null;
78+
})
79+
: null;
80+
pipEnvProjects[projectDir] = config;
81+
return config;
82+
};
83+
84+
module.exports = {
85+
loadProjectConfig,
86+
getPipEnvProject,
87+
};

0 commit comments

Comments
 (0)