gitfleet 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require("commander");
4
+
5
+ const init = require("../commands/init");
6
+ const add = require("../commands/add");
7
+ const status = require("../commands/status");
8
+ const pull = require("../commands/pull");
9
+ const exec = require("../commands/exec");
10
+ const scan = require("../commands/scan");
11
+ const list = require("../commands/list")
12
+ const branch = require("../commands/branch")
13
+
14
+
15
+ const program = new Command();
16
+
17
+ program
18
+ .name("gitfleet")
19
+ .description("Manage multiple git repositories");
20
+
21
+ program.command("init").action(init);
22
+
23
+ program.command("add <path>").action(add);
24
+
25
+ program.command("status").action(status);
26
+
27
+ program.command("pull").action(pull);
28
+
29
+ program.command("scan <path>").action(scan);
30
+
31
+ program.command("exec <command>").action(exec)
32
+
33
+ program.command("list").action(list)
34
+
35
+ program.command("branch").action(branch)
36
+
37
+ program.parse();
@@ -0,0 +1,32 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const { loadConfig, saveConfig } = require("../core/config");
5
+
6
+ module.exports = function (repoPath) {
7
+
8
+ const gitDir = path.join(repoPath, ".git");
9
+
10
+ if (!fs.existsSync(repoPath)) {
11
+ console.log("Path does not exist:", repoPath);
12
+ return;
13
+ }
14
+
15
+ if (!fs.existsSync(gitDir)) {
16
+ console.log("Not a git repository:", repoPath);
17
+ return;
18
+ }
19
+
20
+ const config = loadConfig();
21
+
22
+ if (config.repos.includes(repoPath)) {
23
+ console.log("⚠ Repo already added:", repoPath);
24
+ return;
25
+ }
26
+
27
+ config.repos.push(repoPath);
28
+
29
+ saveConfig(config);
30
+
31
+ console.log("✅ Added repo:", repoPath);
32
+ };
@@ -0,0 +1,21 @@
1
+ const { loadConfig } = require("../core/config");
2
+
3
+ const { execSync } = require("child_process");
4
+
5
+
6
+
7
+ module.exports = function () {
8
+
9
+ const config = loadConfig();
10
+
11
+ for(const repo of config.repos){
12
+ try{
13
+
14
+ console.log(`\n▶ ${repo} : `);
15
+
16
+ execSync("git branch", { cwd: repo, stdio: "inherit" });
17
+ }catch(e){
18
+ console.log("Error:",e)
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ const { loadConfig } = require("../core/config");
2
+
3
+ const { execSync } = require("child_process");
4
+
5
+
6
+
7
+ module.exports = function (command) {
8
+
9
+ const config = loadConfig();
10
+
11
+ for(const repo of config.repos){
12
+ try{
13
+
14
+ console.log(`\n▶ Running in ${repo}`);
15
+
16
+ execSync(command, { cwd: repo, stdio: "inherit" });
17
+ }catch(e){
18
+ console.log("Error:",e)
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,10 @@
1
+ const { saveConfig, configFile } = require("../core/config");
2
+
3
+ module.exports = function () {
4
+
5
+ saveConfig({ repos: [] });
6
+
7
+ console.log("GitFleet initialized");
8
+ console.log("Config file:", configFile);
9
+
10
+ };
@@ -0,0 +1,16 @@
1
+ const { loadConfig } = require("../core/config");
2
+ const path = require("path")
3
+
4
+ module.exports = function(){
5
+ const config = loadConfig();
6
+
7
+ if (config.repos.length === 0) {
8
+ console.log("No repositories added.");
9
+ return;
10
+ }
11
+
12
+ config.repos.forEach((repo, i) => {
13
+ const name = path.basename(repo);
14
+ console.log(`${i + 1}. ${name} → ${repo}`);
15
+ });
16
+ }
@@ -0,0 +1,29 @@
1
+ const { loadConfig } = require("../core/config");
2
+ const { execSync } = require("child_process");
3
+
4
+ function isRepoDirty(repo) {
5
+
6
+ const status = execSync("git status --porcelain", { cwd: repo })
7
+ .toString()
8
+ .trim();
9
+
10
+ return status.length > 0;
11
+
12
+ }
13
+
14
+ module.exports = function () {
15
+ const config = loadConfig();
16
+ for (const repo of config.repos) {
17
+ try {
18
+ if (isRepoDirty(repo)) {
19
+ console.log(`⚠ Skipping ${repo} (local changes)`);
20
+ continue;
21
+ }
22
+ console.log(`⬇ Pulling ${repo}`);
23
+ execSync("git pull", { cwd: repo, stdio: "inherit" });
24
+ } catch (err) {
25
+ console.log(`Failed for ${repo}`);
26
+ }
27
+ }
28
+
29
+ };
@@ -0,0 +1,63 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const { loadConfig, saveConfig } = require("../core/config");
5
+
6
+ function findRepos(dir, repos = []) {
7
+
8
+ const items = fs.readdirSync(dir, { withFileTypes: true });
9
+
10
+ for (const item of items) {
11
+
12
+ const fullPath = path.join(dir, item.name);
13
+
14
+ // if .git folder found
15
+ if (item.name === ".git") {
16
+ repos.push(dir);
17
+ continue;
18
+ }
19
+
20
+ if (item.isDirectory() && item.name !== "node_modules") {
21
+ findRepos(fullPath, repos);
22
+ }
23
+
24
+ }
25
+
26
+ return repos;
27
+ }
28
+
29
+ module.exports = function (scanPath) {
30
+
31
+ scanPath = path.resolve(scanPath);
32
+
33
+ if (!fs.existsSync(scanPath)) {
34
+ console.log("❌ Path does not exist:", scanPath);
35
+ return;
36
+ }
37
+
38
+ const repos = findRepos(scanPath);
39
+
40
+ if (repos.length === 0) {
41
+ console.log("No git repositories found.");
42
+ return;
43
+ }
44
+
45
+ const config = loadConfig();
46
+
47
+ let added = 0;
48
+
49
+ for (const repo of repos) {
50
+
51
+ if (!config.repos.includes(repo)) {
52
+ config.repos.push(repo);
53
+ added++;
54
+ console.log("✅ Added:", repo);
55
+ }
56
+
57
+ }
58
+
59
+ saveConfig(config);
60
+
61
+ console.log("\nFound:", repos.length);
62
+ console.log("Added:", added);
63
+ };
@@ -0,0 +1,29 @@
1
+ const { loadConfig } = require("../core/config");
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = function () {
5
+
6
+ const config = loadConfig();
7
+
8
+ for (const repo of config.repos) {
9
+
10
+ try {
11
+
12
+ const output = execSync("git status --porcelain", { cwd: repo })
13
+ .toString()
14
+ .trim();
15
+
16
+ if (!output) {
17
+ console.log(`Repo: ${repo} → clean`);
18
+ } else {
19
+ const lines = output.split("\n").length;
20
+ console.log(`Repo: ${repo} → ${lines} changes`);
21
+ }
22
+
23
+ } catch {
24
+ console.log(`Repo: ${repo} → error`);
25
+ }
26
+
27
+ }
28
+
29
+ };
package/core/config.js ADDED
@@ -0,0 +1,28 @@
1
+ const fs = require("fs");
2
+ const os = require("os");
3
+ const path = require("path");
4
+
5
+ const configDir = path.join(os.homedir(), ".gitfleet");
6
+ const configFile = path.join(configDir, "config.json");
7
+
8
+ function loadConfig() {
9
+ if (!fs.existsSync(configFile)) {
10
+ return { repos: [] };
11
+ }
12
+
13
+ return JSON.parse(fs.readFileSync(configFile));
14
+ }
15
+
16
+ function saveConfig(config) {
17
+ if (!fs.existsSync(configDir)) {
18
+ fs.mkdirSync(configDir);
19
+ }
20
+
21
+ fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
22
+ }
23
+
24
+ module.exports = {
25
+ loadConfig,
26
+ saveConfig,
27
+ configFile,
28
+ };
package/core/git.js ADDED
@@ -0,0 +1,21 @@
1
+ const { execSync } = require("child_process");
2
+
3
+ function runGit(repo, command) {
4
+
5
+ try {
6
+
7
+ const output = execSync(command, { cwd: repo });
8
+
9
+ return output.toString();
10
+
11
+ } catch (err) {
12
+
13
+ return "Error";
14
+
15
+ }
16
+
17
+ }
18
+
19
+ module.exports = {
20
+ runGit,
21
+ };
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "gitfleet",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "keywords": ["git",
9
+ "cli",
10
+ "developer-tools",
11
+ "git-manager"],
12
+ "description": "",
13
+ "dependencies": {
14
+ "chalk": "^5.6.2",
15
+ "commander": "^14.0.3",
16
+ "ora": "^9.3.0"
17
+ },
18
+ "bin": {
19
+ "gitfleet": "./bin/gitfleet.js"
20
+ },
21
+ "author": "Kartik Singla",
22
+ "license": "MIT"
23
+ }