Skip to content

Commit

Permalink
Merge pull request #31 from TechnologyBrewery/30-add-reactor-support
Browse files Browse the repository at this point in the history
#30 ✨ incorporate Maven Reactor support
  • Loading branch information
d-ryan-ashcraft authored Aug 22, 2023
2 parents 84da034 + e0d95f8 commit ef90da3
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/maven.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
run: mvn -B install -Pbootstrap --file pom.xml

- name: Test habushu-maven-plugin
run: mvn -B test --file pom.xml
run: mvn -B install --file pom.xml

# Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
- name: Update dependency graph
Expand Down
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Habushu #
[![Maven Central](https://img.shields.io/maven-central/v/org.technologybrewery.habushu/habushu.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.technologybrewery.habushu%22%20AND%20a%3A%22habushu%22)
[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/mit)
[![Build (github)](https://github.com/TechnologyBrewery/habushu/actions/workflows/maven.yaml/badge.svg)](https://github.com/TechnologyBrewery/habushu/actions/workflows/maven.yaml) |
[![Build (github)](https://github.com/TechnologyBrewery/habushu/actions/workflows/maven.yaml/badge.svg)](https://github.com/TechnologyBrewery/habushu/actions/workflows/maven.yaml)

In Okinawa, habushu (pronounced HA-BU-SHU) is a sake that is made with venomous snake. The alcohol in the snake assists in dissolving the snake's venom and making it non-poinsonous. **In Maven, Habushu allows virtual environment-based Python projects to be included as part a Maven build. This brings some order and consistency to what can otherwise be haphazardly structured projects.**

Expand Down Expand Up @@ -214,7 +214,7 @@ Default: None

#### behaveExcludeManualTag ####

Exclude any BDD scenario or feature file tagged with `@manual`.
Exclude any BDD scenario or feature file tagged with `@manual`.

**NOTE:** If **behaveOptions** are provided, this property is ignored.

Expand Down Expand Up @@ -502,6 +502,16 @@ Determines if the build should be failed when managed dependency mismatches are

Default: `false`

#### mavenArtifactFile ####

Location of the artifact that will be published for this module. Maven wants to install an artifact with the pom file.
Habushu is really just interested in publishing the pom file for Maven Reactor use, but pushing an artifact makes this
process more smooth. This parameter can be updated to customize the artifact used. A placeholder file is explicitly
used as the default to prevent confusion if we published a real artifact (e.g., wheel file) that would never be used in
normal circumstances.

Default: `${project.basedir}/target/habushu.placeholder.txt`

## The Habushu Build Lifecycle ##

Habushu applies a [custom Maven lifecycle that binds Poetry-based DevSecOps workflow commands](https://fermenter.atlassian.net/wiki/spaces/HAB/pages/2056749057/Dependency+Management+and+Build+Automation+through+Poetry+and+Maven) to the following phases:
Expand Down Expand Up @@ -530,14 +540,29 @@ Uses [behave](https://github.com/behave/behave) to execute BDD scenarios that ar

Builds the `sdist` and `wheel` archives of this project using `poetry build`. It also generates a `requirements.txt` file which is useful when installing the package in a Docker container where you may want to install the dependencies in a specific Docker layer to optimize caching.

##### install #####
Publishes the `pom.xml` for the module into your local Maven Repository (`~/.m2/repository`).

##### deploy #####

Publishes the generated package archives to the specified PyPI repository (defined via **pypiRepoId** and **pypiRepoUrl**). If the current Habushu module is a `SNAPSHOT` version, temporarily set the version of the package to the appropriate developmental version, publish it to the specified PyPI repository, and then reset the version to the original value.
Publishes the generated package archives to the specified PyPI repository (defined via **pypiRepoId** and **pypiRepoUrl**).
If the current Habushu module is a `SNAPSHOT` version, temporarily set the version of the package to the appropriate
developmental version, publish it to the specified PyPI repository, and then reset the version to the original value.

Also publishes the `pom.xml` for the module into the configured Maven Repository.

##### clean #####

Deletes the folder in which archives generated by the **package** phase are placed (`dist`) and if **deleteVirtualEnv** is set to `true`, deletes the project's virtual environment.

### Maven Reactor Integration ###
Optionally, Habushu supports partial builds via the Maven Reactor. This allows functionality such as `-rf` (resume from)
by publishing Habushu POM files as part of the standard Maven `install` and `deploy` lifecylces. No artifacts (e.g.,
wheel files) are managed by Maven - those are solely handled via normal PyPI lookups. To leverage this functionality,
add in Habushu dependencies in your project's `pom.xml`. You can find an example in [`habushu-mixology-consumer/pom.xml`
where it references a dependency to `habushu-mixology`](https://github.com/TechnologyBrewery/habushu/blob/dev/habushu-mixology-consumer/pom.xml)
for Maven Reactor benefits.

## Common Issues ##

### Pyenv/Poetry Not Installed
Expand Down
10 changes: 10 additions & 0 deletions habushu-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-sec-dispatcher</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.technologybrewery.habushu;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -26,68 +28,94 @@
public class BuildDeploymentArtifactsMojo extends AbstractHabushuMojo {

/**
* By default, export requirements.txt file
* By default, export requirements.txt file.
*/
@Parameter(property = "habushu.exportRequirementsFile", required = false, defaultValue = "true")
protected boolean exportRequirementsFile;

/**
* By default, do not include the --without-urls flag when exporting
* By default, do not include the --without-urls flag when exporting.
*/
@Parameter(property = "habushu.exportRequirementsWithUrls", required = false, defaultValue = "true")
protected boolean exportRequirementsWithUrls;

/**
* By default, do not include the --without-hashes flag when exporting
* By default, do not include the --without-hashes flag when exporting.
*/
@Parameter(property = "habushu.exportRequirementsWithHashes", required = false, defaultValue = "true")
protected boolean exportRequirementsWithHashes;

/**
* By default, export to the dist folder to be included with the build archive
* By default, export to the dist folder to be included with the build archive.
*/
@Parameter(property = "habushu.exportRequirementsFolder", required = false, defaultValue = "${project.basedir}/dist")
protected String exportRequirementsFolder;

/**
* Location of the artifact that will be published for this module.
*/
@Parameter(property = "habushu.mavenArtifactFile", required = true, defaultValue = "${project.basedir}/target/habushu.placeholder.txt")
protected File mavenArtifactFile;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
PoetryCommandHelper poetryHelper = createPoetryCommandHelper();

String buildCommand, buildLogMessage;
if (this.rewriteLocalPathDepsInArchives) {
buildCommand = "build-rewrite-path-deps";
buildLogMessage = "Building source and wheel archives with poetry-monorepo-dependency-plugin...";
} else {
buildCommand = "build";
buildLogMessage = "Building source and wheel archives...";
}

getLog().info(buildLogMessage);
poetryHelper.executeAndLogOutput(Arrays.asList(buildCommand));

if (exportRequirementsFile) {
getLog().info("Exporting requirements.txt file...");

String outputFile = exportRequirementsFolder + "/requirements.txt";
File directory = new File(exportRequirementsFolder);
if (!directory.exists()) {
directory.mkdir();
}

List<String> command = new ArrayList<>();
command.add("export");
command.add("--output");
command.add(outputFile);

if (!exportRequirementsWithHashes) {
command.add("--without-hashes");
}

if (!exportRequirementsWithUrls) {
command.add("--without-urls");
}
poetryHelper.executeAndLogOutput(command);
}
PoetryCommandHelper poetryHelper = createPoetryCommandHelper();

String buildCommand, buildLogMessage;
if (this.rewriteLocalPathDepsInArchives) {
buildCommand = "build-rewrite-path-deps";
buildLogMessage = "Building source and wheel archives with poetry-monorepo-dependency-plugin...";
} else {
buildCommand = "build";
buildLogMessage = "Building source and wheel archives...";
}

getLog().info(buildLogMessage);
poetryHelper.executeAndLogOutput(Arrays.asList(buildCommand));

if (exportRequirementsFile) {
getLog().info("Exporting requirements.txt file...");

String outputFile = exportRequirementsFolder + "/requirements.txt";
File directory = new File(exportRequirementsFolder);
if (!directory.exists()) {
directory.mkdir();
}

List<String> command = new ArrayList<>();
command.add("export");
command.add("--output");
command.add(outputFile);

if (!exportRequirementsWithHashes) {
command.add("--without-hashes");
}

if (!exportRequirementsWithUrls) {
command.add("--without-urls");
}
poetryHelper.executeAndLogOutput(command);

setUpPlaceholderFileAsMavenArtifact();
}
}

protected void setUpPlaceholderFileAsMavenArtifact() {
mavenArtifactFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(mavenArtifactFile)) {
writer.println("This is NOT the file you are looking for!");
writer.println();
writer.println("To take advantage of the Maven Reactor, we want to publish pom files for this artifact.");
writer.println("But Maven isn't the right solution for managing Python dependencies.");
writer.println();
writer.println(String.format("Please check your appropriate Python repository for the %s files instead!",
project.getArtifactId()));

} catch (FileNotFoundException e) {
throw new RuntimeException("Could not create placeholder artifact file!", e);
}

project.getArtifact().setFile(mavenArtifactFile);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
<process-classes>org.technologybrewery.habushu:habushu-maven-plugin:${project.version}:format-python</process-classes>
<test>org.technologybrewery.habushu:habushu-maven-plugin:${project.version}:behave-bdd-test</test>
<package>org.technologybrewery.habushu:habushu-maven-plugin:${project.version}:build-deployment-artifacts</package>
<deploy>org.technologybrewery.habushu:habushu-maven-plugin:${project.version}:publish-to-pypi-repo</deploy>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>
org.technologybrewery.habushu:habushu-maven-plugin:${project.version}:publish-to-pypi-repo,
org.apache.maven.plugins:maven-deploy-plugin:deploy
</deploy>
</phases>
</lifecycle>
<lifecycle>
Expand All @@ -31,5 +35,19 @@
</lifecycles>
</configuration>
</component>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>habushu</role-hint>
<implementation>
org.apache.maven.artifact.handler.DefaultArtifactHandler
</implementation>
<configuration>
<type>habushu</type>
<extension>habushu.placeholder.txt</extension>
<packaging>habushu</packaging>
<language>python</language>
<addedToClasspath>false</addedToClasspath>
</configuration>
</component>
</components>
</component-set>
12 changes: 11 additions & 1 deletion habushu-mixology-consumer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<version>2.7.0-SNAPSHOT</version>
</parent>

<name>habushu::Mixing Drinks with Habushu consumer</name>
<name>habushu::Mixing Drinks with Habushu Consumer</name>
<description>Example of how to use the habushu-maven-plugin to consume other Habushu modules</description>

<artifactId>habushu-mixology-consumer</artifactId>
Expand Down Expand Up @@ -60,4 +60,14 @@
</build>
</profile>
</profiles>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>habushu-mixology</artifactId>
<version>${project.version}</version>
<type>habushu</type>
</dependency>
</dependencies>

</project>
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.technologybrewery</groupId>
<artifactId>parent</artifactId>
<version>3</version>
<version>5</version>
</parent>

<groupId>org.technologybrewery.habushu</groupId>
Expand Down

0 comments on commit ef90da3

Please sign in to comment.