Skip to content

Commit

Permalink
Merge pull request #3 from kiwigrid/maven-settings
Browse files Browse the repository at this point in the history
feat: Support maven settings.xml
  • Loading branch information
jekkel authored Dec 16, 2021
2 parents ff62ac8 + 80e7299 commit 6b289da
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ Then add the extension to the playbook:
antora:
extensions:
- require: "@kiwigrid/antora-maven-content"
mavenSettings: true # defaults to false, true resolves to '$HOME/.m2/settings.xml' a string is taken as is
repositories:
- baseUrl: maven-central # required
fetchOptions: # optional
- baseUrl: https://www.example.com # required
fetchOptions: # optional
headers:
"Authorization": "Basic <base64 encoded user:password>"
sources:
Expand Down Expand Up @@ -65,6 +66,12 @@ For each picked version a corresponding playbook content source entry is created
* points to a local transient cached on-demand git repository the artifact has been extracted to
* is configured with the same [start path(s)](https://docs.antora.org/antora/3.0/playbook/content-source-start-paths/)

### Maven `settings.xml`

If `mavenSettings` is given a maven settings.xml is parsed for repositories and authentication data.
The value of the option can be `true` to use `$HOME/.m2/settings.xml` or a string pointing to a settings file.
Only active profiles are extracted.

## Contributions

[Are welcome!](CONTRIBUTING.md)
9 changes: 7 additions & 2 deletions lib/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
const MavenClient = require('./maven-client')
const MavenContentSource = require('./maven-content-source')
const ContentSourceFactory = require('./content-source-factory')
const Process = require("process");

/**
* This antora extension allows to add content from maven coordinates.
Expand Down Expand Up @@ -44,10 +45,14 @@ class MavenContentSourceExtension {
this.contentSourceFactory = new ContentSourceFactory(this.mavenClient, this.git, this.logger);
}

async onPlaybookBuilt({ playbook }) {
async onPlaybookBuilt({playbook}) {
this.logger.info("Add Maven Content Sources to playbook...");
const repositories = this.config.repositories?.map(entry => new MavenRepository(entry));
const repositories = this.config.repositories?.map(entry => new MavenRepository(entry)) || [];
const coordinates = this.config.sources?.map(entry => new MavenContentCoordinate(entry)) || [];
if (this.config.mavenSettings) {
const settingsFile = this.config.mavenSettings === true ? Process.env.HOME + '/.m2/settings.xml' : this.config.mavenSettings;
repositories.push(...(await this.mavenClient.extractRepositoriesFromSettingsFile(settingsFile)));
}
// copy playbook as it is frozen deeply...
const mutablePlaybook = MavenContentSourceExtension.#unfreezePlaybookSources(playbook);
await this.contentSourceFactory.produceContentSourcesIntoPlaybook(repositories, coordinates, mutablePlaybook);
Expand Down
44 changes: 41 additions & 3 deletions lib/maven-client.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const fetch = require("node-fetch");
const fs = require("fs")
const libxml = require("libxmljs2");
const unzip = require("unzip-stream");
const tar = require("tar");
Expand All @@ -12,6 +13,8 @@ const semver = require('semver')

const META_DATA_FILE_NAME = 'maven-metadata.xml';

const SETTINGS_XML_NS = 'http://maven.apache.org/SETTINGS/1.0.0'

class MavenClient {

logger;
Expand Down Expand Up @@ -140,11 +143,11 @@ class MavenClient {
.join('/');
const snapshotMetaData = await MavenClient.#downloadXml(snaphotMetadataUrl, repository.fetchOptions);
const latestVersion = snapshotMetaData.get(
'//snapshotVersion[extension='
'//snapshotVersion[extension="'
+ mavenArtifact.extension
+ '][classifier='
+ '"][classifier="'
+ mavenArtifact.classifier
+ ']/value/text()')?.text()
+ '"]/value/text()')?.text()
if (!latestVersion) {
throw new MavenClientError('Cannot find latest snapshot version info for ' + mavenArtifact.extension + ' in maven metadata: ' + snapshotMetaData)
}
Expand Down Expand Up @@ -213,6 +216,41 @@ class MavenClient {
return groupId.split('\.')
}

async extractRepositoriesFromSettingsFile(settingsFilePath) {
this.logger.debug('Loading repositories from ' + settingsFilePath + '...');
if (!fs.existsSync(settingsFilePath)) {
this.logger.warn('Skip loading repos from settings, ' + settingsFilePath + ' does not exist.');
return [];
}
const mavenSettingsXml = await fs.promises.readFile(settingsFilePath, "utf-8")
const mavenSettingsDocument = libxml.parseXml(mavenSettingsXml);
this.logger.debug('Settings file parsed ...');
const activeProfileNamePredicate = mavenSettingsDocument
.find('/xmlns:settings/xmlns:activeProfiles/xmlns:activeProfile/text()', SETTINGS_XML_NS)
.map(node => 'xmlns:id="' + node.text() + '"')
.join(",");
this.logger.debug('Found active profiles: ' + activeProfileNamePredicate);
const activeProfileRepoNodes = mavenSettingsDocument.find('/xmlns:settings/xmlns:profiles/xmlns:profile[' + activeProfileNamePredicate + ']/xmlns:repositories/xmlns:repository', SETTINGS_XML_NS)
return activeProfileRepoNodes.map(node => {
this.logger.debug('Found active profile repo: ' + node);
const repoId = node.get('xmlns:id/text()', SETTINGS_XML_NS)?.text()
const baseUrl = node.get('xmlns:url/text()', SETTINGS_XML_NS)?.text()
const serverNode = mavenSettingsDocument.get('/xmlns:settings/xmlns:servers/xmlns:server[xmlns:id="'+ repoId +'"]', SETTINGS_XML_NS);
const fetchOptions = {};
if (serverNode) {
this.logger.debug('Found active profile repo server: ' + serverNode);
const userName = serverNode.get('xmlns:username/text()', SETTINGS_XML_NS)?.text()
const password = serverNode.get('xmlns:password/text()', SETTINGS_XML_NS)?.text()
const buff = Buffer.from(userName + ':' + password, 'utf-8');
fetchOptions.headers = {
'Authorization': 'Basic ' + buff.toString('base64')
}
}
const mavenRepository = new MavenRepository({baseUrl, fetchOptions});
this.logger.info('Found repo in maven settings: ' + mavenRepository);
return mavenRepository;
})
}
}

class MavenClientError extends Error {
Expand Down

0 comments on commit 6b289da

Please sign in to comment.