2019-08-15 04:30:16 +00:00
|
|
|
import { logger } from '../../logger';
|
2021-01-21 12:11:35 +00:00
|
|
|
import * as ivyVersioning from '../../versioning/ivy';
|
2020-05-01 16:03:48 +00:00
|
|
|
import { compare } from '../../versioning/maven/compare';
|
|
|
|
import { downloadHttpProtocol } from '../maven/util';
|
2020-07-17 08:14:50 +00:00
|
|
|
import {
|
|
|
|
getArtifactSubdirs,
|
|
|
|
getLatestVersion,
|
|
|
|
getPackageReleases,
|
|
|
|
getUrls,
|
|
|
|
} from '../sbt-package';
|
2021-03-02 20:44:55 +00:00
|
|
|
import type { GetReleasesConfig, ReleaseResult } from '../types';
|
2020-05-01 16:03:48 +00:00
|
|
|
import { SBT_PLUGINS_REPO, parseIndexDir } from './util';
|
2019-05-30 23:39:07 +00:00
|
|
|
|
2020-03-01 07:01:12 +00:00
|
|
|
export const id = 'sbt-plugin';
|
2020-04-07 13:41:39 +00:00
|
|
|
export const defaultRegistryUrls = [SBT_PLUGINS_REPO];
|
2021-01-21 12:11:35 +00:00
|
|
|
export const defaultVersioning = ivyVersioning.id;
|
2020-06-19 19:29:34 +00:00
|
|
|
export const registryStrategy = 'hunt';
|
2020-04-07 13:41:39 +00:00
|
|
|
|
2020-01-14 11:22:42 +00:00
|
|
|
const ensureTrailingSlash = (str: string): string => str.replace(/\/?$/, '/');
|
|
|
|
|
2019-11-24 04:09:13 +00:00
|
|
|
async function resolvePluginReleases(
|
|
|
|
rootUrl: string,
|
|
|
|
artifact: string,
|
|
|
|
scalaVersion: string
|
2019-11-26 15:13:07 +00:00
|
|
|
): Promise<string[]> {
|
2019-11-24 04:09:13 +00:00
|
|
|
const searchRoot = `${rootUrl}/${artifact}`;
|
2019-11-26 15:13:07 +00:00
|
|
|
const parse = (content: string): string[] =>
|
2020-04-12 16:09:36 +00:00
|
|
|
parseIndexDir(content, (x) => !/^\.+$/.test(x));
|
2020-01-14 11:22:42 +00:00
|
|
|
const indexContent = await downloadHttpProtocol(
|
|
|
|
ensureTrailingSlash(searchRoot),
|
|
|
|
'sbt'
|
|
|
|
);
|
2019-11-24 04:09:13 +00:00
|
|
|
if (indexContent) {
|
|
|
|
const releases: string[] = [];
|
|
|
|
const scalaVersionItems = parse(indexContent);
|
2020-04-12 16:09:36 +00:00
|
|
|
const scalaVersions = scalaVersionItems.map((x) =>
|
|
|
|
x.replace(/^scala_/, '')
|
|
|
|
);
|
2021-03-04 05:21:55 +00:00
|
|
|
const searchVersions = scalaVersions.includes(scalaVersion)
|
|
|
|
? [scalaVersion]
|
|
|
|
: scalaVersions;
|
2019-11-24 04:09:13 +00:00
|
|
|
for (const searchVersion of searchVersions) {
|
|
|
|
const searchSubRoot = `${searchRoot}/scala_${searchVersion}`;
|
2020-01-14 11:22:42 +00:00
|
|
|
const subRootContent = await downloadHttpProtocol(
|
|
|
|
ensureTrailingSlash(searchSubRoot),
|
|
|
|
'sbt'
|
|
|
|
);
|
2019-11-24 04:09:13 +00:00
|
|
|
if (subRootContent) {
|
|
|
|
const sbtVersionItems = parse(subRootContent);
|
|
|
|
for (const sbtItem of sbtVersionItems) {
|
|
|
|
const releasesRoot = `${searchSubRoot}/${sbtItem}`;
|
|
|
|
const releasesIndexContent = await downloadHttpProtocol(
|
2020-01-14 11:22:42 +00:00
|
|
|
ensureTrailingSlash(releasesRoot),
|
2019-11-24 04:09:13 +00:00
|
|
|
'sbt'
|
|
|
|
);
|
|
|
|
if (releasesIndexContent) {
|
|
|
|
const releasesParsed = parse(releasesIndexContent);
|
2020-04-12 16:09:36 +00:00
|
|
|
releasesParsed.forEach((x) => releases.push(x));
|
2019-11-24 04:09:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-17 11:15:22 +00:00
|
|
|
if (releases.length) {
|
|
|
|
return [...new Set(releases)].sort(compare);
|
|
|
|
}
|
2019-11-24 04:09:13 +00:00
|
|
|
}
|
2020-07-17 08:14:50 +00:00
|
|
|
return null;
|
2019-11-24 04:09:13 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 06:53:52 +00:00
|
|
|
export async function getReleases({
|
2020-02-28 07:49:51 +00:00
|
|
|
lookupName,
|
2020-06-19 19:29:34 +00:00
|
|
|
registryUrl,
|
2020-02-28 07:49:51 +00:00
|
|
|
}: GetReleasesConfig): Promise<ReleaseResult | null> {
|
2019-05-30 23:39:07 +00:00
|
|
|
const [groupId, artifactId] = lookupName.split(':');
|
|
|
|
const groupIdSplit = groupId.split('.');
|
|
|
|
const artifactIdSplit = artifactId.split('_');
|
|
|
|
const [artifact, scalaVersion] = artifactIdSplit;
|
|
|
|
|
2020-06-19 19:29:34 +00:00
|
|
|
const repoRoot = ensureTrailingSlash(registryUrl);
|
2019-08-15 04:30:16 +00:00
|
|
|
const searchRoots: string[] = [];
|
2020-06-19 19:29:34 +00:00
|
|
|
// Optimize lookup order
|
|
|
|
searchRoots.push(`${repoRoot}${groupIdSplit.join('.')}`);
|
|
|
|
searchRoots.push(`${repoRoot}${groupIdSplit.join('/')}`);
|
2019-05-30 23:39:07 +00:00
|
|
|
|
|
|
|
for (let idx = 0; idx < searchRoots.length; idx += 1) {
|
|
|
|
const searchRoot = searchRoots[idx];
|
2020-07-17 08:14:50 +00:00
|
|
|
let versions = await resolvePluginReleases(
|
2020-02-28 07:49:51 +00:00
|
|
|
searchRoot,
|
|
|
|
artifact,
|
|
|
|
scalaVersion
|
|
|
|
);
|
2020-07-17 08:14:50 +00:00
|
|
|
let urls = {};
|
|
|
|
|
|
|
|
if (!versions?.length) {
|
|
|
|
const artifactSubdirs = await getArtifactSubdirs(
|
|
|
|
searchRoot,
|
|
|
|
artifact,
|
|
|
|
scalaVersion
|
|
|
|
);
|
|
|
|
versions = await getPackageReleases(searchRoot, artifactSubdirs);
|
|
|
|
const latestVersion = getLatestVersion(versions);
|
|
|
|
urls = await getUrls(searchRoot, artifactSubdirs, latestVersion);
|
|
|
|
}
|
2019-05-30 23:39:07 +00:00
|
|
|
|
2020-02-28 07:49:51 +00:00
|
|
|
const dependencyUrl = `${searchRoot}/${artifact}`;
|
2019-06-10 15:48:26 +00:00
|
|
|
|
2019-05-30 23:39:07 +00:00
|
|
|
if (versions) {
|
|
|
|
return {
|
2020-07-17 08:14:50 +00:00
|
|
|
...urls,
|
2019-06-10 15:48:26 +00:00
|
|
|
dependencyUrl,
|
2020-04-12 16:09:36 +00:00
|
|
|
releases: versions.map((v) => ({ version: v })),
|
2019-05-30 23:39:07 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 07:43:01 +00:00
|
|
|
logger.debug(
|
2019-05-30 23:39:07 +00:00
|
|
|
`No versions found for ${lookupName} in ${searchRoots.length} repositories`
|
|
|
|
);
|
|
|
|
return null;
|
|
|
|
}
|