Skip to content

Commit

Permalink
Implement target platform
Browse files Browse the repository at this point in the history
# Conflicts:
#	server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java
#	server/src/main/java/org/eclipse/openvsx/RegistryAPI.java
#	server/src/main/java/org/eclipse/openvsx/adapter/VSCodeAdapter.java
#	server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java
#	server/src/main/java/org/eclipse/openvsx/storage/GoogleCloudStorageService.java
#	server/src/main/java/org/eclipse/openvsx/storage/StorageUtilService.java
  • Loading branch information
amvanbaren committed Mar 22, 2022
1 parent a77dc99 commit 2bc6807
Show file tree
Hide file tree
Showing 78 changed files with 3,193 additions and 1,339 deletions.
6 changes: 6 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This change log covers only the command line interface (CLI) of Open VSX.

### v0.5.0 (Mar. 2022)

#### New Features

- Added CLI parameter `--target` to support target platforms ([#406](https://github.com/eclipse/openvsx/pull/406))

### v0.4.0 (Feb. 2022)

#### New Features
Expand Down
2 changes: 1 addition & 1 deletion cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ You can use `ovsx` for downloading extensions from an Open VSX instance. Extensi

Variants:
* `ovsx get <extension>`
downloads an extension and saves it in a file as specified in its download URL (usually in the format `namespace.extension-version.vsix`) in the current working directory.
downloads an extension and saves it in a file as specified in its download URL (usually in the format `namespace.extension-version@target.vsix`) in the current working directory.
* `ovsx get <extension> -o <path>`
downloads an extension and saves it in the specified file or directory.
* `ovsx get <extension> --metadata`
Expand Down
14 changes: 7 additions & 7 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@
},
"dependencies": {
"commander": "^6.1.0",
"follow-redirects": "^1.13.2",
"follow-redirects": "^1.14.6",
"is-ci": "^2.0.0",
"leven": "^3.1.0",
"tmp": "^0.2.1",
"vsce": "^2.6.3"
},
"devDependencies": {
"@types/follow-redirects": "^1.13.0",
"@types/follow-redirects": "^1.13.1",
"@types/is-ci": "^2.0.0",
"@types/node": "^10.14.18",
"@types/semver": "^7.1.0",
"@types/node": "^10.17.60",
"@types/semver": "^7.3.9",
"@types/tmp": "^0.1.0",
"@typescript-eslint/eslint-plugin": "^3.6.1",
"@typescript-eslint/parser": "^3.6.1",
"eslint": "^7.4.0",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",
"eslint": "^7.32.0",
"rimraf": "^3.0.2",
"typescript": "3.8.3"
},
Expand Down
22 changes: 17 additions & 5 deletions cli/src/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ import { promisify, matchExtensionId, optionalStat, makeDirs, addEnvOptions } fr
*/
export async function getExtension(options: GetOptions): Promise<void> {
addEnvOptions(options);
const registry = new Registry(options);
if (!options.target) {
options.target = 'universal';
}

const registry = new Registry(options);
const match = matchExtensionId(options.extensionId);
if (!match) {
throw new Error('The extension identifier must have the form `namespace.extension`.');
}

const extension = await registry.getMetadata(match[1], match[2]);
const extension = await registry.getMetadata(match[1], match[2], options.target);
if (extension.error) {
throw new Error(extension.error);
}
Expand All @@ -48,7 +51,7 @@ function findMatchingVersion(registry: Registry, extension: Extension, constrain
return Promise.resolve(extension);
}
for (const version of Object.keys(extension.allVersions)) {
if (semver.satisfies(version, constraint)) {
if (!isAlias(extension, version) && semver.satisfies(version, constraint)) {
try {
return registry.getJson(new URL(extension.allVersions[version]));
} catch (err) {
Expand All @@ -59,6 +62,10 @@ function findMatchingVersion(registry: Registry, extension: Extension, constrain
return Promise.reject(`Extension ${extension.namespace}.${extension.name} has no published version matching '${constraint}'`);
}

function isAlias(extension: Extension, version: string): boolean {
return extension.versionAlias.includes(version);
}

async function printMetadata(registry: Registry, extension: Extension, output?: string): Promise<void> {
const metadata = JSON.stringify(extension, null, 4);
if (!output) {
Expand All @@ -83,7 +90,7 @@ async function download(registry: Registry, extension: Extension, output?: strin
throw new Error(`Extension ${extension.namespace}.${extension.name} does not provide a download URL.`);
}
const fileNameIndex = downloadUrl.lastIndexOf('/');
const fileName = downloadUrl.substring(fileNameIndex + 1);
const fileName = decodeURIComponent(downloadUrl.substring(fileNameIndex + 1));
let filePath: string | undefined;
if (output) {
const stats = await optionalStat(output);
Expand All @@ -96,7 +103,8 @@ async function download(registry: Registry, extension: Extension, output?: strin
filePath = path.resolve(process.cwd(), fileName);
}
await makeDirs(path.dirname(filePath));
console.log(`Downloading ${extension.namespace}.${extension.name} v${extension.version} to ${filePath}`);
const target = extension.targetPlatform !== 'universal' ? '@' + extension.targetPlatform : '';
console.log(`Downloading ${extension.namespace}.${extension.name}-${extension.version}${target} to ${filePath}`);
await registry.download(filePath, new URL(downloadUrl));
}

Expand All @@ -105,6 +113,10 @@ export interface GetOptions extends RegistryOptions {
* Identifier in the form `namespace.extension` or `namespace/extension`.
*/
extensionId: string;
/**
* Target platform.
*/
target?: string;
/**
* An exact version or version range.
*/
Expand Down
14 changes: 10 additions & 4 deletions cli/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,29 @@ module.exports = function (argv: string[]): void {

const publishCmd = program.command('publish [extension.vsix]');
publishCmd.description('Publish an extension, packaging it first if necessary.')
.option('-t, --target <targets...>', 'Target architectures')
.option('-i, --packagePath <paths...>', 'Publish the provided VSIX packages.')
.option('--baseContentUrl <url>', 'Prepend all relative links in README.md with this URL.')
.option('--baseImagesUrl <url>', 'Prepend all relative image links in README.md with this URL.')
.option('--yarn', 'Use yarn instead of npm while packing extension files.')
.option('--pre-release', 'Mark this package as a pre-release')
.action((extensionFile: string, { packagePath, baseContentUrl, baseImagesUrl, yarn, preRelease }) => {
.action((extensionFile: string, { target, packagePath, baseContentUrl, baseImagesUrl, yarn, preRelease }) => {
if (extensionFile !== undefined && packagePath !== undefined) {
console.error('\u274c Please specify either a package file or a package path, but not both.\n');
publishCmd.help();
}
if (extensionFile !== undefined && target !== undefined) {
console.warn("Ignoring option '--target' for prepackaged extension.");
target = undefined;
}
if (extensionFile !== undefined && baseContentUrl !== undefined)
console.warn("Ignoring option '--baseContentUrl' for prepackaged extension.");
if (extensionFile !== undefined && baseImagesUrl !== undefined)
console.warn("Ignoring option '--baseImagesUrl' for prepackaged extension.");
if (extensionFile !== undefined && yarn !== undefined)
console.warn("Ignoring option '--yarn' for prepackaged extension.");
const { registryUrl, pat } = program.opts();
publish({ extensionFile, registryUrl, pat, packagePath: typeof packagePath === 'string' ? [packagePath] : packagePath, baseContentUrl, baseImagesUrl, yarn, preRelease })
publish({ extensionFile, registryUrl, pat, targets: typeof target === 'string' ? [target] : target, packagePath: typeof packagePath === 'string' ? [packagePath] : packagePath, baseContentUrl, baseImagesUrl, yarn, preRelease })
.catch(handleError(program.debug,
'See the documentation for more information:\n'
+ 'https://github.com/eclipse/openvsx/wiki/Publishing-Extensions'
Expand All @@ -61,12 +66,13 @@ module.exports = function (argv: string[]): void {

const getCmd = program.command('get <namespace.extension>');
getCmd.description('Download an extension or its metadata.')
.option('-t, --target <target>', 'Target architecture')
.option('-v, --versionRange <version>', 'Specify an exact version or a version range.')
.option('-o, --output <path>', 'Save the output in the specified file or directory.')
.option('--metadata', 'Print the extension\'s metadata instead of downloading it.')
.action((extensionId: string, { versionRange, output, metadata }) => {
.action((extensionId: string, { target, versionRange, output, metadata }) => {
const { registryUrl } = program.opts();
getExtension({ extensionId, version: versionRange, registryUrl, output, metadata })
getExtension({ extensionId, target: target, version: versionRange, registryUrl, output, metadata })
.catch(handleError(program.debug));
});

Expand Down
35 changes: 29 additions & 6 deletions cli/src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ import { checkLicense } from './check-license';
*/
export async function publish(options: PublishOptions = {}): Promise<void> {
addEnvOptions(options);
if (options.packagePath) {
// call the publish command for every package path
await Promise.all(options.packagePath.map(path => doPublish({ ...options, packagePath: path })));
} else {
return doPublish({ ... options, packagePath: undefined });
const internalPublishOptions = [];
const packagePaths = options.packagePath || [undefined];
const targets = options.targets || [undefined];
for (const packagePath of packagePaths) {
for (const target of targets) {
internalPublishOptions.push({ ... options, packagePath: packagePath, target: target });
}
}
await Promise.all(internalPublishOptions.map(publishOptions => doPublish(publishOptions)));
}

async function doPublish(options: InternalPublishOptions = {}): Promise<void> {
Expand All @@ -34,6 +37,7 @@ async function doPublish(options: InternalPublishOptions = {}): Promise<void> {
if (options.packagePath && options.packagePath.endsWith('.vsix')) {
options.extensionFile = options.packagePath;
delete options.packagePath;
delete options.target;
}
const registry = new Registry(options);
if (!options.extensionFile) {
Expand All @@ -47,7 +51,14 @@ async function doPublish(options: InternalPublishOptions = {}): Promise<void> {
if (extension.error) {
throw new Error(extension.error);
}
console.log(`\ud83d\ude80 Published ${extension.namespace}.${extension.name} v${extension.version}`);

const name = `${extension.namespace}.${extension.name}`;
let description = `${name} v${extension.version}`;
if (options.target) {
description += `@${options.target}`;
}

console.log(`\ud83d\ude80 Published ${description}`);
}

interface PublishCommonOptions extends RegistryOptions {
Expand Down Expand Up @@ -77,6 +88,11 @@ interface PublishCommonOptions extends RegistryOptions {
// Interface used by top level CLI
export interface PublishOptions extends PublishCommonOptions {

/**
* Target architectures.
*/
targets?: string[];

/**
* Paths to the extension to be packaged and published. Cannot be used together
* with `extensionFile`.
Expand All @@ -87,6 +103,12 @@ export interface PublishOptions extends PublishCommonOptions {
// Interface used internally by the doPublish method
interface InternalPublishOptions extends PublishCommonOptions {

/**
* Only one target for our internal command.
* Target architecture.
*/
target?: string;

/**
* Only one path for our internal command.
* Path to the extension to be packaged and published. Cannot be used together
Expand All @@ -102,6 +124,7 @@ async function packageExtension(options: InternalPublishOptions, registry: Regis

options.extensionFile = await createTempFile({ postfix: '.vsix' });
const createVSIXOptions: ICreateVSIXOptions = {
target: options.target,
cwd: options.packagePath,
packagePath: options.extensionFile,
baseContentUrl: options.baseContentUrl,
Expand Down
8 changes: 6 additions & 2 deletions cli/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ export class Registry {
}
}

getMetadata(namespace: string, extension: string): Promise<Extension> {
getMetadata(namespace: string, extension: string, target?: string): Promise<Extension> {
try {
const path = `api/${encodeURIComponent(namespace)}/${encodeURIComponent(extension)}`;
let path = `api/${encodeURIComponent(namespace)}/${encodeURIComponent(extension)}`;
if (target) {
path += `/${encodeURIComponent(target)}`;
}
return this.getJson(this.getUrl(path));
} catch (err) {
return Promise.reject(err);
Expand Down Expand Up @@ -252,6 +255,7 @@ export interface Extension extends Response {
name: string;
namespace: string;
version: string;
targetPlatform: string;
publishedBy: UserData;
verified: boolean;
// key: version, value: url
Expand Down
Loading

0 comments on commit 2bc6807

Please sign in to comment.