Skip to content

Commit 6f81c62

Browse files
authored
fix(apple): Use project-relative path to gitignore file (#982)
1 parent 7a0443d commit 6f81c62

File tree

4 files changed

+149
-77
lines changed

4 files changed

+149
-77
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- feat(react-native): Add Feedback Widget step ([#969](https://github.com/getsentry/sentry-wizard/pull/969))
77
- feat(react-native): More granular error reporting for RN Wizard ([#861](https://github.com/getsentry/sentry-wizard/pull/861))
88
- feat(Mobile): add `sendDefaultPii=true` to Mobile wizards ([#981](https://github.com/getsentry/sentry-wizard/pull/981))
9+
- fix(apple): Use project-relative path to gitignore file ([#982](https://github.com/getsentry/sentry-wizard/pull/982))
910

1011
## 4.8.0
1112

lib/Helper/SentryCli.ts

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
import * as fs from 'node:fs';
21
import type { Answers } from 'inquirer';
32
import * as path from 'node:path';
43

54
import type { Args } from '../Constants';
6-
import { addToGitignore } from './Git';
7-
import { green, l, nl, red } from './Logging';
85
import { Config } from '../Types';
96

10-
const SENTRYCLIRC_FILENAME = '.sentryclirc';
11-
const GITIGNORE_FILENAME = '.gitignore';
12-
const PROPERTIES_FILENAME = 'sentry.properties';
13-
147
export interface SentryCliProps {
158
'defaults/url': string;
169
'defaults/org': string | null;
@@ -94,70 +87,4 @@ export class SentryCli {
9487
}
9588
return dumpedSections.join('\n');
9689
}
97-
98-
/**
99-
* Creates `.sentryclirc` and `sentry.properties` files with the CLI properties
100-
* obtained from the user answers (or from logging into Sentry).
101-
* The `.sentryclirc` only contains the auth token and will be added to the
102-
* user's `.gitignore` file. The properties file contains the rest of the
103-
* properties (org, project, etc.).
104-
*
105-
* @param sentryCli instance of the Sentry CLI
106-
* @param cliProps the properties to write to the files
107-
*/
108-
public async createSentryCliConfig(cliProps: SentryCliProps): Promise<void> {
109-
const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;
110-
111-
/**
112-
* To not commit the auth token to the VCS, instead of adding it to the
113-
* properties file (like the rest of props), it's added to the Sentry CLI
114-
* config, which is added to the gitignore. This way makes the properties
115-
* file safe to commit without exposing any auth tokens.
116-
*/
117-
if (authToken) {
118-
try {
119-
await fs.promises.appendFile(
120-
SENTRYCLIRC_FILENAME,
121-
this.dumpConfig({ auth: { 'auth/token': authToken } }),
122-
);
123-
green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);
124-
} catch {
125-
red(
126-
`⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +
127-
`please add it to identify your user account:\n${authToken}`,
128-
);
129-
nl();
130-
}
131-
} else {
132-
red(
133-
`⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,
134-
);
135-
l(
136-
'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',
137-
);
138-
l(
139-
'To learn how to configure Sentry CLI, visit ' +
140-
'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',
141-
);
142-
}
143-
144-
await addToGitignore(
145-
SENTRYCLIRC_FILENAME,
146-
`⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, please add it to not commit your auth key.`,
147-
);
148-
149-
try {
150-
await fs.promises.writeFile(
151-
`./${PROPERTIES_FILENAME}`,
152-
this.dumpProperties(cliPropsToWrite),
153-
);
154-
green('✓ Successfully created sentry.properties');
155-
} catch {
156-
red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);
157-
l(
158-
'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',
159-
);
160-
}
161-
nl();
162-
}
16390
}

src/utils/sentrycli-utils.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// @ts-expect-error - clack is ESM and TS complains about that. It works though
2+
import clack from '@clack/prompts';
3+
import chalk from 'chalk';
14
import * as fs from 'fs';
25
import * as path from 'path';
36

@@ -12,12 +15,21 @@ export function createSentryCLIRC(
1215
const rcPath = path.join(directory, '.sentryclirc');
1316
fs.writeFileSync(rcPath, '[auth]\ntoken=' + params.auth_token);
1417

15-
if (!fs.existsSync('.gitignore')) {
16-
fs.writeFileSync('.gitignore', '.sentryclirc');
18+
const gitignorePath = path.join(directory, '.gitignore');
19+
if (!fs.existsSync(gitignorePath)) {
20+
clack.log.info(
21+
`Creating .gitignore file at path: ${chalk.cyan(gitignorePath)}`,
22+
);
23+
fs.writeFileSync(gitignorePath, '.sentryclirc');
1724
} else {
18-
const gitIgnore = fs.readFileSync('.gitignore').toString();
25+
const gitIgnore = fs.readFileSync(gitignorePath).toString();
1926
if (!gitIgnore.includes('.sentryclirc')) {
20-
fs.appendFileSync('.gitignore', '\n.sentryclirc');
27+
clack.log.info(
28+
`Appending .sentryclirc to .gitignore file at path: ${chalk.cyan(
29+
gitignorePath,
30+
)}`,
31+
);
32+
fs.appendFileSync(gitignorePath, '\n.sentryclirc\n');
2133
}
2234
}
2335
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// @ts-expect-error - clack is ESM and TS complains about that. It works though
2+
import * as clack from '@clack/prompts';
3+
import * as fs from 'node:fs';
4+
import * as os from 'node:os';
5+
import path from 'node:path';
6+
import { beforeEach, describe, expect, it, vi } from 'vitest';
7+
import { configureSentryCLI } from '../../src/apple/configure-sentry-cli';
8+
9+
vi.mock('@clack/prompts', async () => ({
10+
__esModule: true,
11+
default: await vi.importActual<typeof clack>('@clack/prompts'),
12+
}));
13+
14+
describe('configureSentryCLI', () => {
15+
const authToken = 'test';
16+
let projectDir: string;
17+
let rcPath: string;
18+
let gitignorePath: string;
19+
20+
beforeEach(() => {
21+
beforeEach(() => {
22+
vi.spyOn(clack.log, 'warn').mockImplementation(() => {
23+
/* empty */
24+
});
25+
vi.spyOn(clack, 'select').mockResolvedValue(undefined);
26+
});
27+
28+
projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'project'));
29+
fs.mkdirSync(projectDir, { recursive: true });
30+
31+
rcPath = path.join(projectDir, '.sentryclirc');
32+
gitignorePath = path.join(projectDir, '.gitignore');
33+
});
34+
35+
describe('.sentryclirc file not exists', () => {
36+
it('should create the .sentryclirc file', () => {
37+
// -- Arrange --
38+
// Pre-condition is that the .sentryclirc file does not exist
39+
expect(fs.existsSync(rcPath)).toBe(false);
40+
41+
// -- Act --
42+
configureSentryCLI({ projectDir, authToken });
43+
44+
// -- Assert --
45+
expect(fs.existsSync(rcPath)).toBe(true);
46+
expect(fs.readFileSync(rcPath, 'utf8')).toContain(`token=test`);
47+
});
48+
});
49+
50+
describe('.sentryclirc file exists', () => {
51+
it('should update the .sentryclirc file', () => {
52+
// -- Arrange --
53+
// Pre-condition is that the .sentryclirc file exists
54+
fs.writeFileSync(rcPath, `token=old`);
55+
56+
// -- Act --
57+
configureSentryCLI({ projectDir, authToken });
58+
59+
// -- Assert --
60+
expect(fs.readFileSync(rcPath, 'utf8')).toContain(`token=${authToken}`);
61+
});
62+
});
63+
64+
describe('.gitignore file not exists', () => {
65+
it('should create the .gitignore file', () => {
66+
// -- Arrange --
67+
// Pre-condition is that the .gitignore file does not exist
68+
expect(fs.existsSync(gitignorePath)).toBe(false);
69+
70+
// -- Act --
71+
configureSentryCLI({ projectDir, authToken });
72+
73+
// -- Assert --
74+
expect(fs.existsSync(gitignorePath)).toBe(true);
75+
expect(fs.readFileSync(gitignorePath, 'utf8')).toContain('.sentryclirc');
76+
});
77+
});
78+
79+
describe('.gitignore file exists', () => {
80+
describe("contains '.sentryclirc'", () => {
81+
it('should not append the .sentryclirc file to the .gitignore file', () => {
82+
// -- Arrange --
83+
// Pre-condition is that the .gitignore file exists and contains '.sentryclirc'
84+
fs.writeFileSync(
85+
gitignorePath,
86+
`
87+
# Xcode
88+
xcuserdata/
89+
90+
# Sentry
91+
.sentryclirc
92+
`,
93+
);
94+
95+
// -- Act --
96+
configureSentryCLI({ projectDir, authToken });
97+
98+
// -- Assert --
99+
expect(fs.readFileSync(gitignorePath, 'utf8')).toContain(
100+
'.sentryclirc',
101+
);
102+
});
103+
});
104+
105+
describe("does not contain '.sentryclirc'", () => {
106+
it('should append the .sentryclirc file to the .gitignore file', () => {
107+
// -- Arrange --
108+
// Pre-condition is that the .gitignore file exists and does not contain '.sentryclirc'
109+
fs.writeFileSync(
110+
gitignorePath,
111+
`
112+
# Xcode
113+
xcuserdata/
114+
`,
115+
);
116+
117+
// -- Act --
118+
configureSentryCLI({ projectDir, authToken });
119+
120+
// -- Assert --
121+
expect(fs.readFileSync(gitignorePath, 'utf8')).toBe(
122+
`
123+
# Xcode
124+
xcuserdata/
125+
126+
.sentryclirc
127+
`,
128+
);
129+
});
130+
});
131+
});
132+
});

0 commit comments

Comments
 (0)