diff --git a/README.md b/README.md index b0f94b2..e56fdbc 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # 🧰 Dev Toolkit CLI -[![npm version](https://img.shields.io/npm/v/@forz70043/dev-toolkit.svg?style=flat-square&color=00bfa5)](https://www.npmjs.com/package/@forz70043/dev-toolkit) +[![npm version](https://img.shields.io/npm/v/@forz70043/dev-toolkit.svg?style=flat-square&color=00bfa5)](https://www.npmjs.com/package/@forz/dev-toolkit) [![npm downloads](https://img.shields.io/npm/dt/@forz70043/dev-toolkit.svg?style=flat-square&color=blue)](https://www.npmjs.com/package/@forz70043/dev-toolkit) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](LICENSE) [![GitHub Repo](https://img.shields.io/badge/source-GitHub-black?logo=github&style=flat-square)](https://github.com/Forz70043/dev-toolkit) -> A powerful CLI toolkit that automates common developer tasks — clean Git branches, check `.env` files, lint commits, and show project info. +> A powerful CLI dev toolkit that automates common developer tasks — clean Git branches, check `.env` files, lint commits, and show project info. > Developed with ā¤ļø by [Alfonso Pisicchio](https://pisicchio.dev). @@ -60,8 +60,8 @@ dev project-info * āœ… Environment variable validator * āœ… Commit linter * āœ… Project info command +* āœ… GitHub API integration for remote repo stats * āŒ dev help command with autocomplete -* āŒ GitHub API integration for remote repo stats ### šŸ§‘ā€šŸ’» Author diff --git a/bin/dev.js b/bin/dev.js index ccb7db0..a7e01eb 100755 --- a/bin/dev.js +++ b/bin/dev.js @@ -1,19 +1,37 @@ #!/usr/bin/env node +/** + * dev-toolkit CLI + * Author: Alfonso Pisicchio + * License: MIT + */ + import { Command } from "commander"; import chalk from "chalk"; import { gitClean } from "../commands/git-clean.js"; import { envCheck } from "../commands/env-check.js"; import { lintCommit } from "../commands/lint-commit.js"; import { projectInfo } from "../commands/project-info.js"; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const pkgPath = path.resolve(__dirname, "../package.json"); +const { version } = JSON.parse(fs.readFileSync(pkgPath, "utf-8")); const program = new Command(); +// ======================================= +// šŸ“¦ Program Definition +// ======================================= program .name("dev") .description("🧰 Developer Toolkit CLI") - .version("1.0.0"); + .version(version); -// Commands +// ======================================= +// 🧩 Commands +// ======================================= program .command("git-clean") .description("Remove local Git branches not present in remote") diff --git a/commands/project-info.js b/commands/project-info.js index e4fe486..3d08435 100644 --- a/commands/project-info.js +++ b/commands/project-info.js @@ -1,22 +1,55 @@ import fs from "fs"; import chalk from "chalk"; import simpleGit from "simple-git"; +import { execSync } from "child_process"; + +const fetchFn = global.fetch || (await import("node-fetch")).default; export async function projectInfo() { - const pkgPath = "./package.json"; + try { + const remoteUrl = execSync("git config --get remote.origin.url").toString().trim(); - const git = simpleGit(); - const currentBranch = (await git.branchLocal()).current; - const lastCommit = (await git.log({ n: 1 })).latest; + if (!remoteUrl) { + console.log(chalk.red("āŒ No remote Git repository found.")); + return; + } - if (fs.existsSync(pkgPath)) { - const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8")); - console.log(chalk.cyan("šŸ“¦ Project Info")); - console.log(chalk.white(`Name: ${pkg.name}`)); - console.log(chalk.white(`Version: ${pkg.version}`)); - } + const match = remoteUrl.match(/github\.com[:/](.+?)\/(.+?)(?:\.git)?$/); + if (!match) { + console.log(chalk.red("āŒ Repository does not appear to be on GitHub.")); + return; + } + + const [_, owner, repo] = match; + + const res = await fetchFn(`https://api.github.com/repos/${owner}/${repo}`); + if (!res.ok) { + console.log(chalk.red(`āŒ Unable to retrieve info from GitHub (${res.status})`)); + return; + } - console.log(chalk.white(`Branch: ${currentBranch}`)); - console.log(chalk.white(`Last commit: ${lastCommit.message}`)); - console.log(chalk.gray(`By ${lastCommit.author_name} on ${lastCommit.date}`)); + const data = await res.json(); + + console.log(chalk.bold.cyan(`\nšŸ“¦ Repository Info: ${data.full_name}`)); + console.log(chalk.gray(data.html_url)); + console.log(""); + console.log(`${chalk.yellow("🪶 Description:")} ${data.description || "—"}`); + console.log(`${chalk.yellow("⭐ Stars:")} ${data.stargazers_count}`); + console.log(`${chalk.yellow("šŸ“ Forks:")} ${data.forks_count}`); + console.log(`${chalk.yellow("šŸ‘€ Open Issues:")} ${data.open_issues_count}\n`); + console.log(`${chalk.yellow("🧱 Language:")} ${data.language || "Unknown"}`); + console.log(`${chalk.yellow("šŸ•’ Last Updated:")} ${new Date(data.updated_at).toLocaleString()}`); + + const commitsRes = await fetchFn(`https://api.github.com/repos/${owner}/${repo}/commits?per_page=1`); + if (commitsRes.ok) { + const [lastCommit] = await commitsRes.json(); + if (lastCommit) { + console.log(`${chalk.yellow("🧩 Last Commit:")} ${lastCommit.commit.message}`); + console.log(`${chalk.gray(`by ${lastCommit.commit.author.name} on ${lastCommit.commit.author.date}`)}\n`); + } + } + + } catch (err) { + console.error(chalk.red(`āŒ Error: ${err.message}`)); + } } diff --git a/package.json b/package.json index 07cbf7c..e53808f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@forz/dev-toolkit", - "version": "1.0.3", - "description": "🧰 A developer CLI for Git, env, and project automation by Alfonso Pisicchio", + "version": "1.0.4", + "description": "🧰 Developer Toolkit CLI for Git, env, and project automation by Alfonso Pisicchio", "type": "module", "bin": { "dev": "./bin/dev.js" @@ -31,4 +31,4 @@ "dotenv": "^16.4.0", "simple-git": "^3.24.0" } -} +} \ No newline at end of file