Skip to content

Commit

Permalink
Merge branch 'master' into feat/auth-from-enviroment
Browse files Browse the repository at this point in the history
  • Loading branch information
brustolin authored Sep 5, 2023
2 parents 1e61c49 + 45af819 commit eb367c8
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 114 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Unreleased

- feat(apple): Use ".sentryclirc" for auth instead of hard coding it (#422)
- feat(apple): Add option to choose between cocoapods when available and SPM (#423)
- feat: Add Bun package manager support (#417)
- feat(android): Add wizard support for Android (#389)

Set up the Sentry Android SDK in your app with one command:
Expand Down
59 changes: 0 additions & 59 deletions lib/Helper/PackageManager.ts

This file was deleted.

12 changes: 9 additions & 3 deletions lib/Steps/Integrations/ReactNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
} from '../../Helper/File';
import { dim, green, l, nl, red } from '../../Helper/Logging';
import { checkPackageVersion } from '../../Helper/Package';
import { getPackageManagerChoice } from '../../Helper/PackageManager';
import {
detectPackageManger,
installPackageWithPackageManager,
} from '../../../src/utils/package-manager';
import { SentryCli } from '../../Helper/SentryCli';
import { MobileProject } from './MobileProject';
import { BottomBar } from '../../Helper/BottomBar';
Expand Down Expand Up @@ -60,7 +63,7 @@ export class ReactNative extends MobileProject {
nl();

let userAnswers: Answers = { continue: true };
const packageManager = getPackageManagerChoice();
const packageManager = detectPackageManger();

const hasCompatibleReactNativeVersion = checkPackageVersion(
this._readAppPackage(),
Expand All @@ -86,7 +89,10 @@ export class ReactNative extends MobileProject {

if (packageManager) {
BottomBar.show(`Adding ${SENTRY_REACT_NATIVE_PACKAGE}...`);
await packageManager.installPackage(SENTRY_REACT_NATIVE_PACKAGE);
await installPackageWithPackageManager(
packageManager,
SENTRY_REACT_NATIVE_PACKAGE,
);
BottomBar.hide();
green(`✓ Added \`${SENTRY_REACT_NATIVE_PACKAGE}\``);
}
Expand Down
26 changes: 19 additions & 7 deletions src/apple/apple-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,28 @@ async function runAppleWizardWithTelementry(
'We created a ".sentryclirc" file in your project directory in order to provide an auth token for Sentry CLI.\nIt was also added to your ".gitignore" file.\nAt your CI enviroment, you can set the SENTRY_AUTH_TOKEN environment variable instead. See https://docs.sentry.io/cli/configuration/#auth-token for more information.',
);

const hasCocoa = cocoapod.usesCocoaPod(projectDir);
let hasCocoa = cocoapod.usesCocoaPod(projectDir);

if (hasCocoa) {
const podAdded = await traceStep('Add CocoaPods reference', () =>
cocoapod.addCocoaPods(projectDir),
);
if (!podAdded) {
clack.log.warn(
"Could not add Sentry pod to your Podfile. You'll have to add it manually.\nPlease follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/#install",
const pm = (
await traceStep('Choose a package manager', () =>
askForItemSelection(
['Swift Package Manager', 'CocoaPods'],
'Which package manager would you like to use to add Sentry?',
),
)
).value;

hasCocoa = pm === 'CocoaPods';
if (hasCocoa) {
const podAdded = await traceStep('Add CocoaPods reference', () =>
cocoapod.addCocoaPods(projectDir),
);
if (!podAdded) {
clack.log.warn(
"Could not add Sentry pod to your Podfile. You'll have to add it manually.\nPlease follow the instructions at https://docs.sentry.io/platforms/apple/guides/ios/#install",
);
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/sourcemaps/sourcemaps-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
abort,
abortIfCancelled,
confirmContinueEvenThoughNoGitRepo,
detectPackageManager,
SENTRY_DOT_ENV_FILE,
printWelcome,
SENTRY_CLI_RC_FILE,
Expand All @@ -31,6 +30,7 @@ import { configureAngularSourcemapGenerationFlow } from './tools/angular';
import { detectUsedTool, SupportedTools } from './utils/detect-tool';
import { configureNextJsSourceMapsUpload } from './tools/nextjs';
import { configureRemixSourceMapsUpload } from './tools/remix';
import { detectPackageManger } from '../utils/package-manager';

export async function runSourcemapsWizard(
options: WizardOptions,
Expand Down Expand Up @@ -331,8 +331,8 @@ SENTRY_AUTH_TOKEN=${authToken}
}

function printOutro(url: string, orgSlug: string, projectId: string) {
const pacMan = detectPackageManager() || 'npm';
const buildCommand = `'${pacMan}${pacMan === 'npm' ? ' run' : ''} build'`;
const packageManager = detectPackageManger();
const buildCommand = packageManager?.buildCommand ?? 'npm run build';

const urlObject = new URL(url);
urlObject.host = `${orgSlug}.${urlObject.host}`;
Expand Down
11 changes: 6 additions & 5 deletions src/sourcemaps/tools/sentry-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import * as fs from 'fs';
import {
abortIfCancelled,
addSentryCliRc,
detectPackageManager,
getPackageDotJson,
installPackage,
} from '../../utils/clack-utils';

import { SourceMapUploadToolConfigurationOptions } from './types';
import { hasPackageInstalled, PackageDotJson } from '../../utils/package-json';
import { traceStep } from '../../telemetry';
import { detectPackageManger } from '../../utils/package-manager';

const SENTRY_NPM_SCRIPT_NAME = 'sentry:sourcemaps';

Expand Down Expand Up @@ -205,7 +205,8 @@ async function addSentryCommandToBuildCommand(
(s) => s !== SENTRY_NPM_SCRIPT_NAME,
);

const pacMan = detectPackageManager() || 'npm';
const packageManager = detectPackageManger();
const packageManagerName = packageManager?.name ?? 'npm';

// Heuristic to pre-select the build command:
// Often, 'build' is the prod build command, so we favour it.
Expand All @@ -220,15 +221,15 @@ async function addSentryCommandToBuildCommand(
(await abortIfCancelled(
clack.confirm({
message: `Is ${chalk.cyan(
`${pacMan} run ${buildCommand}`,
`${packageManagerName} run ${buildCommand}`,
)} your production build command?`,
}),
));

if (allNpmScripts.length && (!buildCommand || !isProdBuildCommand)) {
buildCommand = await abortIfCancelled(
clack.select({
message: `Which ${pacMan} command in your ${chalk.cyan(
message: `Which ${packageManagerName} command in your ${chalk.cyan(
'package.json',
)} builds your application for production?`,
options: allNpmScripts
Expand All @@ -254,7 +255,7 @@ Please add it manually to your prod build command.`,
packageDotJson.scripts[
buildCommand
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
] = `${packageDotJson.scripts[buildCommand]} && ${pacMan} run ${SENTRY_NPM_SCRIPT_NAME}`;
] = `${packageDotJson.scripts[buildCommand]} && ${packageManager} run ${SENTRY_NPM_SCRIPT_NAME}`;

await fs.promises.writeFile(
path.join(process.cwd(), 'package.json'),
Expand Down
64 changes: 27 additions & 37 deletions src/utils/clack-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import * as fs from 'fs';
import * as path from 'path';
import { setInterval } from 'timers';
import { URL } from 'url';
import { promisify } from 'util';
import * as Sentry from '@sentry/node';
import { windowedSelect } from './vendor/clack-custom-select';
import { hasPackageInstalled, PackageDotJson } from './package-json';
import { SentryProjectData, WizardOptions } from './types';
import { traceStep } from '../telemetry';
import {
detectPackageManger,
PackageManager,
installPackageWithPackageManager,
packageManagers,
} from './package-manager';

const opn = require('opn') as (
url: string,
Expand Down Expand Up @@ -185,17 +190,11 @@ export async function installPackage({
sdkInstallSpinner.start(
`${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(
packageName,
)} with ${chalk.bold(packageManager)}.`,
)} with ${chalk.bold(packageManager.label)}.`,
);

try {
if (packageManager === 'yarn') {
await promisify(childProcess.exec)(`yarn add ${packageName}@latest`);
} else if (packageManager === 'pnpm') {
await promisify(childProcess.exec)(`pnpm add ${packageName}@latest`);
} else if (packageManager === 'npm') {
await promisify(childProcess.exec)(`npm install ${packageName}@latest`);
}
await installPackageWithPackageManager(packageManager, packageName);
} catch (e) {
sdkInstallSpinner.stop('Installation failed.');
clack.log.error(
Expand All @@ -212,7 +211,7 @@ export async function installPackage({
sdkInstallSpinner.stop(
`${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(
packageName,
)} with ${chalk.bold(packageManager)}.`,
)} with ${chalk.bold(packageManager.label)}.`,
);
}

Expand Down Expand Up @@ -460,42 +459,29 @@ export async function getPackageDotJson(): Promise<PackageDotJson> {
return packageJson || {};
}

async function getPackageManager(): Promise<string> {
const detectedPackageManager = detectPackageManager();
async function getPackageManager(): Promise<PackageManager> {
const detectedPackageManager = detectPackageManger();

if (detectedPackageManager) {
return detectedPackageManager;
}

const selectedPackageManager: string | symbol = await abortIfCancelled(
clack.select({
message: 'Please select your package manager.',
options: [
{ value: 'npm', label: 'Npm' },
{ value: 'yarn', label: 'Yarn' },
{ value: 'pnpm', label: 'Pnpm' },
],
}),
);
const selectedPackageManager: PackageManager | symbol =
await abortIfCancelled(
clack.select({
message: 'Please select your package manager.',
options: packageManagers.map((packageManager) => ({
value: packageManager,
label: packageManager.label,
})),
}),
);

Sentry.setTag('package-manager', selectedPackageManager);
Sentry.setTag('package-manager', selectedPackageManager.name);

return selectedPackageManager;
}

export function detectPackageManager(): 'yarn' | 'npm' | 'pnpm' | undefined {
if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {
return 'yarn';
}
if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {
return 'npm';
}
if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {
return 'pnpm';
}
return undefined;
}

export function isUsingTypeScript() {
try {
return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
Expand Down Expand Up @@ -720,7 +706,11 @@ async function askForWizardLogin(options: {
const data = await new Promise<WizardProjectData>((resolve) => {
const pollingInterval = setInterval(() => {
axios
.get<WizardProjectData>(`${options.url}api/0/wizard/${wizardHash}/`)
.get<WizardProjectData>(`${options.url}api/0/wizard/${wizardHash}/`, {
headers: {
'Accept-Encoding': 'deflate',
},
})
.then((result) => {
resolve(result.data);
clearTimeout(timeout);
Expand Down
61 changes: 61 additions & 0 deletions src/utils/package-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* eslint-disable @typescript-eslint/typedef */
import { exec } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';

export interface PackageManager {
name: string;
label: string;
lockFile: string;
installCommand: string;
buildCommand: string;
}

const bun: PackageManager = {
name: 'bun',
label: 'Bun',
lockFile: 'bun.lockb',
installCommand: 'bun add',
buildCommand: 'bun build',
};
const yarn: PackageManager = {
name: 'yarn',
label: 'Yarn',
lockFile: 'yarn.lock',
installCommand: 'yarn add',
buildCommand: 'yarn build',
};
const pnpm: PackageManager = {
name: 'pnpm',
label: 'PNPM',
lockFile: 'pnpm-lock.yaml',
installCommand: 'pnpm add',
buildCommand: 'pnpm build',
};
const npm: PackageManager = {
name: 'npm',
label: 'NPM',
lockFile: 'package-lock.json',
installCommand: 'npm add',
buildCommand: 'npm run build',
};

export const packageManagers = [bun, yarn, pnpm, npm];

export function detectPackageManger(): PackageManager | null {
for (const packageManager of packageManagers) {
if (fs.existsSync(path.join(process.cwd(), packageManager.lockFile))) {
return packageManager;
}
}
// We make the default NPM - it's weird if we don't find any lock file
return null;
}

export async function installPackageWithPackageManager(
packageManager: PackageManager,
packageName: string,
): Promise<void> {
await promisify(exec)(`${packageManager.installCommand} ${packageName}`);
}

0 comments on commit eb367c8

Please sign in to comment.