dependency-change-report 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/index.mjs +58 -65
  2. package/package.json +1 -1
package/lib/index.mjs CHANGED
@@ -31,48 +31,77 @@ const executeCommand = (command, args, cwd, timeout = 300000) => {
31
31
  let stdout = '';
32
32
  let stderr = '';
33
33
  let isResolved = false;
34
+ let timeoutId = null;
34
35
 
35
- // Set up timeout with proper cleanup
36
- const timeoutId = setTimeout(() => {
37
- if (!isResolved) {
38
- isResolved = true;
36
+ // Cleanup function to remove all listeners and clear timeout
37
+ const cleanup = () => {
38
+ if (timeoutId) {
39
+ clearTimeout(timeoutId);
40
+ timeoutId = null;
41
+ }
42
+
43
+ // Remove all listeners to prevent memory leaks and hanging
44
+ childProcess.removeAllListeners();
45
+
46
+ // Ensure streams are properly closed
47
+ if (childProcess.stdout) {
48
+ childProcess.stdout.removeAllListeners();
49
+ }
50
+ if (childProcess.stderr) {
51
+ childProcess.stderr.removeAllListeners();
52
+ }
53
+ };
54
+
55
+ // Kill process function
56
+ const killProcess = () => {
57
+ try {
58
+ // Just kill the process directly, don't try process group
59
+ childProcess.kill('SIGTERM');
39
60
 
40
- // Kill the process and all its children
41
- try {
42
- if (childProcess.pid) {
43
- // Try to kill the process group first
44
- process.kill(-childProcess.pid, 'SIGTERM');
45
- }
46
- } catch (e) {
47
- // If that fails, kill just the process
61
+ // If SIGTERM doesn't work after a short delay, use SIGKILL
62
+ setTimeout(() => {
48
63
  try {
49
- childProcess.kill('SIGTERM');
50
- } catch (e2) {
51
- // Force kill if SIGTERM doesn't work
52
- try {
64
+ if (!childProcess.killed) {
53
65
  childProcess.kill('SIGKILL');
54
- } catch (e3) {
55
- // Process might already be dead
56
66
  }
67
+ } catch (e) {
68
+ // Process might already be dead
57
69
  }
58
- }
59
-
70
+ }, 1000);
71
+ } catch (e) {
72
+ // Process might already be dead
73
+ }
74
+ };
75
+
76
+ // Set up timeout with proper cleanup
77
+ timeoutId = setTimeout(() => {
78
+ if (!isResolved) {
79
+ isResolved = true;
80
+ killProcess();
81
+ cleanup();
60
82
  reject(new Error(`Command timed out after ${timeout}ms: ${command} ${args.join(' ')}`));
61
83
  }
62
84
  }, timeout);
63
85
 
64
- childProcess.stdout.on('data', (data) => {
65
- stdout += data.toString();
66
- });
86
+ // Handle stdout data
87
+ if (childProcess.stdout) {
88
+ childProcess.stdout.on('data', (data) => {
89
+ stdout += data.toString();
90
+ });
91
+ }
67
92
 
68
- childProcess.stderr.on('data', (data) => {
69
- stderr += data.toString();
70
- });
93
+ // Handle stderr data
94
+ if (childProcess.stderr) {
95
+ childProcess.stderr.on('data', (data) => {
96
+ stderr += data.toString();
97
+ });
98
+ }
71
99
 
100
+ // Handle process close (preferred over exit)
72
101
  childProcess.on('close', (code, signal) => {
73
102
  if (!isResolved) {
74
103
  isResolved = true;
75
- clearTimeout(timeoutId);
104
+ cleanup();
76
105
 
77
106
  if (signal) {
78
107
  reject(new Error(`Command was killed with signal ${signal}: ${command} ${args.join(' ')}`));
@@ -86,29 +115,14 @@ const executeCommand = (command, args, cwd, timeout = 300000) => {
86
115
  }
87
116
  });
88
117
 
118
+ // Handle process errors
89
119
  childProcess.on('error', (error) => {
90
120
  if (!isResolved) {
91
121
  isResolved = true;
92
- clearTimeout(timeoutId);
122
+ cleanup();
93
123
  reject(error);
94
124
  }
95
125
  });
96
-
97
- // Handle process exit to ensure cleanup
98
- childProcess.on('exit', (code, signal) => {
99
- if (!isResolved) {
100
- isResolved = true;
101
- clearTimeout(timeoutId);
102
-
103
- if (signal) {
104
- reject(new Error(`Command exited with signal ${signal}: ${command} ${args.join(' ')}`));
105
- } else if (code !== 0) {
106
- reject(new Error(`Command exited with code ${code}: ${command} ${args.join(' ')}`));
107
- } else {
108
- resolve(stdout);
109
- }
110
- }
111
- });
112
126
  });
113
127
  };
114
128
 
@@ -1395,30 +1409,9 @@ const analyzeDependencyChanges = async (repoUrl, olderVersion, newerVersion, wor
1395
1409
  report.reportPath = reportPath;
1396
1410
 
1397
1411
  console.log(`Report generated at ${reportPath}`);
1398
-
1399
- // Force cleanup of any remaining processes
1400
- if (process.platform !== 'win32') {
1401
- try {
1402
- // Kill any remaining git processes that might be hanging
1403
- await executeCommand('pkill', ['-f', 'git'], undefined, 5000);
1404
- } catch (e) {
1405
- // Ignore errors - processes might not exist
1406
- }
1407
- }
1408
-
1409
1412
  return report;
1410
1413
  } catch (error) {
1411
1414
  console.error(`Error analyzing dependency changes: ${error.message}`);
1412
-
1413
- // Force cleanup on error as well
1414
- if (process.platform !== 'win32') {
1415
- try {
1416
- await executeCommand('pkill', ['-f', 'git'], undefined, 5000);
1417
- } catch (e) {
1418
- // Ignore errors
1419
- }
1420
- }
1421
-
1422
1415
  throw error;
1423
1416
  }
1424
1417
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-change-report",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "main": "index.mjs",
5
5
  "type": "module",
6
6
  "bin": {