Skip to content

Commit 9f2c0c0

Browse files
setup non-interactive forced mode for ci processes
1 parent a7ab9bc commit 9f2c0c0

File tree

3 files changed

+75
-9
lines changed

3 files changed

+75
-9
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ async function main(): Promise<void> {
7171
: detectPackageManager();
7272

7373
// Show update prompt
74-
const updateType = await displayUpdatePrompt(allDependencies);
74+
const updateType = await displayUpdatePrompt(allDependencies, config);
7575

7676
if (updateType) {
7777
const outdatedDeps = allDependencies.filter(

src/ui/display/__tests__/updatePrompt.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const mockStdin = {
1212
isRaw: false,
1313
isPaused: vi.fn(() => false),
1414
pause: vi.fn(),
15+
isTTY: true, // Mock TTY environment
1516
};
1617

1718
// Stub the global process.stdin
@@ -22,6 +23,8 @@ vi.stubGlobal('process', {
2223
describe('updatePrompt', () => {
2324
beforeEach(() => {
2425
vi.clearAllMocks();
26+
// Ensure TTY is true by default for tests
27+
mockStdin.isTTY = true;
2528
});
2629

2730
it('should return null when no outdated dependencies', async () => {
@@ -38,6 +41,41 @@ describe('updatePrompt', () => {
3841
expect(result).toBeNull();
3942
});
4043

44+
it('should return null when noUpdatePrompt config is true', async () => {
45+
const dependencies: DependencyInfo[] = [
46+
{
47+
packageName: 'test-package',
48+
currentVersion: '1.0.0',
49+
latestVersion: '1.0.1',
50+
isOutdated: true,
51+
updateType: 'patch',
52+
},
53+
];
54+
55+
const result = await displayUpdatePrompt(dependencies, {
56+
noUpdatePrompt: true,
57+
});
58+
expect(result).toBeNull();
59+
});
60+
61+
it('should return null when not in TTY environment', async () => {
62+
const dependencies: DependencyInfo[] = [
63+
{
64+
packageName: 'test-package',
65+
currentVersion: '1.0.0',
66+
latestVersion: '1.0.1',
67+
isOutdated: true,
68+
updateType: 'patch',
69+
},
70+
];
71+
72+
// Mock non-TTY environment
73+
mockStdin.isTTY = false;
74+
75+
const result = await displayUpdatePrompt(dependencies);
76+
expect(result).toBeNull();
77+
});
78+
4179
it('should show patch update option when patch dependencies exist', async () => {
4280
const dependencies: DependencyInfo[] = [
4381
{

src/ui/display/updatePrompt.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import chalk from 'chalk';
2+
import { type PatchPulseConfig } from '../../services/config';
23
import { type DependencyInfo } from '../../types';
34
import { pluralize } from '../../utils/pluralize';
45
import { displayHelp } from './help';
@@ -22,9 +23,12 @@ export interface UpdateOptions {
2223
* @param _wasPaused - The original paused state (unused but kept for consistency)
2324
*/
2425
function setupRawMode(stdin: typeof process.stdin) {
25-
stdin.setRawMode(true);
26-
stdin.resume();
27-
stdin.setEncoding('utf8');
26+
// Check if stdin is a TTY before calling setRawMode
27+
if (stdin.isTTY) {
28+
stdin.setRawMode(true);
29+
stdin.resume();
30+
stdin.setEncoding('utf8');
31+
}
2832
}
2933

3034
/**
@@ -42,20 +46,24 @@ function restoreTerminalSettings({
4246
wasRaw: boolean;
4347
wasPaused: boolean;
4448
}) {
45-
stdin.setRawMode(wasRaw);
46-
if (wasPaused) {
47-
stdin.pause();
49+
// Only call setRawMode if stdin is a TTY
50+
if (stdin.isTTY) {
51+
stdin.setRawMode(wasRaw);
52+
if (wasPaused) {
53+
stdin.pause();
54+
}
4855
}
4956
}
5057

5158
/**
5259
* Displays the interactive update prompt after the summary
5360
* @param dependencies - Array of outdated dependencies
54-
* @param packageManager - The detected package manager
61+
* @param config - The configuration object
5562
* @returns Promise that resolves with the selected update type or null if cancelled
5663
*/
5764
export function displayUpdatePrompt(
58-
dependencies: DependencyInfo[]
65+
dependencies: DependencyInfo[],
66+
config?: PatchPulseConfig
5967
): Promise<'patch' | 'minor' | 'all' | null> {
6068
return new Promise(resolve => {
6169
const outdatedDeps = dependencies.filter(d => d.isOutdated && !d.isSkipped);
@@ -65,6 +73,26 @@ export function displayUpdatePrompt(
6573
return;
6674
}
6775

76+
// Check if update prompt is disabled via config
77+
if (config?.noUpdatePrompt) {
78+
resolve(null);
79+
return;
80+
}
81+
82+
// Check if we're in a non-interactive environment (CI/CD)
83+
if (!process.stdin.isTTY) {
84+
console.log(
85+
chalk.yellow(
86+
'⚠️ Running in non-interactive environment. Skipping update prompt.'
87+
)
88+
);
89+
console.log(
90+
chalk.gray('Use --update-prompt flag to force interactive mode.')
91+
);
92+
resolve(null);
93+
return;
94+
}
95+
6896
const updateOptions = categorizeUpdates(outdatedDeps);
6997

7098
function showOptions() {

0 commit comments

Comments
 (0)