Skip to content

Commit

Permalink
feat(cli): init, config, generate, help commands
Browse files Browse the repository at this point in the history
  • Loading branch information
adiologydev committed Aug 27, 2024
1 parent bd6f321 commit 11d0540
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 58 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,7 @@ dist

# Finder (MacOS) folder config
.DS_Store

# TinyJobs
jobs
tinyjobs.json
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"peerDependencies": {},
"dependencies": {
"@clack/prompts": "^0.7.0",
"conf": "^13.0.1",
"picocolors": "^1.0.1"
}
}
29 changes: 29 additions & 0 deletions packages/cli/src/base/exampleJobs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const typescriptJobExample = `import { Job } from "tinyjobs";
export default class ExampleJob extends Job {
constructor() {
super();
this.name = 'ExampleJob';
}
async run() {
console.log('Hello from ExampleJob!');
}
}
`;

const javascriptJobExample = `const { Job } = require("tinyjobs");
module.exports = class ExampleJob extends Job {
constructor() {
super();
this.name = 'ExampleJob';
}
async run() {
console.log('Hello from ExampleJob!');
}
};
`;

export { typescriptJobExample, javascriptJobExample };
95 changes: 95 additions & 0 deletions packages/cli/src/commands/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { log, select, text } from "@clack/prompts";
import color from "picocolors";
import config from "../utils/config";

async function configCommand(args: string[]) {
let command: string | symbol = args[0];

if (!command)
command = await select({
message: "Select what you'd like to configure:",
options: [
{
value: "directory",
label:
"Directory - Configure the directory where TinyJobs will store jobs",
},
{
value: "language",
label: "Language - Configure the language you are using for TinyJobs",
},
],
});

switch (command) {
case "directory":
case "dir":
let dir: string | symbol = args[1];

if (!dir) {
dir = await text({
message: "Enter the directory where you want to store your jobs:",
});
}

if (dir === config.get("jobsDir")) {
log.info("Directory is already configured.");
break;
}

config.set("jobsDir", dir);
log.info(
`Jobs directory has been configured to ${color.bold(
config.get("jobsDir") as string
)}.`
);
break;

case "language":
case "lang":
let lang: string | symbol = args[1];

if (!lang) {
lang = await select({
message: "Select the language you are using:",
options: [
{
value: "typescript",
label: "TypeScript",
},
{
value: "javascript",
label: "JavaScript",
},
],
});
}

if (lang === config.get("language")) {
log.info("Language is already configured.");
break;
}

try {
config.set(
"language",
lang === "ts" ? "typescript" : lang === "js" ? "javascript" : lang
);
log.info(
`Language has been configured to ${color.bold(
config.get("language") as string
)}.`
);
} catch (e) {
// @ts-expect-error
log.error(e.message);
}
break;

default:
log.info("Invalid option.");
break;
}
}

export default configCommand;
81 changes: 79 additions & 2 deletions packages/cli/src/commands/generate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,82 @@
import color from "picocolors";
import { log, select, text } from "@clack/prompts";
import fs from "fs";
import config from "../utils/config";
import {
javascriptJobExample,
typescriptJobExample,
} from "../base/exampleJobs";
import { pascalCase } from "../utils/utils";

async function generateCommand(args: string[]) {}
async function generateCommand(args: string[]) {
let option: string | symbol = args[0];

if (!option) {
option = await select({
message: "Select from the following generate options:",
options: [
{
value: "types",
label: "Types - Generates types for TinyJobs Handler Intellisense",
},
{
value: "job",
label:
"Job - Generates a new Job with a specified name in the jobs directory",
},
],
});
}

switch (option) {
case "types":
console.log("Generating types...");
break;

case "job":
await generateJob(args);
break;

default:
console.log("Invalid option.");
break;
}
}

export default generateCommand;

const generateJob = async (args: string[]) => {
if (!config.get("jobsDir" || !config.get("language")))
log.error(
"TinyJobs is not initialized. Run 'tinyjobs init' to initialize TinyJobs."
);

let jobName: string | symbol = args[1];
if (!jobName) {
jobName = await text({
message: "Enter the name of the job:",
});
}

const language = config.get("language");

const exists = fs.existsSync(
`${process.cwd()}/${config.get("jobsDir")}/${pascalCase(String(jobName))}.${language === "typescript" ? "ts" : "js"}`
);

if (exists) {
log.error("Job with this name already exists.");
return;
}

const jobTemplate =
language === "typescript" ? typescriptJobExample : javascriptJobExample;

fs.writeFileSync(
`${process.cwd()}/${config.get("jobsDir")}/${pascalCase(String(jobName)).replace(/.ts|.js/gi, "")}.${
language === "typescript" ? "ts" : "js"
}`,
jobTemplate.replace(/ExampleJob/g, pascalCase(String(jobName)))
);

log.success("Job generated successfully.");
};
52 changes: 51 additions & 1 deletion packages/cli/src/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,57 @@ import { log } from "@clack/prompts";
import color from "picocolors";

async function helpCommand(args: string[]) {
log.info("This is the help command.");
const command = args[0];

if (command) {
switch (command) {
case "generate":
log.info(
`${color.bold("tinyjobs generate types")}\nGenerate TypeScript types for your jobs.`
);
log.info(
`${color.bold("tinyjobs generate job [name]")}\nGenerate a new job with the specified name.`
);
break;

case "init":
log.info(
`${color.bold("tinyjobs init")}\nInitialize TinyJobs in your project.`
);
break;

case "config":
log.info(
`${color.bold("tinyjobs config directory [name]")}\nConfigure the directory where TinyJobs will store jobs.`
);
log.info(
`${color.bold("tinyjobs config language [typescript|javascript|ts|js]")}\nConfigure the language you are using for TinyJobs.`
);
break;

case "version":
log.info(
`${color.bold("tinyjobs version")}\nDisplay the current version of TinyJobs.`
);
break;

default:
log.error("Command not found.");
break;
}
} else {
log.info("Welcome to the TinyJobs CLI!");

log.info(
`To get started, run ${color.bold("tinyjobs init")} to set up your project.`
);

log.info(
`To generate a new job, run ${color.bold("tinyjobs generate")} and follow the prompts.`
);

log.info(`To configure TinyJobs, run ${color.bold("tinyjobs config")} `);
}
}

export default helpCommand;
102 changes: 100 additions & 2 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,106 @@
import { log } from "@clack/prompts";
import color from "picocolors";
import { log, select, text } from "@clack/prompts";
import fs from "fs";
import config from "../utils/config";
import { javascriptJobExample, typescriptJobExample } from "../base/exampleJobs";

async function initCommand(args: string[]) {
// Confirm initialization
log.info("This is the init command.");
const confirm = await select({
message:
"Would you like to initialize TinyJobs in this project? This will create a tinyjobs.json file and an example job.",
options: [
{ value: true, label: "Yes" },
{ value: false, label: "No" },
],
});

if (!confirm) {
log.info("Cancelled TinyJobs initialization. Exiting...");
process.exit(0);
}

// Selecting the language
const type = await select({
message: "Select the language you are using:",
options: [
{
value: "typescript",
label: "TypeScript",
},
{
value: "javascript",
label: "JavaScript",
},
],
});

config.set("language", type);

// Selecting the directory to store jobs and types
const jobsDir = await select({
message: "Select the directory to store your jobs:",
options: [
{
value: "jobs",
label: "jobs - A directory named 'jobs' in the root of your project",
},
{
value: "custom",
label: "custom - A custom directory",
},
],
});

let customDir: string | symbol = "";

if (jobsDir === "custom") {
customDir = await text({
message: "Enter the custom directory name:",
});
}

const finalDir = jobsDir === "custom" ? customDir : jobsDir;

if (!fs.existsSync(`${process.cwd()}/${finalDir}`))
fs.mkdirSync(`${process.cwd()}/${finalDir}`, { recursive: true });

config.set("jobsDir", finalDir);

// Generate example job
await generateExampleJob(
type as "typescript" | "javascript",
String(finalDir)
);

log.success("TinyJobs initialized successfully.");
}

export default initCommand;

const generateExampleJob = async (
type: "javascript" | "typescript",
finalDir: string
) => {
if (type === "typescript") {
if (!fs.existsSync(`${process.cwd()}/${finalDir}/ExampleJob.ts`)) {
fs.writeFileSync(
`${process.cwd()}/${finalDir}/ExampleJob.ts`,
typescriptJobExample
);
log.info("Example job generated successfully.");
} else {
log.warn("ExampleJob.ts already exists. Skipping...");
}
} else {
if (!fs.existsSync(`${process.cwd()}/${finalDir}/ExampleJob.js`)) {
fs.writeFileSync(
`${process.cwd()}/${finalDir}/ExampleJob.js`,
javascriptJobExample
);
log.info("Example job generated successfully.");
} else {
log.warn("ExampleJob.js already exists. Skipping...");
}
}
};
Loading

0 comments on commit 11d0540

Please sign in to comment.