ext (un)link

This commit is contained in:
João Moreno 2021-01-19 16:17:18 +01:00
parent 4ff784e1fb
commit c6145fc306
No known key found for this signature in database
GPG key ID: 896B853774D1A575
3 changed files with 97 additions and 14 deletions

View file

@ -6,10 +6,27 @@
const fs = require('fs').promises;
const path = require('path');
const cp = require('child_process');
const os = require('os');
const mkdirp = require('mkdirp');
const product = require('../product.json');
const root = path.resolve(path.join(__dirname, '..', '..'));
const exists = (path) => fs.stat(path).then(() => true, () => false);
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
async function readControlFile() {
try {
return JSON.parse(await fs.readFile(controlFilePath, 'utf8'));
} catch (err) {
return {};
}
}
async function writeControlFile(control) {
await mkdirp(path.dirname(controlFilePath));
await fs.writeFile(controlFilePath, JSON.stringify(control, null, ' '));
}
async function exec(cmd, args, opts = {}) {
return new Promise((c, e) => {
const child = cp.spawn(cmd, args, { stdio: 'inherit', env: process.env, ...opts });
@ -43,14 +60,18 @@ async function initExtension(extDesc) {
}
const type = await getExtensionType(folderPath);
return { path: folderPath, type };
return { path: folderPath, type, ...extDesc };
}
async function createWorkspace(type, extensions) {
const workspaceName = `vscode-${type}-extensions.code-workspace`;
const workspacePath = path.join(root, workspaceName);
const workspace = { folders: extensions.map(ext => ({ path: path.basename(ext.path) })) };
console.log(`✅ create workspace: ${workspaceName}`);
if (!await exists(workspacePath)) {
console.log(`✅ create workspace: ${workspaceName}`);
}
await fs.writeFile(workspacePath, JSON.stringify(workspace, undefined, ' '));
}
@ -69,25 +90,29 @@ async function init() {
for (const [type, extensions] of byType) {
await createWorkspace(type, extensions);
}
return byType;
}
async function ls() {
const types = new Map();
async function status() {
const byType = await init();
const control = await readControlFile();
for (const extDesc of product.builtInExtensions) {
const folderPath = getFolderPath(extDesc);
const type = await getExtensionType(folderPath);
types.set(type, 1 + (types.get(type) || 0));
}
for (const [type, extensions] of byType) {
console.log(`${type} (${extensions.length} extensions):`);
for (const [type, count] of types) {
console.log(`${type}: ${count} extensions`);
const maxWidth = Math.max(...extensions.map(e => e.name.length));
for (const ext of extensions) {
console.log(` ${ext.name.padEnd(maxWidth, ' ')}${control[ext.name]}`);
}
}
console.log(`total: ${product.builtInExtensions.length} extensions`);
}
async function each([cmd, ...args], opts) {
await init();
for (const extDesc of product.builtInExtensions) {
const folderPath = getFolderPath(extDesc);
@ -104,6 +129,46 @@ async function each([cmd, ...args], opts) {
}
}
async function _link(extensions, opts, fn) {
await init();
const control = await readControlFile();
for (const extDesc of product.builtInExtensions) {
if (extensions.length > 0 && extensions.indexOf(extDesc.name) === -1) {
continue;
}
if (opts.type) {
const folderPath = getFolderPath(extDesc);
const type = await getExtensionType(folderPath);
if (type !== opts.type) {
continue;
}
}
await fn(control, extDesc);
}
await writeControlFile(control);
}
async function link(extensions, opts) {
await _link(extensions, opts, async (control, extDesc) => {
const ext = await initExtension(extDesc);
control[extDesc.name] = ext.path;
console.log(`👉 link: ${extDesc.name}${ext.path}`);
});
}
async function unlink(extensions, opts) {
await _link(extensions, opts, async (control, extDesc) => {
control[extDesc.name] = 'marketplace';
console.log(`👉 unlink: ${extDesc.name}`);
});
}
if (require.main === module) {
const { program } = require('commander');
@ -115,9 +180,9 @@ if (require.main === module) {
.action(init);
program
.command('ls')
.description('List extension types')
.action(ls);
.command('status')
.description('Print extension status')
.action(status);
program
.command('each <command...>')
@ -126,5 +191,17 @@ if (require.main === module) {
.allowUnknownOption()
.action(each);
program
.command('link [extensions...]')
.option('-t, --type <type>', 'Specific type only')
.description('Link with code-oss')
.action(link);
program
.command('unlink [extensions...]')
.option('-t, --type <type>', 'Specific type only')
.description('Unlink from code-oss')
.action(unlink);
program.parseAsync(process.argv);
}

View file

@ -39,6 +39,7 @@
"iconv-lite-umd": "0.6.8",
"jsonc-parser": "^2.3.0",
"mime": "^1.4.1",
"mkdirp": "^1.0.4",
"source-map": "0.6.1",
"typescript": "4.2.0-dev.20201207",
"vsce": "1.48.0"

View file

@ -1061,6 +1061,11 @@ minimist@^1.2.0:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.3.tgz#3db5c0765545ab8637be71f333a104a965a9ca3f"
integrity sha512-+bMdgqjMN/Z77a6NlY/I3U5LlRDbnmaAk6lDveAPKwSpcPM4tKAuYsvYF8xjhOPXhOYGe/73vVLVez5PW+jqhw==
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"