Files
gemini-cli/scripts/configure-registry.js
T
2025-10-24 09:45:50 -07:00

116 lines
3.4 KiB
JavaScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview This script automates the configuration of the user's
* global .npmrc file to work with this repository's development workflow.
*
* Rationale:
* This project uses a hybrid registry setup:
* - Production packages (`@google/gemini-cli`) are on the public npmjs.org registry.
* - Pre-release packages (`@google-gemini/gemini-cli`) are on the GitHub Packages registry.
*
* This script provides a consistent, automated, and less error-prone way to
* configure the necessary scopes and authentication for both registries. It
* backs up the user's existing .npmrc, making it a safe, one-time setup.
*/
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
import { execSync } from 'node:child_process';
const homedir = os.homedir();
const npmrcPath = path.join(homedir, '.npmrc');
const backupPath = path.join(homedir, '.npmrc.bak');
const GITHUB_REGISTRY_URL = 'https://npm.pkg.github.com/';
const GITHUB_SCOPE = '@google-gemini';
const PROD_SCOPE = '@google';
const PROD_REGISTRY_URL = 'https://registry.npmjs.org/';
function checkGhCli() {
try {
execSync('gh --version', { stdio: 'ignore' });
return true;
} catch (_e) {
console.error(
'Error: The GitHub CLI (`gh`) is not installed or not in your PATH.',
);
console.error('Please install it to continue: https://cli.github.com/');
return false;
}
}
function getGhAuthStatus() {
try {
execSync('gh auth status', { stdio: 'ignore' });
return true;
} catch (_e) {
console.error('Error: You are not logged in to the GitHub CLI (`gh`).');
console.error(
"Please run `gh auth login` and ensure you grant the 'read:packages' and 'write:packages' scopes.",
);
return false;
}
}
function getGhAuthToken() {
try {
const token = execSync('gh auth token', {
encoding: 'utf8',
}).trim();
if (!token) {
throw new Error('No token returned from `gh auth token`');
}
return token;
} catch (_e) {
console.error('Error: Failed to retrieve GitHub auth token.');
console.error(
'Please ensure you are logged in (`gh auth status`) and have the correct permissions.',
);
return null;
}
}
function setupNpmrc() {
console.log('Configuring your global ~/.npmrc for development...');
if (!checkGhCli() || !getGhAuthStatus()) {
process.exit(1);
}
const token = getGhAuthToken();
if (!token) {
process.exit(1);
}
// Back up the original .npmrc if it exists and a backup doesn't already.
if (fs.existsSync(npmrcPath) && !fs.existsSync(backupPath)) {
fs.copyFileSync(npmrcPath, backupPath);
console.log(`Backed up your existing configuration to ${backupPath}`);
}
const newContent = [
`# Added by gemini-cli setup`,
`# Configures scopes for both production and development registries`,
``,
`# Production packages from npmjs.org`,
`${PROD_SCOPE}:registry=${PROD_REGISTRY_URL}`,
``,
`# Pre-release packages from GitHub Packages`,
`${GITHUB_SCOPE}:registry=${GITHUB_REGISTRY_URL}`,
`//${new URL(GITHUB_REGISTRY_URL).hostname}/:_authToken=${token}`,
``,
].join('\n');
fs.writeFileSync(npmrcPath, newContent);
console.log(`✅ Successfully configured your ~/.npmrc file.`);
console.log('You can now install both production and pre-release packages.');
}
setupNpmrc();