diff --git a/README.rst b/README.rst
index 8ab9b27..8247f4b 100644
--- a/README.rst
+++ b/README.rst
@@ -13,15 +13,15 @@ which is useful for IT shops that develop in both of these languages.
Functionality
-------------
-* keeps the *setup.py* version in sync with the Maven project version by updating setup.py in the **process-sources** phase
-* packages the Python module during the Maven **package** phase
-* allows specifying which format should the Python module be distributed as: source, RPM, egg, tar, zip, etc.
+* Keeps the *setup.py* version in sync with the Maven project version by updating setup.py in the **process-sources** phase.
+* Packages the Python module during the Maven **package** phase.
+* Allows specifying which format should the Python module be distributed as: source, RPM, egg, tar, zip, etc.
+* Supports uploading packages to PyPI during the **deploy** phase.
Configuration
-------------
-Add the following to your *pom.xml* build section:
-::
+Add the following to your *pom.xml* build section::
maven-python-mojos
@@ -43,6 +43,45 @@ Add the following to your *pom.xml* build section:
+This defaults to building an egg file. If you would like to use another distribution type, you may specify something else::
+
+
+ package
+
+ package
+
+
+ rpm
+
+
+
+If you wish to build multiple different distribtion types, you can add multiple ```` blocks with different types.
+Supported types are egg, wheel, wininst, rpm, bdist, dumb, source, or docs.
+
+If you wish to upload your packaged files to PyPI, add the following::
+
+
+ deploy
+
+ deploy
+
+
+
+This will default to uploading all of the packages generated by the **package** goal. If you don't want that, you can specify
+a distribution type in the same way as you can for packaging. The deploy goal supports all distribution types except for docs.
+
+You can also optionally specify a repository to upload to::
+
+
+ deploy
+
+ deploy
+
+
+ https://pypi.myserver.com
+
+
+
setup.py
--------
@@ -50,12 +89,13 @@ To make the code runnable outside maven you can have a setup.py. If a setup-temp
your source root setup.py will be replaced.
setup-template.py
---------
+-----------------
-setup template allows for using maven controlled variables in your setup.py file.
+Setup template allows for using maven controlled variables in your setup.py file.
Set the *version* field in your *setup-template.py* to a hardcoded constant of **${VERSION}**, e.g.
Set the *name* field in your *setup-template.py* to a hardcoded constant of **${PROJECT_NAME}**, e.g.
::
+
from setuptools import setup, find_packages
setup(
@@ -65,13 +105,10 @@ Set the *name* field in your *setup-template.py* to a hardcoded constant of **${
packages = find_packages('.')
)
-
Maven Repository
----------------
-Add the following plugin repository to your *pom.xml* in order to use this plugin:
-
-::
+Add the following plugin repository to your *pom.xml* in order to use this plugin::
@@ -79,8 +116,3 @@ Add the following plugin repository to your *pom.xml* in order to use this plugi
https://jitpack.io
-
-
-
-
-
diff --git a/src/main/java/com/github/mojos/distribute/AbstractSetupCommandMojo.java b/src/main/java/com/github/mojos/distribute/AbstractSetupCommandMojo.java
new file mode 100644
index 0000000..c38669e
--- /dev/null
+++ b/src/main/java/com/github/mojos/distribute/AbstractSetupCommandMojo.java
@@ -0,0 +1,105 @@
+package com.github.mojos.distribute;
+
+/*
+ * Copyright 2001-2018 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Abstract class to run a setup.py command
+ */
+public abstract class AbstractSetupCommandMojo extends AbstractMojo {
+ /**
+ * @parameter default-value="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ /**
+ * @parameter default-value="python"
+ * @required
+ */
+ private String pythonExecutable;
+
+ /**
+ * Implementations should add any commands and arguments they wish to pass to setup.py here.
+ *
+ * @param args List to add setup.py commands to.
+ * @throws MojoExecutionException
+ */
+ abstract void addSetupArgs(List args) throws MojoExecutionException;
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.plugin.AbstractMojo#execute()
+ */
+ @Override
+ public void execute() throws MojoExecutionException {
+ final File buildDirectory = Paths.get(project.getBuild().getDirectory(), "maven-python").toFile();
+ final String setupOutputCanonicalPath = project.getProperties().getProperty("python.distribute.plugin.setup.path", "src/main/python/setup.py");
+
+ try {
+ List args = new ArrayList<>();
+ args.add(pythonExecutable);
+ args.add(setupOutputCanonicalPath);
+ addSetupArgs(args);
+ //execute setup script
+ ProcessBuilder processBuilder = new ProcessBuilder(args.toArray(new String[args.size()]));
+ processBuilder.directory(buildDirectory);
+
+ Process pr = processBuilder.start();
+ BufferedReader stdout = new BufferedReader(new InputStreamReader(pr.getInputStream()));
+ BufferedReader stderr = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
+ while (!pr.waitFor(100, TimeUnit.MILLISECONDS)) {
+ stdout.lines().forEachOrdered(line -> getLog().debug(line));
+ stderr.lines().forEachOrdered(line -> getLog().warn(line));
+ }
+
+ stdout.lines().forEachOrdered(line -> getLog().debug(line));
+ stderr.lines().forEachOrdered(line -> getLog().warn(line));
+
+ int exitCode = pr.exitValue();
+ if (exitCode != 0) {
+ throw new MojoExecutionException("'" + String.join(" ", processBuilder.command()) + "' returned error code " + exitCode);
+ }
+ } catch (FileNotFoundException e) {
+ throw new MojoExecutionException("Unable to find " + setupOutputCanonicalPath, e);
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to read " + setupOutputCanonicalPath, e);
+ } catch (InterruptedException e) {
+ throw new MojoExecutionException("Unable to execute python " + setupOutputCanonicalPath, e);
+ }
+ }
+
+ private void logErrorOrWarning(String line) {
+ if (line.toLowerCase().contains("error"))
+ getLog().error(line);
+ else
+ getLog().warn(line);
+ }
+}
diff --git a/src/main/java/com/github/mojos/distribute/DeployMojo.java b/src/main/java/com/github/mojos/distribute/DeployMojo.java
new file mode 100644
index 0000000..d9d5e38
--- /dev/null
+++ b/src/main/java/com/github/mojos/distribute/DeployMojo.java
@@ -0,0 +1,57 @@
+package com.github.mojos.distribute;
+
+/*
+ * Copyright 2001-2018 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Uploads a Python module to PyPI using distribute
+ *
+ * @goal deploy
+ * @phase deploy
+ */
+public class DeployMojo extends AbstractSetupCommandMojo {
+ /**
+ * @parameter
+ */
+ private String repository;
+
+ /**
+ * @parameter
+ */
+ private String distributionType;
+
+ static List builtDistributionTypes = Collections.synchronizedList(new ArrayList<>());
+
+ @Override
+ void addSetupArgs(List args) throws MojoExecutionException {
+ if (distributionType != null) {
+ args.add(PackageMojo.getDistributionTypeArg(distributionType));
+ } else {
+ args.addAll(builtDistributionTypes);
+ }
+ args.add("upload");
+ if (repository != null) {
+ args.add("-r");
+ args.add(repository);
+ }
+ }
+}
diff --git a/src/main/java/com/github/mojos/distribute/InstallMojo.java b/src/main/java/com/github/mojos/distribute/InstallMojo.java
index b34adac..4b645db 100644
--- a/src/main/java/com/github/mojos/distribute/InstallMojo.java
+++ b/src/main/java/com/github/mojos/distribute/InstallMojo.java
@@ -1,7 +1,7 @@
package com.github.mojos.distribute;
/*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-2018 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,55 +16,17 @@
* limitations under the License.
*/
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
+import java.util.List;
/**
* Installs a Python module using distribute
- *
+ *
* @goal install
* @phase install
*/
-public class InstallMojo extends AbstractMojo {
-
- /* (non-Javadoc)
- * @see org.apache.maven.plugin.AbstractMojo#execute()
- */
- public void execute() throws MojoExecutionException, MojoFailureException {
-
- File setup = new File("src/main/python/setup.py");
-
- try {
- //execute setup script
- ProcessBuilder t = new ProcessBuilder("python","setup.py","install");
- t.directory(new File("src/test/python"));
- t.redirectErrorStream(true);
-
- Process pr = t.start();
- int exitCode = pr.waitFor();
- BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
- String line = "";
- while ((line = buf.readLine()) != null) {
- getLog().info(line);
- }
-
- if (exitCode != 0) {
- throw new MojoExecutionException("'python setup.py install' returned error code " + exitCode);
- }
-
- } catch (FileNotFoundException e) {
- throw new MojoExecutionException("Unable to find " + setup.getPath(),e);
- } catch (IOException e) {
- throw new MojoExecutionException("Unable to read " + setup.getPath(),e);
- } catch (InterruptedException e) {
- throw new MojoExecutionException("Unable to execute python " + setup.getPath(),e);
- }
- }
+public class InstallMojo extends AbstractSetupCommandMojo {
+ @Override
+ void addSetupArgs(List args) {
+ args.add("install");
+ }
}
diff --git a/src/main/java/com/github/mojos/distribute/PackageMojo.java b/src/main/java/com/github/mojos/distribute/PackageMojo.java
index 61be848..710eb3b 100644
--- a/src/main/java/com/github/mojos/distribute/PackageMojo.java
+++ b/src/main/java/com/github/mojos/distribute/PackageMojo.java
@@ -1,7 +1,7 @@
package com.github.mojos.distribute;
/*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-2018 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,9 @@
* limitations under the License.
*/
-import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.project.MavenProject;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.file.Paths;
-import java.util.concurrent.TimeUnit;
+import java.util.List;
/**
* Packages a Python module using distribute
@@ -34,72 +26,39 @@
* @goal package
* @phase package
*/
-public class PackageMojo extends AbstractMojo {
- /**
- * @parameter default-value="${project}"
- * @required
- * @readonly
- */
- private MavenProject project;
-
- /**
- * @parameter default-value="python"
- * @required
- */
- private String pythonExecutable;
-
+public class PackageMojo extends AbstractSetupCommandMojo {
/**
* @parameter default-value="egg"
* @required
*/
private String distributionType;
+ static String getDistributionTypeArg(String distributionType) throws MojoExecutionException {
+ switch (distributionType) {
+ case "egg":
+ case "wheel":
+ case "wininst":
+ case "rpm":
+ case "dumb":
+ return "bdist_" + distributionType;
+ case "bdist":
+ return "bdist";
+ case "source":
+ return "sdist";
+ case "docs":
+ return "build_sphinx";
+ default:
+ throw new MojoExecutionException("Invalid distributionType (egg, wheel, wininst, rpm, bdist, dumb, source, or docs supported): " + distributionType);
+ }
+ }
+
/* (non-Javadoc)
* @see org.apache.maven.plugin.AbstractMojo#execute()
*/
@Override
- public void execute() throws MojoExecutionException {
- final File buildDirectory = Paths.get(project.getBuild().getDirectory(), "maven-python").toFile();
- final String setupOutputCanonicalPath = project.getProperties().getProperty("python.distribute.plugin.setup.path");
-
- try {
- String bdistName;
- switch(distributionType) {
- case "egg":
- bdistName = "bdist_egg";
- break;
- case "wheel":
- bdistName = "bdist_wheel";
- break;
- default:
- throw new MojoExecutionException("invalid distributionType (egg or wheel supported): " + distributionType);
- }
-
- //execute setup script
- ProcessBuilder processBuilder = new ProcessBuilder(pythonExecutable, setupOutputCanonicalPath, bdistName);
- processBuilder.directory(buildDirectory);
-
- Process pr = processBuilder.start();
- BufferedReader stdout = new BufferedReader(new InputStreamReader(pr.getInputStream()));
- BufferedReader stderr = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
- while (!pr.waitFor(100, TimeUnit.MILLISECONDS)) {
- stdout.lines().forEachOrdered(line->getLog().info(line));
- stderr.lines().forEachOrdered(line->getLog().error(line));
- }
-
- stdout.lines().forEachOrdered(line->getLog().debug(line));
- stderr.lines().forEachOrdered(line->getLog().warn(line));
-
- int exitCode = pr.exitValue();
- if (exitCode != 0) {
- throw new MojoExecutionException("python setup.py returned error code " + exitCode);
- }
- } catch (FileNotFoundException e) {
- throw new MojoExecutionException("Unable to find " + setupOutputCanonicalPath, e);
- } catch (IOException e) {
- throw new MojoExecutionException("Unable to read " + setupOutputCanonicalPath, e);
- } catch (InterruptedException e) {
- throw new MojoExecutionException("Unable to execute python " + setupOutputCanonicalPath, e);
- }
+ public void addSetupArgs(List args) throws MojoExecutionException {
+ String distributionTypeArg = getDistributionTypeArg(distributionType);
+ args.add(distributionTypeArg);
+ DeployMojo.builtDistributionTypes.add(distributionTypeArg);
}
}
\ No newline at end of file