repo-branch 0.0.7 → 0.0.8

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.
Files changed (2) hide show
  1. package/dist/index.js +91 -113
  2. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -1,134 +1,95 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
37
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
5
  };
39
6
  Object.defineProperty(exports, "__esModule", { value: true });
40
7
  const commander_1 = require("commander");
41
- const rest_1 = require("@octokit/rest");
42
8
  const chalk_1 = __importDefault(require("chalk"));
43
9
  const inquirer_1 = __importDefault(require("inquirer"));
44
10
  const listr_1 = __importDefault(require("listr"));
45
11
  const dotenv_1 = __importDefault(require("dotenv"));
46
- const path = __importStar(require("path"));
47
- const fs = __importStar(require("fs"));
12
+ const util_1 = require("util");
13
+ const exec = (0, util_1.promisify)(require("child_process").exec);
48
14
  // Load environment variables from .env file
49
15
  dotenv_1.default.config({ quiet: true });
50
16
  const program = new commander_1.Command();
51
17
  // Configuration - load from environment variables
52
18
  const GITHUB_ORG = process.env.BRANCH_SYNC_GITHUB_ORG || "";
53
- const GITHUB_OWNER = process.env.BRANCH_SYNC_GITHUB_OWNER || "";
54
- const GITHUB_TOKEN = process.env.BRANCH_SYNC_GITHUB_TOKEN || "";
55
- const OWNER = GITHUB_ORG || GITHUB_OWNER;
56
- // Function to check if .env file exists
57
- function checkEnvFile() {
58
- const envPath = path.resolve(process.cwd(), ".env");
59
- return fs.existsSync(envPath);
60
- }
61
- // Function to validate environment variables
62
- function validateEnv() {
63
- if (!OWNER) {
64
- console.error(chalk_1.default.red("❌ Neither BRANCH_SYNC_GITHUB_ORG nor BRANCH_SYNC_GITHUB_OWNER found in environment variables"));
65
- console.error(chalk_1.default.yellow("Please set either BRANCH_SYNC_GITHUB_ORG or BRANCH_SYNC_GITHUB_OWNER in your .env file or as environment variable"));
66
- return false;
19
+ // Get current GitHub user (from gh auth status)
20
+ const getCurrentUser = async () => {
21
+ try {
22
+ const { stdout } = await exec("gh api user --jq .login");
23
+ return stdout.trim();
67
24
  }
68
- if (!GITHUB_TOKEN) {
69
- console.error(chalk_1.default.red(" BRANCH_SYNC_GITHUB_TOKEN not found in environment variables"));
70
- console.error(chalk_1.default.yellow("Please set BRANCH_SYNC_GITHUB_TOKEN in your .env file or as environment variable"));
71
- return false;
25
+ catch (error) {
26
+ throw new Error("Failed to get GitHub user. Please run 'gh auth login'");
27
+ }
28
+ };
29
+ // Function to validate environment and get owner
30
+ const validateAndGetOwner = async () => {
31
+ if (GITHUB_ORG) {
32
+ return GITHUB_ORG;
33
+ }
34
+ try {
35
+ const currentUser = await getCurrentUser();
36
+ return currentUser;
37
+ }
38
+ catch (error) {
39
+ console.error(chalk_1.default.red("❌ Unable to determine GitHub owner"));
40
+ console.error(chalk_1.default.yellow("Please either:"));
41
+ console.error(chalk_1.default.yellow("1. Set BRANCH_SYNC_GITHUB_ORG in your .env file"));
42
+ console.error(chalk_1.default.yellow("2. Run 'gh auth login' to authenticate with GitHub CLI"));
43
+ throw error;
72
44
  }
73
- return true;
74
- }
75
- if (!validateEnv()) {
76
- if (!checkEnvFile()) {
77
- console.error(chalk_1.default.red("\nNo .env file found!"));
78
- console.error(chalk_1.default.yellow("Create a .env file with:"));
79
- console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_TOKEN=your_token_here"));
80
- console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_OWNER=your_username"));
45
+ };
46
+ // Check if GitHub CLI is installed
47
+ const checkGitHubCLI = async () => {
48
+ try {
49
+ await exec("gh --version");
50
+ return true;
81
51
  }
82
- process.exit(1);
83
- }
84
- const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
85
- async function getRepositories() {
52
+ catch (error) {
53
+ return false;
54
+ }
55
+ };
56
+ const getRepositories = async (owner) => {
86
57
  try {
87
- const repos = !!GITHUB_ORG
88
- ? await octokit.paginate(octokit.rest.repos.listForOrg, {
89
- org: OWNER,
90
- username: OWNER,
91
- per_page: 100,
92
- sort: "full_name",
93
- })
94
- : await octokit.paginate(octokit.rest.repos.listForAuthenticatedUser, {
95
- username: OWNER,
96
- per_page: 100,
97
- sort: "full_name",
98
- });
99
- return repos.map((repo) => ({
58
+ const command = `gh repo list ${owner} --limit 1000 --json name,defaultBranchRef,nameWithOwner`;
59
+ const { stdout } = await exec(command);
60
+ const repos = JSON.parse(stdout);
61
+ return repos
62
+ .map((repo) => ({
100
63
  name: repo.name,
101
- defaultBranch: repo.default_branch ?? "main",
102
- full_name: repo.full_name,
103
- }));
64
+ defaultBranch: repo.defaultBranchRef?.name || "main",
65
+ full_name: repo.nameWithOwner,
66
+ }))
67
+ .sort((a, b) => a.full_name.localeCompare(b.full_name));
104
68
  }
105
69
  catch (error) {
106
70
  console.error(chalk_1.default.red("Failed to fetch repositories:"), error);
107
71
  throw error;
108
72
  }
109
- }
110
- async function createBranch(repoName, branchName) {
73
+ };
74
+ const createBranch = async (owner, repoName, branchName) => {
111
75
  try {
112
- const { data: refData } = await octokit.rest.git.getRef({
113
- owner: OWNER,
114
- repo: repoName,
115
- ref: `heads/${(await octokit.rest.repos.get({ owner: OWNER, repo: repoName })).data.default_branch}`,
116
- });
117
- await octokit.rest.git.createRef({
118
- owner: OWNER,
119
- repo: repoName,
120
- ref: `refs/heads/${branchName}`,
121
- sha: refData.object.sha,
122
- });
76
+ // Get default branch
77
+ const { stdout: defaultBranchStdout } = await exec(`gh repo view ${owner}/${repoName} --json defaultBranchRef --jq .defaultBranchRef.name`);
78
+ const defaultBranch = defaultBranchStdout.trim() || "main";
79
+ // Get SHA of default branch
80
+ const { stdout: shaStdout } = await exec(`gh api repos/${owner}/${repoName}/git/refs/heads/${defaultBranch} --jq .object.sha`);
81
+ const sha = shaStdout.trim();
82
+ // Create new branch
83
+ await exec(`gh api repos/${owner}/${repoName}/git/refs -f ref=refs/heads/${branchName} -f sha=${sha}`);
123
84
  }
124
85
  catch (error) {
125
- if (error.status === 422) {
86
+ if (error.stderr && error.stderr.includes("Reference already exists")) {
126
87
  throw new Error(`Branch already exists`);
127
88
  }
128
89
  throw error;
129
90
  }
130
- }
131
- async function selectRepositories(repos) {
91
+ };
92
+ const selectRepositories = async (repos) => {
132
93
  const answers = await inquirer_1.default.prompt([
133
94
  {
134
95
  type: "checkbox",
@@ -142,11 +103,13 @@ async function selectRepositories(repos) {
142
103
  },
143
104
  ]);
144
105
  return answers.selectedRepos;
145
- }
146
- async function run(branchName, repoNames) {
106
+ };
107
+ const run = async (branchName, repoNames) => {
147
108
  try {
148
- console.log(chalk_1.default.blue("🔍 Fetching repositories..."));
149
- const allRepos = await getRepositories();
109
+ // Get owner (org or current user)
110
+ const owner = await validateAndGetOwner();
111
+ console.log(chalk_1.default.blue(`🔍 Fetching repositories for ${owner}...`));
112
+ const allRepos = await getRepositories(owner);
150
113
  let selectedRepos;
151
114
  if (repoNames && repoNames.length > 0) {
152
115
  selectedRepos = allRepos.filter((repo) => repoNames.includes(repo.name));
@@ -168,7 +131,7 @@ async function run(branchName, repoNames) {
168
131
  title: `Creating branch in ${chalk_1.default.cyan(repo.name)}`,
169
132
  task: async () => {
170
133
  try {
171
- await createBranch(repo.name, branchName);
134
+ await createBranch(owner, repo.name, branchName);
172
135
  }
173
136
  catch (error) {
174
137
  if (error.message.includes("already exists")) {
@@ -189,13 +152,28 @@ async function run(branchName, repoNames) {
189
152
  console.error(chalk_1.default.red("Error:"), error);
190
153
  process.exit(1);
191
154
  }
192
- }
193
- program
194
- .name("repo-branch")
195
- .description("Create a branch across multiple GitHub repositories")
196
- .argument("<branch-name>", "name of the branch to create")
197
- .argument("[repositories...]", "repositories to create branch in")
198
- .action((branchName, repositories) => {
199
- run(branchName, repositories);
200
- });
201
- program.parse();
155
+ };
156
+ // Main execution wrapper to avoid top-level await
157
+ (async () => {
158
+ // Check if GitHub CLI is available
159
+ if (!(await checkGitHubCLI())) {
160
+ console.error(chalk_1.default.red(" GitHub CLI not found"));
161
+ console.error(chalk_1.default.yellow("Please install GitHub CLI: https://cli.github.com/"));
162
+ process.exit(1);
163
+ }
164
+ program
165
+ .name("repo-branch")
166
+ .description("Create a branch across multiple GitHub repositories")
167
+ .argument("<branch-name>", "name of the branch to create")
168
+ .argument("[repositories...]", "repositories to create branch in")
169
+ .helpOption("-h, --help", "Display help for command")
170
+ .addHelpText("after", `
171
+ Examples:
172
+ $ repo-branch feature/new-ui
173
+ $ repo-branch feature/new-ui repo1 repo2
174
+ `)
175
+ .action((branchName, repositories) => {
176
+ run(branchName, repositories);
177
+ });
178
+ program.parse();
179
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repo-branch",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Create branches across multiple GitHub repositories simultaneously",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -30,7 +30,6 @@
30
30
  "start": "node dist/index.js"
31
31
  },
32
32
  "dependencies": {
33
- "@octokit/rest": "^22.0.1",
34
33
  "chalk": "^5.6.2",
35
34
  "commander": "^14.0.2",
36
35
  "dotenv": "^17.2.3",