DenReg/cli/commands/publish.ts

146 lines
4.3 KiB
TypeScript
Raw Normal View History

2020-07-28 17:43:58 +00:00
import { Colors, Path, FS, Compress, Base64 } from "../deps.ts";
import { getMeta, IMeta, log, getConfig } from "../global.ts";
2020-09-14 21:47:48 +00:00
import { ServerError } from "../helper/server_error.ts";
2020-07-28 17:43:58 +00:00
2020-08-16 17:20:37 +00:00
async function runScript(script: string) {
console.log(Colors.bold(Colors.blue("Running script:")), script);
const runPerm = await Deno.permissions.query({
name: "run",
});
if (runPerm.state !== "granted") {
console.log(
Colors.red("Missing --allow-run permission. Cannot run hooks!")
);
throw new Error("Missing --allow-run permission. Cannot run hooks!");
}
const process = Deno.run({
cmd: ["deno", "run", "-A", "--unstable", script],
});
const status = await process.status();
console.log(Colors.bold(Colors.blue("Finished script:")), script);
if (!status.success) {
throw new Error(
"A hook did not complete sucessfully. This is not a issue of denreg!"
);
}
}
async function runHooks(hooks: undefined | string | string[]) {
if (!hooks) return;
if (typeof hooks === "string") {
hooks = [hooks];
}
for (const hook of hooks) {
await runScript(hook);
}
}
export default async function publish(options: { dry: boolean }) {
const originalMeta = await getMeta();
if (originalMeta.hooks) {
log("Running prepublish hooks");
await runHooks(originalMeta.hooks.prepublish);
}
const meta = await getMeta();
//TODO: Output Diff between original and result meta
2020-07-28 17:43:58 +00:00
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()) + ".tar";
2020-07-28 17:43:58 +00:00
try {
const walker = FS.walk(meta.root || ".", {
2020-07-28 17:43:58 +00:00
includeDirs: false,
includeFiles: true,
match: meta.files.map((file) => Path.globToRegExp(file)),
});
log("Copying files to package to", tmpDir);
const copy = async (path: string, abs?: boolean) => {
const relative = abs ? path : Path.relative(meta.root || ".", path);
log("Adding file:", path, "as", relative);
const dest = Path.join(tmpDir, relative);
2020-07-28 17:43:58 +00:00
await FS.ensureDir(Path.dirname(dest));
await FS.copy(path, dest);
};
await copy("meta.json", true);
2020-07-28 17:43:58 +00:00
for await (const file of walker) {
await copy(file.path);
}
log("Compressing files into", packedFile);
2020-07-28 17:43:58 +00:00
await Compress.Tar.compress(tmpDir, packedFile, {
excludeSrc: true,
});
const url = new URL(getConfig("registry"));
url.pathname = "/api/package/" + meta.name;
console.log(
"Pushing version",
Colors.blue(meta.version),
"to repository"
);
if (!options.dry) {
log("Uploading new package version");
await fetch(url, {
method: "POST",
body: await Deno.readFile(packedFile),
headers: {
Authorization:
"Basic " +
Base64.encode(
getConfig("username") + ":" + getConfig("password")
),
},
})
.then((res) =>
res.status === 200
? res.json()
2020-09-14 21:47:48 +00:00
: Promise.reject(new ServerError(res.statusText))
)
.then((res) => {
if (!res.success) {
2020-09-14 21:47:48 +00:00
throw new ServerError(res.message);
} else {
console.log(Colors.green("Upload successfull"));
}
})
.catch((err) => {
2020-09-14 21:47:48 +00:00
//import { ServerError } from "../helper/server_error.ts";
if (err instanceof ServerError)
console.log(Colors.red("Server Error: " + err.message));
else console.log(Colors.red("Error: " + err.message));
});
} else {
console.log(Colors.yellow("Dry run. Skipping upload"));
}
2020-08-16 17:21:17 +00:00
if (meta.hooks) {
log("Running postpublish hooks");
await runHooks(meta.hooks.postpublish);
}
2020-07-28 17:43:58 +00:00
} finally {
await Deno.remove(tmpDir, { recursive: true });
await Deno.remove(packedFile);
}
}