repo-branch 0.0.6 → 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 +93 -106
  2. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -1,143 +1,115 @@
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
- const GITHUB_OWNER = process.env.BRANCH_SYNC_GITHUB_OWNER || "";
53
- const GITHUB_TOKEN = process.env.BRANCH_SYNC_GITHUB_TOKEN || "";
54
- // Function to check if .env file exists
55
- function checkEnvFile() {
56
- const envPath = path.resolve(process.cwd(), ".env");
57
- return fs.existsSync(envPath);
58
- }
59
- // Function to validate environment variables
60
- function validateEnv() {
61
- if (!GITHUB_OWNER) {
62
- console.error(chalk_1.default.red("❌ BRANCH_SYNC_GITHUB_OWNER not found in environment variables"));
63
- console.error(chalk_1.default.yellow("Please set BRANCH_SYNC_GITHUB_OWNER in your .env file or as environment variable"));
64
- return false;
18
+ const GITHUB_ORG = process.env.BRANCH_SYNC_GITHUB_ORG || "";
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();
65
24
  }
66
- if (!GITHUB_TOKEN) {
67
- console.error(chalk_1.default.red(" BRANCH_SYNC_GITHUB_TOKEN not found in environment variables"));
68
- console.error(chalk_1.default.yellow("Please set BRANCH_SYNC_GITHUB_TOKEN in your .env file or as environment variable"));
69
- 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;
70
44
  }
71
- return true;
72
- }
73
- if (!validateEnv()) {
74
- if (!checkEnvFile()) {
75
- console.error(chalk_1.default.red("\nNo .env file found!"));
76
- console.error(chalk_1.default.yellow("Create a .env file with:"));
77
- console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_TOKEN=your_token_here"));
78
- 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;
79
51
  }
80
- process.exit(1);
81
- }
82
- const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
83
- async function getRepositories() {
52
+ catch (error) {
53
+ return false;
54
+ }
55
+ };
56
+ const getRepositories = async (owner) => {
84
57
  try {
85
- const repos = await octokit.paginate(octokit.rest.repos.listForOrg, {
86
- org: GITHUB_OWNER,
87
- username: GITHUB_OWNER,
88
- per_page: 100,
89
- sort: "full_name",
90
- });
91
- 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) => ({
92
63
  name: repo.name,
93
- defaultBranch: repo.default_branch ?? "main",
94
- }));
64
+ defaultBranch: repo.defaultBranchRef?.name || "main",
65
+ full_name: repo.nameWithOwner,
66
+ }))
67
+ .sort((a, b) => a.full_name.localeCompare(b.full_name));
95
68
  }
96
69
  catch (error) {
97
70
  console.error(chalk_1.default.red("Failed to fetch repositories:"), error);
98
71
  throw error;
99
72
  }
100
- }
101
- async function createBranch(repoName, branchName) {
73
+ };
74
+ const createBranch = async (owner, repoName, branchName) => {
102
75
  try {
103
- const { data: refData } = await octokit.rest.git.getRef({
104
- owner: GITHUB_OWNER,
105
- repo: repoName,
106
- ref: `heads/${(await octokit.rest.repos.get({ owner: GITHUB_OWNER, repo: repoName })).data.default_branch}`,
107
- });
108
- await octokit.rest.git.createRef({
109
- owner: GITHUB_OWNER,
110
- repo: repoName,
111
- ref: `refs/heads/${branchName}`,
112
- sha: refData.object.sha,
113
- });
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}`);
114
84
  }
115
85
  catch (error) {
116
- if (error.status === 422) {
86
+ if (error.stderr && error.stderr.includes("Reference already exists")) {
117
87
  throw new Error(`Branch already exists`);
118
88
  }
119
89
  throw error;
120
90
  }
121
- }
122
- async function selectRepositories(repos) {
91
+ };
92
+ const selectRepositories = async (repos) => {
123
93
  const answers = await inquirer_1.default.prompt([
124
94
  {
125
95
  type: "checkbox",
126
96
  name: "selectedRepos",
127
97
  message: "Select repositories:",
128
98
  choices: repos.map((repo) => ({
129
- name: `${repo.name} (${repo.defaultBranch})`,
99
+ name: `${repo.full_name} (${repo.defaultBranch})`,
130
100
  value: repo,
131
101
  })),
132
102
  pageSize: 15,
133
103
  },
134
104
  ]);
135
105
  return answers.selectedRepos;
136
- }
137
- async function run(branchName, repoNames) {
106
+ };
107
+ const run = async (branchName, repoNames) => {
138
108
  try {
139
- console.log(chalk_1.default.blue("🔍 Fetching repositories..."));
140
- 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);
141
113
  let selectedRepos;
142
114
  if (repoNames && repoNames.length > 0) {
143
115
  selectedRepos = allRepos.filter((repo) => repoNames.includes(repo.name));
@@ -159,7 +131,7 @@ async function run(branchName, repoNames) {
159
131
  title: `Creating branch in ${chalk_1.default.cyan(repo.name)}`,
160
132
  task: async () => {
161
133
  try {
162
- await createBranch(repo.name, branchName);
134
+ await createBranch(owner, repo.name, branchName);
163
135
  }
164
136
  catch (error) {
165
137
  if (error.message.includes("already exists")) {
@@ -180,13 +152,28 @@ async function run(branchName, repoNames) {
180
152
  console.error(chalk_1.default.red("Error:"), error);
181
153
  process.exit(1);
182
154
  }
183
- }
184
- program
185
- .name("repo-branch")
186
- .description("Create a branch across multiple GitHub repositories")
187
- .argument("<branch-name>", "name of the branch to create")
188
- .argument("[repositories...]", "repositories to create branch in")
189
- .action((branchName, repositories) => {
190
- run(branchName, repositories);
191
- });
192
- 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.6",
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",