diff --git a/.vscode/settings.json b/.vscode/settings.json index aeb028d..8413774 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "deno.enable": true -} \ No newline at end of file + "deno.enable": true, + "deno.unstable": true +} diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000..792e5c4 --- /dev/null +++ b/cli/README.md @@ -0,0 +1,20 @@ +A CLI for the denreg registry. + +## Installation + +Recommended way for installation is +`deno install -A --unstable https://deno.hibas123.de/raw/@denreg-cli/denreg.ts` +Since the cli requires access to: + +- reading and writing files +- access to environment variables +- network access + +The -A flag is the easiest way to install. You can however manually grant the required permissions. + +| permission | reason | +| ------------- | ------------------------------------------------------------------------------------------------- | +| --allow-read | Read configuration files (~/.denreg) as well the your project files on publish | +| --allow-write | Write configuration file while using setup and init as well as during publish for temporary files | +| --allow-net | Access to network for uploading to the registry (can be exclusive to the registry) | +| --allow-env | Required to get config file path relative to user home directory | diff --git a/cli/commands/init.ts b/cli/commands/init.ts index 33c2deb..6d5eb3d 100644 --- a/cli/commands/init.ts +++ b/cli/commands/init.ts @@ -1,4 +1,4 @@ -import { Cliffy, Path, FS, Compress, Base64 } from "../deps.ts"; +import { Cliffy, Path, FS } from "../deps.ts"; import { getMeta, setMeta, @@ -18,7 +18,7 @@ export default async function init() { description: "", author: getConfig("author"), contributors: [], - files: ["**/*.ts", "**/*.js"], + files: ["**/*.ts", "**/*.js", "README.md"], ...existing, }; @@ -35,6 +35,19 @@ export default async function init() { message: "Who's the author of your package?", default: meta.author, }); + + if (!(await FS.exists("README.md"))) { + const res = await Cliffy.Confirm.prompt({ + message: "Autogenerate README?", + default: true, + }); + if (res) { + await Deno.writeFile( + "README.md", + new TextEncoder().encode(meta.description || "") + ); + } + } } await setMeta(meta); diff --git a/cli/denreg.ts b/cli/denreg.ts index af83ec8..545c712 100644 --- a/cli/denreg.ts +++ b/cli/denreg.ts @@ -1,7 +1,4 @@ -import { Ini, Cliffy, Compress, Base64 } from "./deps.ts"; -import * as Colors from "https://deno.land/std@0.62.0/fmt/colors.ts"; -import * as Path from "https://deno.land/std@0.62.0/path/mod.ts"; -import * as FS from "https://deno.land/std@0.62.0/fs/mod.ts"; +import { Cliffy, Path } from "./deps.ts"; import { init } from "./global.ts"; import setupCMD from "./commands/setup.ts"; @@ -38,7 +35,7 @@ const flags = await new Cliffy.Command() default: Path.resolve(HOME_FOLDER, ".denreg"), global: true, }) - .option("-v, --verbose", "Verbose", { + .option("-v, --verbose [verbose:boolean]", "Verbose", { default: false, global: true, }) @@ -76,222 +73,3 @@ await init(flags.options); if (command) { await Promise.resolve((command as CommandHandler)(...opts)); } - -// function log(...args: any[]) { -// if (flags.options.verbose) console.log(...args); -// } - -// const CONFIG_LOCATION = flags.options.config; - -// function loadConfigSync() { -// try { -// const data = Deno.readFileSync(CONFIG_LOCATION); -// return Ini.decode(new TextDecoder().decode(data)); -// } catch (err) { -// return {}; -// } -// } - -// const config = loadConfigSync(); - -// const { username, password, registry } = config; - -// async function setConfig(name: string, value: string) { -// config[name] = value; - -// const data = Ini.encode(config); - -// await Deno.writeFile(CONFIG_LOCATION, new TextEncoder().encode(data), { -// create: true, -// }); -// } - -// async function setup() { -// const registry = await Cliffy.Input.prompt({ -// message: "What's your registry?", -// default: config.registry, -// }); -// const username = await Cliffy.Input.prompt({ -// message: "What's your username?", -// default: config.username, -// }); -// const password = await Cliffy.Secret.prompt({ -// message: "What's your password?", -// hidden: true, -// default: config.password, -// }); - -// const author = await Cliffy.Input.prompt({ -// message: "Who are you? (optional) Name ", -// default: config.author, -// }); - -// await setConfig("registry", registry); -// await setConfig("username", username); -// await setConfig("password", password); -// await setConfig("author", author); -// } - -// interface IMeta { -// name: string; -// version: string; -// description?: string; -// author?: string; -// contributors?: string[]; -// files: string[]; -// } - -// async function init() { -// let existing = {}; -// try { -// existing = await _getMeta(); -// } catch (err) {} -// let meta: IMeta = { -// name: Path.basename(Deno.cwd()).toLowerCase().replace(/\s+/g, "-"), -// version: "0.0.1", -// description: "", -// author: config.author, -// contributors: [], -// files: ["**/*.ts", "**/*.js", "importmap.json"], -// ...existing, -// }; - -// if (flags.options.interactive) { -// meta.name = await Cliffy.Input.prompt({ -// message: "What's the name of your package?", -// default: meta.name, -// }); -// meta.description = await Cliffy.Input.prompt({ -// message: "What's the description of your package?", -// default: meta.description, -// }); -// meta.author = await Cliffy.Input.prompt({ -// message: "Who's the author of your package?", -// default: meta.author, -// }); -// } - -// await _setMeta(meta); -// } - -// async function bump(options: any, type: "minor" | "major" | "patch") { -// const meta = await _getMeta(); - -// let [major = 0, minor = 0, patch = 0] = meta.version.split(".").map(Number); - -// switch (type) { -// case "major": -// major++; -// break; -// case "minor": -// minor++; -// break; -// case "patch": -// patch++; -// break; -// default: -// throw new Error("type must be either major, minor or patch"); -// } -// const newVersion = [major, minor, patch].join("."); -// console.log( -// "Bumping version from", -// Colors.blue(meta.version), -// "to", -// Colors.blue(newVersion) -// ); -// meta.version = newVersion; -// await _setMeta(meta); -// } - -// async function uploadPackage() { -// const meta: IMeta = await _getMeta(); - -// if (!meta.name) throw new Error("name is not set in meta.json"); -// if (!meta.version) throw new Error("version is not set in meta.json"); -// if (!meta.files || !Array.isArray(meta.files) || meta.files.length <= 0) -// throw new Error("files is not set or empty in meta.json"); - -// const tmpDir = await Deno.makeTempDir(); -// const packedFile = await Deno.makeTempFile(); - -// try { -// const walker = FS.walk(".", { -// includeDirs: false, -// includeFiles: true, -// match: meta.files.map((file) => Path.globToRegExp(file)), -// }); - -// log("Copying files to package to", tmpDir); - -// const copy = async (path: string) => { -// const dest = Path.join(tmpDir, path); -// await FS.ensureDir(Path.dirname(dest)); -// await FS.copy(path, dest); -// }; - -// await copy("meta.json"); - -// for await (const file of walker) { -// await copy(file.path); -// } - -// log("Compressing file"); - -// await Compress.Tar.compress(tmpDir, packedFile, { -// excludeSrc: true, -// }); - -// const url = new URL(config.registry); -// url.pathname = "/api/package/" + meta.name; - -// log("Uploading new package version"); - -// const res = await fetch(url, { -// method: "POST", -// body: await Deno.readFile(packedFile), -// headers: { -// Authorization: -// "Basic " + -// Base64.encode(config.username + ":" + config.password), -// }, -// }).then((res) => (res.status === 200 ? res.json() : res.statusText)); - -// log("Upload finished. Result:", res); - -// if (typeof res === "string" || res.error) { -// console.log( -// Colors.red("Error: " + (typeof res == "string" ? res : res.error)) -// ); -// } else { -// if (res.success) { -// console.log(Colors.green("Upload successfull")); -// } -// } -// } finally { -// await Deno.remove(tmpDir, { recursive: true }); -// await Deno.remove(packedFile); -// } -// } - -// async function _getMeta(): Promise { -// log("Reading meta.json"); -// return (await FS.readJson("meta.json")) as IMeta; -// } - -// async function _setMeta(meta: IMeta): Promise { -// log("Saving meta.json"); -// return FS.writeJson("meta.json", meta, { -// spaces: " ", -// }); -// } - -// if (!username || !password || !registry) { -// if (!flags.options.interactive) { -// console.error( -// Colors.red("Run setup or set necessary value in " + CONFIG_LOCATION) -// ); -// } else { -// log("Running setup"); -// await setup(); -// } -// } diff --git a/cli/global.ts b/cli/global.ts index 980b7d3..38138ed 100644 --- a/cli/global.ts +++ b/cli/global.ts @@ -1,4 +1,4 @@ -import { Ini, Cliffy, Compress, Base64, FS, Colors } from "./deps.ts"; +import { Ini, FS, Colors } from "./deps.ts"; import setupCMD from "./commands/setup.ts"; export interface IMeta { diff --git a/cli/meta.json b/cli/meta.json index 44a2651..75b46d0 100644 --- a/cli/meta.json +++ b/cli/meta.json @@ -4,8 +4,5 @@ "description": "CLI for the DenReg package registry", "author": "Fabian Stamm ", "contributors": [], - "files": [ - "**/*.ts", - "**/*.js" - ] -} \ No newline at end of file + "files": ["**/*.ts", "**/*.js", "README.md"] +}