in packages/apps/autorest/src/autorest-as-a-service.ts [221:345]
export async function selectVersion(
logger: IAutorestLogger,
requestedVersion: string,
force: boolean,
minimumVersion?: string,
): Promise<Extension> {
const installedVersions = await installedCores();
let currentVersion: Extension | null = installedVersions[0] || null;
// the consumer can say I want the latest-installed, but at least XXX.XXX
if (minimumVersion && currentVersion && !semver.satisfies(currentVersion.version, minimumVersion)) {
currentVersion = null;
}
if (currentVersion) {
logger.debug(`The most recent installed version is ${currentVersion.version}`);
if (requestedVersion === "latest-installed" || (requestedVersion === "latest" && false == (await networkEnabled))) {
logger.debug(`requesting current version '${currentVersion.version}'`);
requestedVersion = currentVersion.version;
}
} else {
logger.debug(`No ${newCorePackage} (or ${oldCorePackage}) is installed.`);
}
let selectedVersion: Extension | null = null;
// take the highest version that satisfies the version range.
for (const each of installedVersions.sort((a, b) => semver.compare(a?.version, b?.version))) {
if (semver.satisfies(each.version, requestedVersion)) {
selectedVersion = each;
}
}
// is the requested version installed?
if (!selectedVersion || force) {
if (!force) {
logger.debug(`${requestedVersion} was not satisfied directly by a previous installation.`);
}
// if it's not a file, and the network isn't available, we can't continue.
if (!(await isFile(requestedVersion)) && !(await networkEnabled)) {
// no network enabled.
throw new Exception(
`Network access is not available, requested version '${requestedVersion}' is not installed. `,
);
}
// after this point, latest-installed must mean latest.
if (requestedVersion === "latest-installed") {
requestedVersion = "latest";
}
// if they have requested 'latest' -- they really mean latest with same major version number
if (requestedVersion === "latest") {
requestedVersion = versionRange;
}
let corePackageName = newCorePackage;
let pkg: Package | undefined = undefined;
try {
// try the package
pkg = await (await extensionManager).findPackage(newCorePackage, requestedVersion);
} catch (error) {
// try a prerelease version from github.
try {
const rv = requestedVersion.replace(/^[~|^]/g, "");
pkg = await (
await extensionManager
).findPackage(
"core",
`https://github.com/Azure/autorest/releases/download/autorest-core-${rv}/autorest-core-${rv}.tgz`,
);
} catch {
// fallback to old package name
try {
pkg = await (await extensionManager).findPackage(oldCorePackage, requestedVersion);
} catch {
// no package found!
}
}
if (!pkg) {
logger.debug(`Error trying to resolve @autorest/core version ${requestedVersion}: ${error}`);
throw new Exception(
`Unable to find a valid AutoRest core package '${newCorePackage}' @ '${requestedVersion}'.`,
);
}
corePackageName = oldCorePackage;
}
if (pkg) {
if (args.debug) {
console.log(`Selected package: ${pkg.resolvedInfo.rawSpec} => ${pkg.name}@${pkg.version}`);
}
}
// pkg.version == the actual version
// check if it's installed already.
selectedVersion = await (await extensionManager).getInstalledExtension(corePackageName, pkg.version);
if (!selectedVersion || force) {
// this will throw if there is an issue with installing the extension.
if (args.debug) {
console.log(`**Installing package** ${corePackageName}@${pkg.version}\n[This will take a few moments...]`);
}
// @autorest/core install too fast and this doesn't look good right now as Yarn doesn't give info fast enough.
// If we migrate to yarn v2 with the api we might be able to get more info and reenable that
const progress = logger.startProgress("installing core...");
selectedVersion = await (
await extensionManager
).installPackage(pkg, force, 5 * 60 * 1000, (status) => {
progress.update({ ...status });
});
progress.stop();
if (args.debug) {
console.log(`Extension location: ${selectedVersion.packageJsonPath}`);
}
} else {
if (args.debug) {
console.log(`AutoRest Core ${pkg.version} is available at ${selectedVersion.modulePath}`);
}
}
}
return selectedVersion;
}