Skip to content

Commit

Permalink
feat: add 'shim' via aloneguid/win-shim
Browse files Browse the repository at this point in the history
  • Loading branch information
CKylinMC committed Dec 1, 2023
1 parent 1d45b35 commit 85de9ba
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cmand",
"version": "0.7.9-beta",
"version": "0.8.0-beta",
"author": "CKylinMC",
"description": "A simple command-line tool for Windows managing your small scripts.",
"main": "build/main/index.js",
Expand Down
98 changes: 94 additions & 4 deletions src/actions/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import path from 'path';
import chalk from 'chalk';
import inquirer from 'inquirer';
import yaml from 'yaml';
import { scripthome } from '../info';
import Db from '../lib/Db';
import { includeshome, scripthome } from '../info';
import Db, { Settings } from '../lib/Db';
import got from 'got';
import { Spinner } from '../lib/Spinner';
import { ProgressBar } from '../lib/ProgressBar';
import AdmZip from 'adm-zip';
import { exec } from 'child_process';

export async function create(name = null) {
const questions = [
Expand Down Expand Up @@ -100,9 +105,94 @@ export async function createTask(taskname, contents) {
console.log(chalk.green('Task added into cmand.yml, run "cmand task ' + taskname + '" to run it.'));
}

export async function makeShim(executable: string, alias = null) {
if(!await Settings.get('supress-shim-notice', false)) console.log(chalk.blue('[NOTICE] You are making shim for an executable via "aloneguid/win-shim". CMAND will not manage shims, only provide creation feature via subcommand. (Supress this notice by "cmand cfg set supress-shim-notice true")'));
const utilshome = path.join(includeshome(), "cmand-utils");
const shim = path.join(utilshome, "shmake.exe");
if (!fs.existsSync(shim)) {
if (!fs.existsSync(utilshome)) {
fs.mkdirSync(utilshome);
}
const shimpack = path.join(utilshome, "shmake.zip");
console.log(chalk.yellow('It seems this is the first time you run this command. CMAND will download the necessary files automatically. Please wait.'));
let spinner = new Spinner("Checking latest version of win-shim...").start();
let result;
try {
result = await got("https://api.github.com/repos/aloneguid/win-shim/releases/latest").json();
} catch (err) {
spinner.fail(chalk.red("Failed to fetch the latest version of win-shim: ", err.message));
return;
}
let versionTag = result.tag_name;
let downloadUrl = `https://github.com/aloneguid/win-shim/releases/download/${versionTag}/shmake.zip`;
let dlok = true;
await new Promise((resolve, reject) => {
const stream = got.stream(downloadUrl, { https: { rejectUnauthorized: false } });
stream.on('downloadProgress', ({ transferred, total, percent }) => {
spinner.text(`Downloading shmake.zip... ${ProgressBar.render({ max: total, value: transferred })} (${percent}%)`);
})
stream.on('error', reject);
const writer = fs.createWriteStream(shimpack);
writer.on('error', reject);
writer.on('finish', resolve);
stream.pipe(writer);
}).catch(() => {
dlok = false;
});
if (!dlok) {
spinner.fail(chalk.red("Failed to download shmake.zip."));
return;
}
spinner.text("Extracting shmake...");
const zip = new AdmZip(shimpack);
const zipEntries = zip.getEntries();
const fileList = {};
for (const entry of zipEntries) {
fileList[entry.entryName] = entry;
}
if (!fileList['shmake.exe']) {
spinner.fail(chalk.red("Failed to extract shmake"));
return;
}
try {
zip.extractEntryTo(fileList['shmake.exe'], utilshome);
} catch (err) {
spinner.fail(chalk.red("Failed to extract shmake: ") + err.message);
return;
}
try {
fs.unlinkSync(shimpack);
} catch (err) {
spinner.fail(chalk.red("Failed to remove shmake archive which is useless now: ") + err.message);
return;
}
spinner.success(chalk.green("shmake.exe has been downloaded successfully."));
}
let spinner = new Spinner("Creating shim...").start();
let execname = path.basename(executable, path.extname(executable));
let targetname = `${alias ?? execname}.exe`;
let output = path.join(scripthome(), targetname);
try {
if (fs.existsSync(output)) {
spinner.fail(chalk.red(`Failed to create ${targetname}: file already exists.`));
return;
}
let command = [`"${shim}"`, "-a", "%s", "-i", `"${executable}"`, "-o", `"${output}"`];
await new Promise((r, j) => {
exec(command.join(" "), (error) => {
if (error) j(error);
else r(0);
})
})
spinner.success(chalk.green(`Shim created successfully: ${targetname}`));
} catch (err) {
spinner.fail(chalk.red(`Failed to create ${targetname}: `,err));
}
}

export async function makeProxyScript(filename, alias=null, runner=null) {
const sourcepath = path.resolve(process.cwd(), filename);

if (!fs.existsSync(sourcepath)) {
console.log(chalk.red(`Path ${sourcepath} not found.`));
return;
Expand Down Expand Up @@ -151,4 +241,4 @@ export async function makeProxyScript(filename, alias=null, runner=null) {
enabled: true,
});
console.log(chalk.green(`Proxy script ${info.name}.cmd created.`));
}
}
12 changes: 10 additions & 2 deletions src/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
removeConfig,
setConfig,
} from './actions/config';
import { create, createTask, makeProxyScript } from './actions/create';
import { create, createTask, makeProxyScript, makeShim } from './actions/create';
import { edit } from './actions/edit';
import { exportPackage } from './actions/export';
import { info } from './actions/info';
Expand Down Expand Up @@ -94,7 +94,15 @@ export default async function App() {
options.name?.trim?.() || null,
options.runner?.trim?.() || null
)
);
);

p.command('shim')
.argument(
'<executable>', 'path to the executable you want to make shim'
)
.option('-n, --name <name>', 'Specify an alias for the new shim file without extension', null)
.description('Create a shim for the specified executable via aloneguid/win-shim. Need download win-shim on first run.')
.action((path, { name }) => makeShim(path, name?.trim() || null));

p.command('alias')
.argument(
Expand Down
2 changes: 1 addition & 1 deletion src/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import homedir from 'homedir';

export const Info = {
name: 'cmand',
version: '0.7.9-beta',
version: '0.8.0-beta',
description: 'A command line tool for managing your script snippets on Windows.',
author: 'CKylinMC',
}
Expand Down

0 comments on commit 85de9ba

Please sign in to comment.