mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
PY-20194: Use module root or test parent directory as working dir if not set explicitly.
Default workdir for PyCharm is its installation folder. Always never should it be used as working dir for script it runs. If user does not provide working dir, we must guess it. #getWorkingDirSafe() does this guess. It takes directory for script, directory for test or simply first module root. See its javadoc and usage for details.
This commit is contained in:
@@ -30,6 +30,7 @@ import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.options.SettingsEditorGroup;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
@@ -302,6 +303,7 @@ public abstract class AbstractPythonRunConfiguration<T extends AbstractPythonRun
|
||||
mySdkHome = sdkHome;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Module getModule() {
|
||||
return getConfigurationModule().getModule();
|
||||
}
|
||||
@@ -451,16 +453,34 @@ public abstract class AbstractPythonRunConfiguration<T extends AbstractPythonRun
|
||||
}
|
||||
|
||||
/**
|
||||
* @return working directory to run, never null, does its best to return project dir if empty.
|
||||
* Note to inheritors: Always check {@link #getWorkingDirectory()} first. You should return it, if it is not empty since
|
||||
* user should be able to set dir explicitly. Then, do your guess and return super as last resort.
|
||||
*
|
||||
* @return working directory to run, never null, does its best to guess which dir to use.
|
||||
* Unlike {@link #getWorkingDirectory()} it does not simply take directory from config.
|
||||
*/
|
||||
@NotNull
|
||||
public String getWorkingDirectorySafe() {
|
||||
final String result = StringUtil.isEmpty(myWorkingDirectory) ? getProject().getBasePath() : myWorkingDirectory;
|
||||
if (result == null) {
|
||||
return new File(".").getAbsolutePath();
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
|
||||
final String firstModuleRoot = getFirstModuleRoot();
|
||||
if (firstModuleRoot != null) {
|
||||
return firstModuleRoot;
|
||||
}
|
||||
return new File(".").getAbsolutePath();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getFirstModuleRoot() {
|
||||
final Module module = getModule();
|
||||
if (module == null) {
|
||||
return null;
|
||||
}
|
||||
final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots();
|
||||
return roots.length > 0 ? roots[0].getPath() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -66,6 +67,28 @@ public abstract class AbstractPythonTestRunConfiguration extends AbstractPythonR
|
||||
super(project, configurationFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWorkingDirectorySafe() {
|
||||
final String workingDirectoryFromConfig = getWorkingDirectory();
|
||||
if (StringUtil.isNotEmpty(workingDirectoryFromConfig)) {
|
||||
return workingDirectoryFromConfig;
|
||||
}
|
||||
|
||||
final String folderName = myFolderName;
|
||||
if (!StringUtil.isEmptyOrSpaces(folderName)) {
|
||||
return folderName;
|
||||
}
|
||||
final String scriptName = myScriptName;
|
||||
if (!StringUtil.isEmptyOrSpaces(scriptName)) {
|
||||
final VirtualFile script = LocalFileSystem.getInstance().findFileByPath(scriptName);
|
||||
if (script != null) {
|
||||
return script.getParent().getPath();
|
||||
}
|
||||
}
|
||||
return super.getWorkingDirectorySafe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
super.readExternal(element);
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.configurations.ParamsGroup;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.testframework.TestFrameworkRunningModel;
|
||||
import com.intellij.execution.testframework.autotest.ToggleAutoTestAction;
|
||||
import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView;
|
||||
@@ -32,10 +31,7 @@ import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.HelperPackage;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import com.jetbrains.python.console.PythonDebugLanguageConsoleView;
|
||||
@@ -112,20 +108,8 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt
|
||||
cmd.withWorkDirectory(workingDirectory);
|
||||
}
|
||||
else if (myConfiguration instanceof AbstractPythonTestRunConfiguration) {
|
||||
final String folderName = ((AbstractPythonTestRunConfiguration)myConfiguration).getFolderName();
|
||||
if (!StringUtil.isEmptyOrSpaces(folderName)) {
|
||||
cmd.withWorkDirectory(folderName);
|
||||
}
|
||||
else {
|
||||
final String scriptName = ((AbstractPythonTestRunConfiguration)myConfiguration).getScriptName();
|
||||
if (StringUtil.isEmptyOrSpaces(scriptName)) return;
|
||||
final VirtualFile script = LocalFileSystem.getInstance().findFileByPath(scriptName);
|
||||
if (script == null) return;
|
||||
cmd.withWorkDirectory(script.getParent().getPath());
|
||||
}
|
||||
}
|
||||
if (cmd.getWorkDirectory() == null) { // If current dir still not set, lets use project dir
|
||||
cmd.setWorkDirectory(myConfiguration.getWorkingDirectorySafe());
|
||||
final AbstractPythonTestRunConfiguration configuration = (AbstractPythonTestRunConfiguration)myConfiguration;
|
||||
cmd.withWorkDirectory(configuration.getWorkingDirectorySafe());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
@@ -76,6 +77,26 @@ public class PyTestRunConfiguration extends AbstractPythonTestRunConfiguration i
|
||||
return myTestToRun;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWorkingDirectorySafe() {
|
||||
final String workingDirectoryFromConfig = getWorkingDirectory();
|
||||
if (StringUtil.isNotEmpty(workingDirectoryFromConfig)) {
|
||||
return workingDirectoryFromConfig;
|
||||
}
|
||||
final String testToRun = myTestToRun;
|
||||
if (testToRun != null) {
|
||||
final VirtualFile path = LocalFileSystem.getInstance().findFileByPath(testToRun);
|
||||
if (path != null) {
|
||||
if (path.isDirectory()) {
|
||||
return path.getPath();
|
||||
}
|
||||
return path.getParent().getPath();
|
||||
}
|
||||
}
|
||||
return super.getWorkingDirectorySafe();
|
||||
}
|
||||
|
||||
public void setTestToRun(String testToRun) {
|
||||
myTestToRun = testToRun;
|
||||
}
|
||||
|
||||
4
python/testData/testRunner/env/pytest/dir_test.py
vendored
Normal file
4
python/testData/testRunner/env/pytest/dir_test.py
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import os
|
||||
|
||||
def test_test():
|
||||
print("Directory {0}".format(os.getcwd()))
|
||||
@@ -2,6 +2,7 @@ package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.MockPrinter;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.env.EnvTestTagsRequired;
|
||||
import com.jetbrains.env.PyEnvTestCase;
|
||||
import com.jetbrains.env.PyProcessWithConsoleTestTask;
|
||||
@@ -9,11 +10,13 @@ import com.jetbrains.env.ut.PyTestTestProcessRunner;
|
||||
import com.jetbrains.python.sdkTools.SdkCreationType;
|
||||
import com.jetbrains.python.testing.PythonTestConfigurationsModel;
|
||||
import com.jetbrains.python.testing.pytest.PyTestConfigurationProducer;
|
||||
import com.jetbrains.python.testing.pytest.PyTestRunConfiguration;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -52,6 +55,38 @@ public class PythonPyTestingTest extends PyEnvTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure project dir is used as curdir even if not set explicitly
|
||||
*/
|
||||
@Test
|
||||
public void testCurrentDir() throws Exception {
|
||||
runPythonTest(new PyProcessWithConsoleTestTask<PyTestTestProcessRunner>("/testRunner/env/pytest/", SdkCreationType.EMPTY_SDK) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyTestTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyTestTestProcessRunner("", 0) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull final PyTestRunConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
configuration.setWorkingDirectory(null);
|
||||
final VirtualFile fullFilePath = myFixture.getTempDirFixture().getFile("dir_test.py");
|
||||
assert fullFilePath != null : String.format("No dir_test.py in %s", myFixture.getTempDirFixture().getTempDirPath());
|
||||
configuration.setTestToRun(fullFilePath.getPath());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyTestTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertThat("No directory found in output", stdout,
|
||||
Matchers.containsString(String.format("Directory %s", myFixture.getTempDirPath())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPytestRunner() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user