load buildout paths from Buildout 1.5 site.py (PY-3169)

This commit is contained in:
Dmitry Jemerov
2011-03-22 16:45:55 +01:00
parent 6c5fa4bb8e
commit a966f4ef03
4 changed files with 126 additions and 29 deletions
@@ -122,7 +122,7 @@ public class BuildoutConfigurable implements Configurable, NonDefaultProjectConf
if (script_file == null || script_file.isDirectory()) {
throw new ConfigurationException("Invalid script file '" + script_name + "'");
}
paths_from_script = BuildoutFacet.extractFromScript(script_file);
paths_from_script = BuildoutFacet.extractBuildoutPaths(script_file);
if (paths_from_script == null) {
throw new ConfigurationException("Failed to extract paths from '" + script_file.getPresentableName() + "'");
}
@@ -11,6 +11,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiFile;
@@ -42,6 +43,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.buildout.BuildoutFacet");
@NonNls public static final String BUILDOUT_CFG = "buildout.cfg";
@NonNls public static final String SCRIPT_SUFFIX = "-script";
public BuildoutFacet(@NotNull final FacetType facetType,
@NotNull final Module module,
@@ -113,7 +115,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
BuildoutFacetConfiguration config = getConfiguration();
final VirtualFile script = getScript();
if (script != null) {
config.setPaths(extractFromScript(script));
config.setPaths(extractBuildoutPaths(script));
}
}
@@ -122,6 +124,29 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
return LocalFileSystem.getInstance().findFileByPath(getConfiguration().getScriptName());
}
@Nullable
public static List<String> extractBuildoutPaths(@NotNull VirtualFile script) {
try {
List<String> paths = extractFromScript(script);
if (paths == null) {
VirtualFile root = script.getParent().getParent();
String partName = FileUtil.getNameWithoutExtension(script.getName());
if (SystemInfo.isWindows && partName.endsWith(SCRIPT_SUFFIX)) {
partName = partName.substring(0, partName.length() - SCRIPT_SUFFIX.length());
}
VirtualFile sitePy = root.findFileByRelativePath("parts/" + partName + "/site.py");
if (sitePy != null) {
paths = extractFromSitePy(sitePy);
}
}
return paths;
}
catch(IOException e) {
LOG.info(e);
return null;
}
}
/**
* Extracts paths from given script, assuming sys.path[0:0] assignment.
*
@@ -129,39 +154,61 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
* @return extracted paths, or null if extraction fails.
*/
@Nullable
public static List<String> extractFromScript(VirtualFile script) {
assert script != null;
List<String> ret = new LinkedList<String>();
try {
String text = VfsUtil.loadText(script);
Pattern pat = Pattern.compile("(?:^\\s*(['\"])(.*)(\\1),\\s*$)|(\\])", Pattern.MULTILINE);
final String bait_string = "sys.path[0:0]";
int pos = text.indexOf(bait_string);
if (pos >= 0) {
pos += bait_string.length();
Matcher scanner = pat.matcher(text);
boolean did_nothing = true;
while (scanner.find(pos)) {
did_nothing = false;
String value = scanner.group(2);
if (value != null) {
ret.add(value);
pos = scanner.end();
public static List<String> extractFromScript(@NotNull VirtualFile script) throws IOException {
String text = VfsUtil.loadText(script);
Pattern pat = Pattern.compile("(?:^\\s*(['\"])(.*)(\\1),\\s*$)|(\\])", Pattern.MULTILINE);
final String bait_string = "sys.path[0:0]";
int pos = text.indexOf(bait_string);
List<String> ret = null;
if (pos >= 0) {
pos += bait_string.length();
Matcher scanner = pat.matcher(text);
while (scanner.find(pos)) {
String value = scanner.group(2);
if (value != null) {
if (ret == null) {
ret = new ArrayList<String>();
}
else {
break;
} // we've matched the ']', it's group(4)
ret.add(value);
pos = scanner.end();
}
if (did_nothing) return null;
else {
break;
} // we've matched the ']', it's group(4)
}
}
catch (IOException e) {
LOG.error("Failed to read script", e);
return null;
}
return ret;
}
/**
* Extracts paths from site.py generated by buildout 1.5+
*
* @param vFile path to site.py
* @return extracted paths
*/
public static List<String> extractFromSitePy(VirtualFile vFile) throws IOException {
List<String> result = new ArrayList<String>();
String text = VfsUtil.loadText(vFile);
String[] lines = LineTokenizer.tokenize(text, false);
int index = 0;
while(index < lines.length && !lines [index].startsWith("def addsitepackages("))
index++;
while(index < lines.length && !lines [index].trim().startsWith("buildout_paths = ["))
index++;
index++;
while(index < lines.length && !lines [index].trim().equals("]")) {
String line = lines [index].trim();
if (line.endsWith(",")) {
line = line.substring(0, line.length()-1);
}
if (line.startsWith("'") && line.endsWith("'")) {
result.add(StringUtil.unescapeStringCharacters(line.substring(1, line.length()-1)));
}
index++;
}
return result;
}
@Override
public List<String> getAdditionalPythonPath() {
BuildoutFacetConfiguration cfg = getConfiguration();
@@ -261,7 +308,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
@Nullable
public static File findScript(Project project, @Nullable BuildoutFacet buildoutFacet, String name) {
String scriptName = SystemInfo.isWindows ? name + "-script" : name;
String scriptName = SystemInfo.isWindows ? name + SCRIPT_SUFFIX : name;
final List<File> scripts = getScripts(project, buildoutFacet);
for (File script : scripts) {
if (FileUtil.getNameWithoutExtension(script.getName()).equals(scriptName)) {
+18
View File
@@ -0,0 +1,18 @@
#!"C:\Python26\python.exe"
import sys
sys.path[0:0] = [
'c:\\src\\django\\buildout15\\src',
'c:\\src\\django\\buildout15\\eggs\\djangorecipe-0.20-py2.6.egg',
'c:\\src\\django\\buildout15\\eggs\\zc.recipe.egg-1.3.2-py2.6.egg',
'c:\\src\\django\\buildout15\\eggs\\zc.buildout-1.5.2-py2.6.egg',
'c:\\src\\django\\buildout15\\eggs\\setuptools-0.6c12dev_r88124-py2.6.egg',
'c:\\src\\django\\buildout15\\parts\\django',
'c:\\src\\django\\buildout15',
]
import djangorecipe.manage
if __name__ == '__main__':
djangorecipe.manage.main('shorturls.testsettings')
@@ -0,0 +1,32 @@
package com.jetbrains.python.buildout;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* @author yole
*/
public class BuildoutScriptParserTest extends PyLightFixtureTestCase {
public void testParseOldStyleScript() throws IOException {
File scriptFile = new File(myFixture.getTestDataPath(), "buildout/django-script.py");
VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(scriptFile);
List<String> paths = BuildoutFacet.extractFromScript(vFile);
assertEquals(7, paths.size());
assertTrue(paths.contains("c:\\\\src\\\\django\\\\buildout15\\\\eggs\\\\djangorecipe-0.20-py2.6.egg"));
assertTrue(paths.contains("c:\\\\src\\\\django\\\\buildout15\\\\parts\\\\django"));
}
public void testParseSitePy() throws IOException {
File scriptFile = new File(myFixture.getTestDataPath(), "buildout/site.py");
VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(scriptFile);
List<String> paths = BuildoutFacet.extractFromSitePy(vFile);
assertSameElements(paths,
"c:\\src\\django\\buildout15\\src",
"c:\\src\\django\\buildout15\\eggs\\setuptools-0.6c12dev_r88124-py2.6.egg");
}
}