UNPKG

@sentry/wizard

Version:

Sentry wizard helping you to configure your project

149 lines (134 loc) 5.07 kB
import * as fs from 'fs'; import type { Answers } from 'inquirer'; import * as _ from 'lodash'; import * as path from 'path'; import type { Args } from '../Constants'; import { addToGitignore } from './Git'; import { green, l, nl, red } from './Logging'; const SENTRYCLIRC_FILENAME = '.sentryclirc'; const GITIGNORE_FILENAME = '.gitignore'; const PROPERTIES_FILENAME = 'sentry.properties'; export interface SentryCliProps { [s: string]: string; } type SentryCliConfig = Record<string, SentryCliProps>; export class SentryCli { // eslint-disable-next-line @typescript-eslint/typedef private _resolve = require.resolve; public constructor(protected _argv: Args) {} public setResolveFunction(resolve: (path: string) => string): void { this._resolve = resolve as any; } public convertAnswersToProperties(answers: Answers): SentryCliProps { const props: SentryCliProps = {}; props['defaults/url'] = this._argv.url; props['defaults/org'] = _.get(answers, 'config.organization.slug', null); props['defaults/project'] = _.get(answers, 'config.project.slug', null); props['auth/token'] = _.get(answers, 'config.auth.token', null); try { const cliPath = this._resolve('@sentry/cli/bin/sentry-cli', { paths: [process.cwd()], }); props['cli/executable'] = path .relative(process.cwd(), cliPath) .replace(/\\/g, '\\\\'); } catch (e) { // we do nothing and leave everyting as it is } return props; } /** Create the contents of a `sentry.properties` file */ public dumpProperties(props: SentryCliProps): string { const rv = []; for (let key in props) { // eslint-disable-next-line no-prototype-builtins if (props.hasOwnProperty(key)) { const value = props[key]; key = key.replace(/\//g, '.'); if (value === undefined || value === null) { // comment that property out since it has no value rv.push(`#${key}=`); } else { rv.push(`${key}=${value}`); } } } // eslint-disable-next-line prefer-template return rv.join('\n') + '\n'; } public dumpConfig(config: SentryCliConfig): string { const dumpedSections: string[] = []; for (const sectionName in config) { // eslint-disable-next-line no-prototype-builtins if (config.hasOwnProperty(sectionName)) { const props = this.dumpProperties(config[sectionName]); const section = `[${sectionName}]\n${props}`; dumpedSections.push(section); } } return dumpedSections.join('\n'); } /** * Creates `.sentryclirc` and `sentry.properties` files with the CLI properties * obtained from the user answers (or from logging into Sentry). * The `.sentryclirc` only contains the auth token and will be added to the * user's `.gitignore` file. The properties file contains the rest of the * properties (org, project, etc.). * * @param sentryCli instance of the Sentry CLI * @param cliProps the properties to write to the files */ public async createSentryCliConfig(cliProps: SentryCliProps): Promise<void> { const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps; /** * To not commit the auth token to the VCS, instead of adding it to the * properties file (like the rest of props), it's added to the Sentry CLI * config, which is added to the gitignore. This way makes the properties * file safe to commit without exposing any auth tokens. */ if (authToken) { try { await fs.promises.appendFile( SENTRYCLIRC_FILENAME, this.dumpConfig({ auth: { token: authToken } }), ); green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`); } catch { red( `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` + `please add it to identify your user account:\n${authToken}`, ); nl(); } } else { red( `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`, ); l( 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/', ); l( 'To learn how to configure Sentry CLI, visit ' + 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli', ); } await addToGitignore( SENTRYCLIRC_FILENAME, `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` + 'please add it to not commit your auth key.', ); try { await fs.promises.writeFile( `./${PROPERTIES_FILENAME}`, this.dumpProperties(cliPropsToWrite), ); green('✓ Successfully created sentry.properties'); } catch { red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`); l( 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli', ); } nl(); } }