Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add plugin pack command (Experimental) #915

Merged
merged 16 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config = {
testPathIgnorePatterns: [
"<rootDir>/node_modules/",
"<rootDir>/src/__tests__/setup.ts",
"<rootDir>/src/plugin/packer/__tests__/helpers/",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

理想的には__tests__の中であっても*.tests.tsのみを試験対象にするように設定変更する方が良い
が、一旦決め打ちでhelpersを除外している。

"fixtures",
],
};
Expand Down
8 changes: 8 additions & 0 deletions license-manager.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ const OVERRIDE_LICENSES_TEXT = {
licensePageUrl:
"https://raw.githubusercontent.com/dominictarr/through/master/LICENSE.MIT",
},
"node-rsa": {
// License text is written in README.md
licenseText: "See https://github.com/rzcoder/node-rsa#license",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node-rsaはLICENSEファイルがなく、READMEに直接ライセンス本文が書かれているため、license-managerで抽出できない。
そのためREADMEへのリンクを記載する。

},
"stream-buffers": {
licensePageUrl:
"https://raw.githubusercontent.com/samcday/node-stream-buffer/refs/heads/main/UNLICENSE",
},
};

module.exports = config;
16 changes: 15 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@
"@cybozu/eslint-config": "^24.0.0-beta.0",
"@cybozu/license-manager": "^1.2.1",
"@octokit/rest": "^20.1.1",
"@types/debug": "^4.1.12",
"@types/jest": "^29.5.14",
"@types/node": "^18.19.59",
"@types/node-rsa": "^1.1.4",
"@types/rollup-plugin-auto-external": "^2.0.5",
"@types/stream-buffers": "^3.0.7",
"@types/yargs": "^17.0.33",
"@types/yauzl": "^2.10.3",
"@types/yazl": "^2.4.5",
"@vercel/ncc": "^0.38.2",
"ajv": "^8.17.1",
"allure-commandline": "^2.31.0",
Expand All @@ -101,13 +106,22 @@
},
"dependencies": {
"@inquirer/prompts": "^5.3.8",
"@kintone/plugin-manifest-validator": "^10.2.2",
"@kintone/rest-api-client": "^5.5.2",
"chalk": "4.1.2",
"chokidar": "^4.0.1",
"csv-parse": "^4.16.3",
"csv-stringify": "5.6.5",
"debug": "^4.3.7",
"execa": "^9.4.1",
"https-proxy-agent": "^7.0.5",
"iconv-lite": "^0.6.3",
"yargs": "^17.7.2"
"mkdirp": "^3.0.1",
"node-rsa": "^1.1.1",
"stream-buffers": "^3.0.3",
"yargs": "^17.7.2",
"yauzl": "^3.1.3",
"yazl": "^3.1.0"
},
"packageManager": "[email protected]",
"pnpm": {
Expand Down
400 changes: 316 additions & 84 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/cli/main.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import yargs from "yargs";
import { recordCommand } from "./record";
import { pluginCommand } from "./plugin";
import packageJson from "../../package.json";
import { logHandler, logOptions } from "./logOption";

// eslint-disable-next-line no-unused-expressions
yargs
.command(recordCommand)
// NOTE: Hide the plugin command because it's in very early development.
.command({ ...pluginCommand, describe: false })
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

describe: falseでコマンド非公開になる。

.options(logOptions)
.middleware(logHandler)
.demandCommand()
Expand Down
22 changes: 22 additions & 0 deletions src/cli/plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { CommandModule } from "yargs";
import type yargs from "yargs";
import { packCommand } from "./pack";
import { emitExperimentalWarning } from "../../utils/stability";

const command = "plugin";

const describe = "[Experimental] Commands for kintone plugin";

const builder = (args: yargs.Argv) => args.command(packCommand).demandCommand();

const handler = () => {
emitExperimentalWarning("This feature is under early development");
/** noop **/
};

export const pluginCommand: CommandModule = {
command,
describe,
builder,
handler,
};
59 changes: 59 additions & 0 deletions src/cli/plugin/pack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type yargs from "yargs";
import type { CommandModule } from "yargs";
import cli from "../../plugin/packer/cli";
import { emitExperimentalWarning } from "../../utils/stability";

const command = "pack";

const describe = "[Experimental] Packaging plugin project to a zip file";

const builder = (args: yargs.Argv) =>
args
.option("input", {
describe: "The input plugin project directory",
type: "string",
demandOption: true,
requiresArg: true,
})
.option("output", {
describe:
"The destination path of generated plugin file\nDefault to plugin.zip on current directory",
type: "string",
default: "plugin.zip",
requiresArg: true,
})
.option("private-key", {
describe:
"The path of private key file\nIf omitted, new private key will be generated.",
type: "string",
requiresArg: true,
})
.option("watch", {
describe: "run in watch mode",
type: "boolean",
});

type Args = yargs.Arguments<
ReturnType<typeof builder> extends yargs.Argv<infer U> ? U : never
>;

const handler = async (args: Args) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static Badge
今じゃなくて全然いいのですが、今後も開発中の機能で似たようなhandlerを作る事になりそうなので、
flagscallbackから開発中のhandlerを作れるような仕組みがあると良さそうに思いました。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

後続の #916 で対応します!

emitExperimentalWarning("This feature is under early development");
const flags = {
ppk: args["private-key"],
out: args.output,
watch: args.watch,
};
if (process.env.NODE_ENV === "test") {
console.log(JSON.stringify({ pluginDir: args.input, flags: flags }));
Comment on lines +47 to +48
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここはplugin-packerの実装を踏襲

} else {
await cli(args.input, flags);
}
};

export const packCommand: CommandModule<{}, Args> = {
command,
describe,
builder,
handler,
};
6 changes: 3 additions & 3 deletions src/cli/record.ts → src/cli/record/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { CommandModule } from "yargs";
import type yargs from "yargs";
import { exportCommand } from "./record/export";
import { importCommand } from "./record/import";
import { deleteCommand } from "./record/delete";
import { exportCommand } from "./export";
import { importCommand } from "./import";
import { deleteCommand } from "./delete";

const command = "record";

Expand Down
2 changes: 2 additions & 0 deletions src/plugin/packer/__tests__/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fixtures/sample-plugin/plugin.zip
fixtures/sample-plugin/*.ppk
79 changes: 79 additions & 0 deletions src/plugin/packer/__tests__/bin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import path from "path";
import type { ExecaMethod } from "execa";
import pkg from "../../../../package.json";

// TODO: Remove this test file
const execa = {} as ExecaMethod<{}>;

describe.skip("bin", () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この試験はコマンドラインオプションの試験なので、一旦Skipにする。
(cli-kintone側のCLIが確定したら修正する)

it("should output version with --version", () =>
exec("--version").then((result) => {
expect(result.stdout).toBe(pkg.version);
}));

it("should fail without args", () =>
exec().then(
() => {
throw new Error("should be rejected");
},
(result) => {
expect(/An argument `PLUGIN_DIR` is required/.test(result.stderr)).toBe(
true,
);
},
));

it("should recieve 1st arg as PLUGIN_DIR", () =>
exec("foo").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: false },
});
}));

it("should recieve --ppk", () =>
exec("foo", "--ppk", "bar").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: false, ppk: "bar" },
});
}));

it("should recieve --out", () =>
exec("foo", "--out", "bar").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: false, out: "bar" },
});
}));

it("should recieve --watch", () =>
exec("foo", "--watch").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: true },
});
}));

it("should recieve -w as an alias of --watch", () =>
exec("foo", "-w").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: true },
});
}));

it("should filter unexpected option", () =>
exec("foo", "--bar").then((result) => {
expect(JSON.parse(result.stdout)).toStrictEqual({
pluginDir: "foo",
flags: { watch: false },
});
}));
});

const exec = (...args: string[]) => {
const binPath = path.resolve(__dirname, "../bin/cli.js");
const env = Object.assign({}, process.env, { NODE_ENV: "test" });
return execa(binPath, args, { env });
};
Loading
Loading