All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.steady.python.virtualenv.VirtualenvWrapper Maven / Gradle / Ivy

There is a newer version: 3.2.5
Show newest version
/**
 * This file is part of Eclipse Steady.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors
 */
package org.eclipse.steady.python.virtualenv;

import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.Set;

import org.apache.logging.log4j.Logger;
import org.eclipse.steady.python.ProcessWrapperException;
import org.eclipse.steady.python.pip.PipInstalledPackage;
import org.eclipse.steady.python.pip.PipWrapper;
import org.eclipse.steady.python.pip.PyWrapper;
import org.eclipse.steady.python.utils.PythonConfiguration;
import org.eclipse.steady.shared.util.DirUtil;
import org.eclipse.steady.shared.util.FileUtil;
import org.eclipse.steady.shared.util.VulasConfiguration;

/**
 * 

VirtualenvWrapper class.

*/ public class VirtualenvWrapper { private static final String SETUP_PY = "setup.py"; private static final boolean IS_WIN = System.getProperty("os.name").contains("Windows"); private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); private Path pathToVirtualenvExecutable = null; private Path pathToPythonProject = null; private String projectName = null; private Path pathToVirtualenv = null; private Set installedPackages = null; /** * Assumes that the virtualenv executable is part of the PATH environment variable. * * @param _path_to_python_project a {@link java.nio.file.Path} object. * @throws java.lang.IllegalArgumentException if any. * @throws org.eclipse.steady.python.ProcessWrapperException if any. */ public VirtualenvWrapper(Path _path_to_python_project) throws IllegalArgumentException, ProcessWrapperException { this(Paths.get("virtualenv"), _path_to_python_project); } /** * Creates a virtual environment for the project located at the given path. * This path is expected to contain a setup.py file. * * @param _path_to_virtualenv a {@link java.nio.file.Path} object. * @param _path_to_python_project a {@link java.nio.file.Path} object. * @throws java.lang.IllegalArgumentException if any. * @throws org.eclipse.steady.python.ProcessWrapperException if any. */ public VirtualenvWrapper(Path _path_to_virtualenv, Path _path_to_python_project) throws IllegalArgumentException, ProcessWrapperException { // Check it is a directory with a file "setup.py" if (!FileUtil.isAccessibleDirectory(_path_to_python_project)) throw new IllegalArgumentException( "Project path [" + _path_to_python_project + "] does not point to an accessible directory"); if (!DirUtil.containsFile(_path_to_python_project.toFile(), SETUP_PY)) throw new IllegalArgumentException( "Project path [" + _path_to_python_project + "] does not contain the file [" + SETUP_PY + "]"); this.pathToVirtualenvExecutable = _path_to_virtualenv; this.pathToPythonProject = _path_to_python_project.toAbsolutePath(); this.projectName = this.pathToPythonProject.getName(this.pathToPythonProject.getNameCount() - 1).toString(); // Create the virtualenv try { this.pathToVirtualenv = FileUtil.createTmpDir("vulas-virtualenv-" + this.projectName + "-").toAbsolutePath(); } catch (IOException e) { throw new ProcessWrapperException("Cannot create tmp directory: " + e.getMessage()); } this.createVirtualenvForProject(this.pathToVirtualenv); // Copy the project folder this.copyProjectDirectory(); // Create Vulas directories vulas/log and vulas/download // Call PIP install final Path prj_path = Paths.get(this.pathToVirtualenv.toString(), this.projectName); installedPackages = this.getPipWrapper().installPackages(prj_path); // Call setup // final Path setup_path = Paths.get(this.pathToVirtualenv.toString(), this.projectName, // SETUP_PY); // this.getPyWrapper().runScript(setup_path, Arrays.asList(new String[] {"install"})); } /** *

Getter for the field projectName.

* * @return a {@link java.lang.String} object. */ public String getProjectName() { return projectName; } /** *

Getter for the field pathToVirtualenv.

* * @return a {@link java.nio.file.Path} object. */ public Path getPathToVirtualenv() { return pathToVirtualenv; } /** *

Getter for the field installedPackages.

* * @return a {@link java.util.Set} object. */ public Set getInstalledPackages() { return this.installedPackages; } /** *

getPipWrapper.

* * @return a {@link org.eclipse.steady.python.pip.PipWrapper} object. * @throws org.eclipse.steady.python.ProcessWrapperException if any. */ public PipWrapper getPipWrapper() throws ProcessWrapperException { if (IS_WIN) return new PipWrapper( Paths.get(this.pathToVirtualenv.toString(), "Scripts", "pip"), this.pathToVirtualenv); else return new PipWrapper( Paths.get(this.pathToVirtualenv.toString(), "bin", "pip"), this.pathToVirtualenv); } /** *

getPyWrapper.

* * @return a {@link org.eclipse.steady.python.pip.PyWrapper} object. * @throws org.eclipse.steady.python.ProcessWrapperException if any. */ public PyWrapper getPyWrapper() throws ProcessWrapperException { if (IS_WIN) return new PyWrapper( Paths.get(this.pathToVirtualenv.toString(), "Scripts", "python"), this.pathToVirtualenv); else return new PyWrapper( Paths.get(this.pathToVirtualenv.toString(), "bin", "python"), this.pathToVirtualenv); } /** * Creates a virtual environment for the project located at the given path in a temporary directory. * @param _project_path */ private void createVirtualenvForProject(Path _path_to_virtual_env) throws ProcessWrapperException { Path ve = null; try { log.info("Create virtualenv in [" + _path_to_virtual_env + "]"); // Create the virtual env inside this temp directory ProcessBuilder pb = null; if (VulasConfiguration.getGlobal().isEmpty(PythonConfiguration.PY_PY_PATH)) { pb = new ProcessBuilder( this.pathToVirtualenvExecutable.toString(), _path_to_virtual_env.toString()); } else { pb = new ProcessBuilder( this.pathToVirtualenvExecutable.toString(), "--python", VulasConfiguration.getGlobal() .getConfiguration() .getString(PythonConfiguration.PY_PY_PATH), _path_to_virtual_env.toString()); } // Create temp. directory for out and err streams final Path out = Paths.get(_path_to_virtual_env.toString(), "virtualenv-out.txt"); final Path err = Paths.get(_path_to_virtual_env.toString(), "virtualenv-err.txt"); // Redirect out and err pb.redirectOutput(out.toFile()); pb.redirectError(err.toFile()); // Start and wait final Process process = pb.start(); final int exit_code = process.waitFor(); // Success if (exit_code != 0) { final String error_msg = FileUtil.readFile(err); throw new ProcessWrapperException(error_msg); } } catch (IOException e) { throw new ProcessWrapperException(e.getMessage(), e); } catch (InterruptedException e) { throw new ProcessWrapperException(e.getMessage(), e); } } private Path copyProjectDirectory() throws ProcessWrapperException { Path new_dir = null; try { Files.walkFileTree( this.pathToPythonProject, new HashSet(), Integer.MAX_VALUE, new CopyFileVisitor(this.pathToPythonProject, this.pathToVirtualenv)); } catch (Exception e) { new_dir = null; log.error( "Cannot copy project dir [" + this.pathToPythonProject + "] to virtual env [" + this.pathToVirtualenvExecutable + "]:" + e.getMessage()); throw new ProcessWrapperException( "Cannot copy project dir [" + this.pathToPythonProject + "] to virtual env [" + this.pathToVirtualenvExecutable + "]:" + e.getMessage()); } return new_dir; } private static class CopyFileVisitor extends SimpleFileVisitor { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); private Path src = null; private Path tgt = null; public CopyFileVisitor(Path _src, Path _tgt) { this.src = _src; this.tgt = _tgt; } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { final Path relp = this.src.getParent().relativize(dir.toAbsolutePath()); final Path newp = Paths.get(tgt.toString(), relp.toString()); try { Files.createDirectories(newp); } catch (Exception e) { log.error("Cannot copy [" + dir + "] to [" + newp + "]: " + e.getMessage()); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { final Path relp = this.src.getParent().relativize(file); final Path newf = Paths.get(this.tgt.toString(), relp.toString()); try { Files.copy(file, newf); } catch (Exception e) { log.error("Cannot copy [" + file + "] to [" + newf + "]: " + e.getMessage()); } return FileVisitResult.CONTINUE; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy