Skip to content

Commit

Permalink
DCA11Y-1315: Use PAC mirrors where possible
Browse files Browse the repository at this point in the history
Excuse the factoring, it's got enough spaghetti for a whole 'nother generation of Eminem memes. Why? Trying to make it easy to update from upstream. If I was to refactor the existing code we're more likely to get merge-conflicts. I don't see us ever being able to upstream this change so it doesn't make sense for the diff to be optimised for that.
  • Loading branch information
atl-mk committed Oct 19, 2024
1 parent 3a101cc commit 86b0dc9
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 66 deletions.
6 changes: 6 additions & 0 deletions frontend-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
<artifactId>plexus-build-api</artifactId>
<version>0.0.7</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.github.eirslett.maven.plugins.frontend.mojo;

import org.apache.maven.project.MavenProject;

import javax.annotation.Nonnull;
import javax.naming.OperationNotSupportedException;

import static java.util.Objects.requireNonNull;

public class AtlassianUtil {
private AtlassianUtil() throws OperationNotSupportedException {
throw new OperationNotSupportedException("my dude, this is a util class");
}

public static boolean isAtlassianProject(@Nonnull MavenProject mavenProject) {
requireNonNull(mavenProject, "mavenProject");

// Ordered by likelihood
if (containsAtlassian(mavenProject.getGroupId()) ||
containsAtlassian(mavenProject.getVersion()) || // we have forks with original coordinates
containsAtlassian(mavenProject.getArtifactId())) {
return true;
}

// I don't think I'm missing anything here for forks that have a frontend??
// AO plugin, Greenhopper, and Ridalabs all have Atlassian group IDs now
// Please take mercy on me and don't be offended if I forgot something

return false;
}

private static boolean containsAtlassian(@Nonnull String string) {
requireNonNull(string, "string");

return string.toLowerCase().contains("atlassian");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.github.eirslett.maven.plugins.frontend.mojo;

import com.github.eirslett.maven.plugins.frontend.lib.ArchiveExtractionException;
import com.github.eirslett.maven.plugins.frontend.lib.DownloadException;
import com.github.eirslett.maven.plugins.frontend.lib.FrontendPluginFactory;
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.NPMInstaller;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionDetector;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper;
Expand All @@ -14,7 +17,11 @@
import org.apache.maven.settings.Server;
import org.apache.maven.settings.crypto.SettingsDecrypter;

import static com.github.eirslett.maven.plugins.frontend.lib.NPMInstaller.ATLASSIAN_NPM_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeInstaller.ATLASSIAN_NODE_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper.getDownloadableVersion;
import static com.github.eirslett.maven.plugins.frontend.lib.Utils.isBlank;
import static com.github.eirslett.maven.plugins.frontend.mojo.AtlassianUtil.isAtlassianProject;
import static java.util.Objects.isNull;

@Mojo(name="install-node-and-npm", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true)
Expand All @@ -29,7 +36,7 @@ public final class InstallNodeAndNpmMojo extends AbstractFrontendMojo {
/**
* Where to download NPM binary from. Defaults to https://registry.npmjs.org/npm/-/
*/
@Parameter(property = "npmDownloadRoot", required = false, defaultValue = NPMInstaller.DEFAULT_NPM_DOWNLOAD_ROOT)
@Parameter(property = "npmDownloadRoot", required = false)
private String npmDownloadRoot;

/**
Expand Down Expand Up @@ -84,11 +91,6 @@ protected boolean skipExecution() {

@Override
public void execute(FrontendPluginFactory factory) throws Exception {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(session, decrypter);
String nodeDownloadRoot = getNodeDownloadRoot();
String npmDownloadRoot = getNpmDownloadRoot();
Server server = MojoUtils.decryptServer(serverId, session, decrypter);

String nodeVersion = NodeVersionDetector.getNodeVersion(workingDirectory, this.nodeVersion, this.nodeVersionFile);

if (isNull(nodeVersion)) {
Expand All @@ -101,6 +103,41 @@ public void execute(FrontendPluginFactory factory) throws Exception {

String validNodeVersion = getDownloadableVersion(nodeVersion);

final String nodeDownloadRoot = getNodeDownloadRoot();
final String npmDownloadRoot = getNpmDownloadRoot();

if (isAtlassianProject(project) &&
isBlank(serverId) &&
(isBlank(nodeDownloadRoot) || isBlank(npmDownloadRoot))
) { // If they're overridden the settings, they be the boss
getLog().info("Atlassian project detected, going to use the internal mirrors (requires VPN)");

serverId = "maven-atlassian-com";
try {
install(factory, validNodeVersion,
isBlank(nodeDownloadRoot) ? ATLASSIAN_NODE_DOWNLOAD_ROOT : nodeDownloadRoot,
isBlank(npmDownloadRoot) ? ATLASSIAN_NPM_DOWNLOAD_ROOT : npmDownloadRoot);
return;
} catch (InstallationException exception) {
// Ignore as many filesystem exceptions unrelated to the mirror easily
if (!(exception.getCause() instanceof DownloadException ||
exception.getCause() instanceof ArchiveExtractionException)) {
throw exception;
}
getLog().warn("Oh no couldn't use the internal mirrors! Falling back to upstream mirrors");
getLog().debug("Using internal mirrors failed because: ", exception);
} finally {
serverId = null;
}
}

install(factory, validNodeVersion, nodeDownloadRoot, npmDownloadRoot);
}

private void install(FrontendPluginFactory factory, String validNodeVersion, String nodeDownloadRoot, String npmDownloadRoot) throws InstallationException {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(session, decrypter);
Server server = MojoUtils.decryptServer(serverId, session, decrypter);

if (null != server) {
factory.getNodeInstaller(proxyConfig)
.setNodeVersion(validNodeVersion)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.github.eirslett.maven.plugins.frontend.mojo;

import com.github.eirslett.maven.plugins.frontend.lib.ArchiveExtractionException;
import com.github.eirslett.maven.plugins.frontend.lib.DownloadException;
import com.github.eirslett.maven.plugins.frontend.lib.FrontendPluginFactory;
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionDetector;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper;
import com.github.eirslett.maven.plugins.frontend.lib.PnpmInstaller;
Expand All @@ -14,7 +17,11 @@
import org.apache.maven.settings.Server;
import org.apache.maven.settings.crypto.SettingsDecrypter;

import static com.github.eirslett.maven.plugins.frontend.lib.NPMInstaller.ATLASSIAN_NPM_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeInstaller.ATLASSIAN_NODE_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper.getDownloadableVersion;
import static com.github.eirslett.maven.plugins.frontend.lib.Utils.isBlank;
import static com.github.eirslett.maven.plugins.frontend.mojo.AtlassianUtil.isAtlassianProject;
import static java.util.Objects.isNull;

@Mojo(name="install-node-and-pnpm", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true)
Expand All @@ -29,7 +36,7 @@ public final class InstallNodeAndPnpmMojo extends AbstractFrontendMojo {
/**
* Where to download pnpm binary from. Defaults to https://registry.npmjs.org/pnpm/-/
*/
@Parameter(property = "pnpmDownloadRoot", required = false, defaultValue = PnpmInstaller.DEFAULT_PNPM_DOWNLOAD_ROOT)
@Parameter(property = "pnpmDownloadRoot", required = false)
private String pnpmDownloadRoot;

/**
Expand Down Expand Up @@ -85,16 +92,6 @@ protected boolean skipExecution() {

@Override
public void execute(FrontendPluginFactory factory) throws Exception {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(session, decrypter);
// Use different names to avoid confusion with fields `nodeDownloadRoot` and
// `pnpmDownloadRoot`.
//
// TODO: Remove the `downloadRoot` config (with breaking change) to simplify download root
// resolution.
String resolvedNodeDownloadRoot = getNodeDownloadRoot();
String resolvedPnpmDownloadRoot = getPnpmDownloadRoot();
Server server = MojoUtils.decryptServer(serverId, session, decrypter);

String nodeVersion = NodeVersionDetector.getNodeVersion(workingDirectory, this.nodeVersion, this.nodeVersionFile);

if (isNull(nodeVersion)) {
Expand All @@ -107,6 +104,46 @@ public void execute(FrontendPluginFactory factory) throws Exception {

String validNodeVersion = getDownloadableVersion(nodeVersion);

// Use different names to avoid confusion with fields `nodeDownloadRoot` and
// `pnpmDownloadRoot`.
//
// TODO: Remove the `downloadRoot` config (with breaking change) to simplify download root
// resolution.
String resolvedNodeDownloadRoot = getNodeDownloadRoot();
String resolvedPnpmDownloadRoot = getPnpmDownloadRoot();

if (isAtlassianProject(project) &&
isBlank(serverId) &&
(isBlank(resolvedNodeDownloadRoot) || isBlank(resolvedPnpmDownloadRoot))
) { // If they're overridden the settings, they be the boss
getLog().info("Atlassian project detected, going to use the internal mirrors (requires VPN)");

serverId = "maven-atlassian-com";
try {
install(factory, validNodeVersion,
isBlank(resolvedNodeDownloadRoot) ? ATLASSIAN_NODE_DOWNLOAD_ROOT : resolvedNodeDownloadRoot,
isBlank(resolvedPnpmDownloadRoot) ? ATLASSIAN_NPM_DOWNLOAD_ROOT : resolvedPnpmDownloadRoot);
return;
} catch (InstallationException exception) {
// Ignore as many filesystem exceptions unrelated to the mirror easily
if (!(exception.getCause() instanceof DownloadException ||
exception.getCause() instanceof ArchiveExtractionException)) {
throw exception;
}
getLog().warn("Oh no couldn't use the internal mirrors! Falling back to upstream mirrors");
getLog().debug("Using internal mirrors failed because: ", exception);
} finally {
serverId = null;
}
}

install(factory, validNodeVersion, resolvedNodeDownloadRoot, resolvedPnpmDownloadRoot);
}

private void install(FrontendPluginFactory factory, String validNodeVersion, String resolvedNodeDownloadRoot, String resolvedPnpmDownloadRoot) throws InstallationException {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(session, decrypter);
Server server = MojoUtils.decryptServer(serverId, session, decrypter);

if (null != server) {
factory.getNodeInstaller(proxyConfig)
.setNodeVersion(validNodeVersion)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.github.eirslett.maven.plugins.frontend.mojo;

import com.github.eirslett.maven.plugins.frontend.lib.ArchiveExtractionException;
import com.github.eirslett.maven.plugins.frontend.lib.DownloadException;
import com.github.eirslett.maven.plugins.frontend.lib.FrontendPluginFactory;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionDetector;
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper;
import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;
import com.github.eirslett.maven.plugins.frontend.lib.YarnInstaller;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.plugins.annotations.Component;
Expand All @@ -14,7 +15,12 @@
import org.apache.maven.settings.Server;
import org.apache.maven.settings.crypto.SettingsDecrypter;

import static com.github.eirslett.maven.plugins.frontend.lib.NodeInstaller.ATLASSIAN_NODE_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeVersionDetector.getNodeVersion;
import static com.github.eirslett.maven.plugins.frontend.lib.NodeVersionHelper.getDownloadableVersion;
import static com.github.eirslett.maven.plugins.frontend.lib.Utils.isBlank;
import static com.github.eirslett.maven.plugins.frontend.lib.YarnInstaller.ATLASSIAN_YARN_DOWNLOAD_ROOT;
import static com.github.eirslett.maven.plugins.frontend.mojo.AtlassianUtil.isAtlassianProject;
import static com.github.eirslett.maven.plugins.frontend.mojo.YarnUtils.isYarnrcYamlFilePresent;
import static java.util.Objects.isNull;

Expand All @@ -32,8 +38,7 @@ public final class InstallNodeAndYarnMojo extends AbstractFrontendMojo {
/**
* Where to download Yarn binary from. Defaults to https://github.com/yarnpkg/yarn/releases/download/...
*/
@Parameter(property = "yarnDownloadRoot", required = false,
defaultValue = YarnInstaller.DEFAULT_YARN_DOWNLOAD_ROOT)
@Parameter(property = "yarnDownloadRoot", required = false)
private String yarnDownloadRoot;

/**
Expand Down Expand Up @@ -80,10 +85,7 @@ protected boolean skipExecution() {

@Override
public void execute(FrontendPluginFactory factory) throws Exception {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(this.session, this.decrypter);
Server server = MojoUtils.decryptServer(this.serverId, this.session, this.decrypter);

String nodeVersion = NodeVersionDetector.getNodeVersion(workingDirectory, this.nodeVersion, this.nodeVersionFile);
String nodeVersion = getNodeVersion(workingDirectory, this.nodeVersion, this.nodeVersionFile);

if (isNull(nodeVersion)) {
throw new LifecycleExecutionException("Node version could not be detected from a file and was not set");
Expand All @@ -97,6 +99,47 @@ public void execute(FrontendPluginFactory factory) throws Exception {

boolean isYarnYamlFilePresent = isYarnrcYamlFilePresent(this.session, this.workingDirectory);

if (isAtlassianProject(project) &&
isBlank(serverId) &&
(isBlank(nodeDownloadRoot) || isBlank(yarnDownloadRoot))
) { // If they're overridden the settings, they be the boss
getLog().info("Atlassian project detected, going to use the internal mirrors (requires VPN)");

serverId = "maven-atlassian-com";
final String userSetYarnDownloadRoot = yarnDownloadRoot;
if (isBlank(yarnDownloadRoot)) {
yarnDownloadRoot = ATLASSIAN_YARN_DOWNLOAD_ROOT;
}
final String userSetNodeDownloadRoot = nodeDownloadRoot;
if (isBlank(nodeDownloadRoot)) {
nodeDownloadRoot = ATLASSIAN_NODE_DOWNLOAD_ROOT;
}

try {
install(factory, validNodeVersion, isYarnYamlFilePresent);
return;
} catch (InstallationException exception) {
// Ignore as many filesystem exceptions unrelated to the mirror easily
if (!(exception.getCause() instanceof DownloadException ||
exception.getCause() instanceof ArchiveExtractionException)) {
throw exception;
}
getLog().warn("Oh no couldn't use the internal mirrors! Falling back to upstream mirrors");
getLog().debug("Using internal mirrors failed because: ", exception);
} finally {
nodeDownloadRoot = userSetNodeDownloadRoot;
yarnDownloadRoot = userSetYarnDownloadRoot;
serverId = null;
}
}

install(factory, validNodeVersion, isYarnYamlFilePresent);
}

private void install(FrontendPluginFactory factory, String validNodeVersion, boolean isYarnYamlFilePresent) throws InstallationException {
ProxyConfig proxyConfig = MojoUtils.getProxyConfig(this.session, this.decrypter);
Server server = MojoUtils.decryptServer(this.serverId, this.session, this.decrypter);

if (null != server) {
factory.getNodeInstaller(proxyConfig).setNodeDownloadRoot(this.nodeDownloadRoot)
.setNodeVersion(validNodeVersion).setPassword(server.getPassword())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.github.eirslett.maven.plugins.frontend.lib;

public class ArchiveExtractionException extends Exception {

ArchiveExtractionException(String message) {
super(message);
}

ArchiveExtractionException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ArchiveExtractionException extends Exception {

ArchiveExtractionException(String message) {
super(message);
}

ArchiveExtractionException(String message, Throwable cause) {
super(message, cause);
}
}

interface ArchiveExtractor {
public void extract(String archive, String destinationDirectory) throws ArchiveExtractionException;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.github.eirslett.maven.plugins.frontend.lib;

public final class DownloadException extends Exception {
public DownloadException(String message){
super(message);
}
DownloadException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@

import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig.Proxy;

final class DownloadException extends Exception {
public DownloadException(String message){
super(message);
}
DownloadException(String message, Throwable cause) {
super(message, cause);
}
}

interface FileDownloader {
void download(String downloadUrl, String destination, String userName, String password) throws DownloadException;
}
Expand Down Expand Up @@ -69,7 +60,7 @@ public void download(String downloadUrl, String destination, String userName, St
if(statusCode != 200){
throw new DownloadException("Got error code "+ statusCode +" from the server.");
}

byte[] data = IOUtils.toByteArray(response.getEntity().getContent());
new File(FilenameUtils.getFullPathNoEndSeparator(destination)).mkdirs();
FileUtils.writeByteArrayToFile(new File(destination), data);
Expand Down
Loading

0 comments on commit 86b0dc9

Please sign in to comment.