dependency-change-report 1.0.5 → 1.0.6
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.
- package/lib/generate-html.mjs +23 -17
- package/lib/index.mjs +96 -37
- package/package.json +1 -1
package/lib/generate-html.mjs
CHANGED
|
@@ -447,7 +447,7 @@ const generateAddedSection = (added) => {
|
|
|
447
447
|
const rows = added.map(dep => {
|
|
448
448
|
const npmUrl = `https://www.npmjs.com/package/${dep.name}`;
|
|
449
449
|
const versionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.version}`;
|
|
450
|
-
const repoUrl = dep.repository ?
|
|
450
|
+
const repoUrl = (dep.repository && typeof dep.repository === 'string') ?
|
|
451
451
|
dep.repository.replace(/\.git$/, '')
|
|
452
452
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
453
453
|
.replace(/^git\+https:/, 'https:') :
|
|
@@ -498,15 +498,15 @@ const generateUpgradedSection = (upgraded, changelogs, ciStatus = {}) => {
|
|
|
498
498
|
const npmUrl = `https://www.npmjs.com/package/${dep.name}`;
|
|
499
499
|
const oldVersionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.oldVersion}`;
|
|
500
500
|
const newVersionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.newVersion}`;
|
|
501
|
-
const repoUrl = dep.repository ?
|
|
501
|
+
const repoUrl = (dep.repository && typeof dep.repository === 'string') ?
|
|
502
502
|
dep.repository.replace(/\.git$/, '')
|
|
503
503
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
504
504
|
.replace(/^git\+https:/, 'https:') :
|
|
505
|
-
(changelogs[dep.name] && changelogs[dep.name].repoUrl ?
|
|
505
|
+
(changelogs[dep.name] && changelogs[dep.name].repoUrl && typeof changelogs[dep.name].repoUrl === 'string') ?
|
|
506
506
|
changelogs[dep.name].repoUrl.replace(/\.git$/, '')
|
|
507
507
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
508
508
|
.replace(/^git\+https:/, 'https:') :
|
|
509
|
-
null
|
|
509
|
+
null;
|
|
510
510
|
|
|
511
511
|
const changeTypeBadge = `<span class="badge ${dep.changeType}">${dep.changeType}</span>`;
|
|
512
512
|
|
|
@@ -544,9 +544,11 @@ const generateUpgradedSection = (upgraded, changelogs, ciStatus = {}) => {
|
|
|
544
544
|
.filter(dep => changelogs[dep.name])
|
|
545
545
|
.map(dep => {
|
|
546
546
|
const changelog = changelogs[dep.name];
|
|
547
|
-
const repoUrl = changelog.repoUrl.
|
|
548
|
-
|
|
549
|
-
|
|
547
|
+
const repoUrl = (changelog.repoUrl && typeof changelog.repoUrl === 'string') ?
|
|
548
|
+
changelog.repoUrl.replace(/\.git$/, '')
|
|
549
|
+
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
550
|
+
.replace(/^git\+https:/, 'https:') :
|
|
551
|
+
'#';
|
|
550
552
|
|
|
551
553
|
const commits = changelog.commits.map(commit => {
|
|
552
554
|
const commitUrl = `${repoUrl}/commit/${commit.hash}`;
|
|
@@ -692,9 +694,11 @@ const generateModifiedSection = (modified, changelogs = {}) => {
|
|
|
692
694
|
.filter(dep => changelogs[dep.newName])
|
|
693
695
|
.map(dep => {
|
|
694
696
|
const changelog = changelogs[dep.newName];
|
|
695
|
-
const repoUrl = changelog.repoUrl.
|
|
696
|
-
|
|
697
|
-
|
|
697
|
+
const repoUrl = (changelog.repoUrl && typeof changelog.repoUrl === 'string') ?
|
|
698
|
+
changelog.repoUrl.replace(/\.git$/, '')
|
|
699
|
+
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
700
|
+
.replace(/^git\+https:/, 'https:') :
|
|
701
|
+
'#';
|
|
698
702
|
|
|
699
703
|
const commits = changelog.commits.map(commit => {
|
|
700
704
|
const commitUrl = `${repoUrl}/commit/${commit.hash}`;
|
|
@@ -762,9 +766,11 @@ const generateErrorsSection = (errors) => {
|
|
|
762
766
|
|
|
763
767
|
const rows = Object.entries(errors).map(([name, info]) => {
|
|
764
768
|
const npmUrl = `https://www.npmjs.com/package/${name}`;
|
|
765
|
-
const repoUrl = info.repoUrl.
|
|
766
|
-
|
|
767
|
-
|
|
769
|
+
const repoUrl = (info.repoUrl && typeof info.repoUrl === 'string') ?
|
|
770
|
+
info.repoUrl.replace(/\.git$/, '')
|
|
771
|
+
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
772
|
+
.replace(/^git\+https:/, 'https:') :
|
|
773
|
+
'#';
|
|
768
774
|
|
|
769
775
|
return `
|
|
770
776
|
<tr>
|
|
@@ -809,7 +815,7 @@ const generateNestedAddedSection = (added) => {
|
|
|
809
815
|
const npmUrl = `https://www.npmjs.com/package/${dep.name}`;
|
|
810
816
|
const versionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.version}`;
|
|
811
817
|
const parentUrl = `https://www.npmjs.com/package/${dep.parent}`;
|
|
812
|
-
const repoUrl = dep.repository ?
|
|
818
|
+
const repoUrl = (dep.repository && typeof dep.repository === 'string') ?
|
|
813
819
|
dep.repository.replace(/\.git$/, '')
|
|
814
820
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
815
821
|
.replace(/^git\+https:/, 'https:') :
|
|
@@ -860,15 +866,15 @@ const generateNestedUpgradedSection = (upgraded, changelogs, ciStatus = {}) => {
|
|
|
860
866
|
const oldVersionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.oldVersion}`;
|
|
861
867
|
const newVersionUrl = `https://www.npmjs.com/package/${dep.name}/v/${dep.newVersion}`;
|
|
862
868
|
const parentUrl = `https://www.npmjs.com/package/${dep.parent}`;
|
|
863
|
-
const repoUrl = dep.repository ?
|
|
869
|
+
const repoUrl = (dep.repository && typeof dep.repository === 'string') ?
|
|
864
870
|
dep.repository.replace(/\.git$/, '')
|
|
865
871
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
866
872
|
.replace(/^git\+https:/, 'https:') :
|
|
867
|
-
(changelogs[dep.name] && changelogs[dep.name].repoUrl ?
|
|
873
|
+
(changelogs[dep.name] && changelogs[dep.name].repoUrl && typeof changelogs[dep.name].repoUrl === 'string') ?
|
|
868
874
|
changelogs[dep.name].repoUrl.replace(/\.git$/, '')
|
|
869
875
|
.replace(/^git@github\.com:/, 'https://github.com/')
|
|
870
876
|
.replace(/^git\+https:/, 'https:') :
|
|
871
|
-
null
|
|
877
|
+
null;
|
|
872
878
|
|
|
873
879
|
const changeTypeBadge = `<span class="badge ${dep.changeType}">${dep.changeType}</span>`;
|
|
874
880
|
|
package/lib/index.mjs
CHANGED
|
@@ -932,11 +932,12 @@ const extractFromDependencies = (dependencies, packages) => {
|
|
|
932
932
|
* @param {Object} dep - Dependency object
|
|
933
933
|
* @param {string} newerVersionDir - Directory of the newer version
|
|
934
934
|
* @param {string} reposDir - Repository directory
|
|
935
|
-
* @param {Object} multibar - CLI multi progress bar instance
|
|
935
|
+
* @param {Object} multibar - CLI multi progress bar instance (null if disabled)
|
|
936
936
|
* @param {number} maxNameLength - Maximum name length for consistent padding
|
|
937
|
+
* @param {boolean} useProgressBars - Whether to use progress bars
|
|
937
938
|
* @returns {Promise<Object>} - Object with changelog, error, and CI status
|
|
938
939
|
*/
|
|
939
|
-
const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar, maxNameLength) => {
|
|
940
|
+
const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar, maxNameLength, useProgressBars = true) => {
|
|
940
941
|
const result = {
|
|
941
942
|
name: dep.name,
|
|
942
943
|
changelog: null,
|
|
@@ -951,15 +952,23 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
951
952
|
}
|
|
952
953
|
displayName = displayName.padEnd(maxNameLength);
|
|
953
954
|
|
|
954
|
-
// Create individual progress bar for this dependency
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
955
|
+
// Create individual progress bar for this dependency (if enabled)
|
|
956
|
+
let depBar = null;
|
|
957
|
+
if (useProgressBars && multibar) {
|
|
958
|
+
depBar = multibar.create(100, 0, { name: displayName, status: 'Starting...' });
|
|
959
|
+
depBar.update(10, { status: 'Getting repo URL...' });
|
|
960
|
+
} else if (!useProgressBars) {
|
|
961
|
+
console.log(`Processing ${dep.name}...`);
|
|
962
|
+
}
|
|
958
963
|
const packageDir = join(newerVersionDir, 'node_modules', dep.name);
|
|
959
964
|
const repoUrl = await getRepositoryUrl(packageDir);
|
|
960
965
|
|
|
961
966
|
if (!repoUrl) {
|
|
962
|
-
depBar
|
|
967
|
+
if (depBar) {
|
|
968
|
+
depBar.update(100, { status: '❌ No repo URL' });
|
|
969
|
+
} else if (!useProgressBars) {
|
|
970
|
+
console.log(` ❌ ${dep.name}: No repository URL found`);
|
|
971
|
+
}
|
|
963
972
|
result.error = {
|
|
964
973
|
repoUrl: null,
|
|
965
974
|
oldVersion: dep.oldVersion,
|
|
@@ -969,7 +978,9 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
969
978
|
return result;
|
|
970
979
|
}
|
|
971
980
|
|
|
972
|
-
depBar
|
|
981
|
+
if (depBar) {
|
|
982
|
+
depBar.update(20, { status: 'Cleaning repo URL...' });
|
|
983
|
+
}
|
|
973
984
|
|
|
974
985
|
// Clean the repository URL and convert to git URL for authentication
|
|
975
986
|
let cleanRepoUrl = repoUrl.replace(/^git\+/, '');
|
|
@@ -1005,13 +1016,19 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
1005
1016
|
cleanRepoUrl += '.git';
|
|
1006
1017
|
}
|
|
1007
1018
|
|
|
1008
|
-
depBar
|
|
1019
|
+
if (depBar) {
|
|
1020
|
+
depBar.update(30, { status: 'Getting commits...' });
|
|
1021
|
+
}
|
|
1009
1022
|
|
|
1010
1023
|
let commits = [];
|
|
1011
1024
|
try {
|
|
1012
1025
|
commits = await getCommitHistory(cleanRepoUrl, dep.oldVersion, dep.newVersion, reposDir);
|
|
1013
1026
|
if (commits.length > 0) {
|
|
1014
|
-
depBar
|
|
1027
|
+
if (depBar) {
|
|
1028
|
+
depBar.update(70, { status: `Found ${commits.length} commits` });
|
|
1029
|
+
} else if (!useProgressBars) {
|
|
1030
|
+
console.log(` ✅ ${dep.name}: Found ${commits.length} commits`);
|
|
1031
|
+
}
|
|
1015
1032
|
result.changelog = {
|
|
1016
1033
|
repoUrl: cleanRepoUrl,
|
|
1017
1034
|
oldVersion: dep.oldVersion,
|
|
@@ -1019,7 +1036,11 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
1019
1036
|
commits
|
|
1020
1037
|
};
|
|
1021
1038
|
} else {
|
|
1022
|
-
depBar
|
|
1039
|
+
if (depBar) {
|
|
1040
|
+
depBar.update(70, { status: '⚠️ No commits found' });
|
|
1041
|
+
} else if (!useProgressBars) {
|
|
1042
|
+
console.log(` ⚠️ ${dep.name}: No commits found between versions`);
|
|
1043
|
+
}
|
|
1023
1044
|
result.error = {
|
|
1024
1045
|
repoUrl: cleanRepoUrl,
|
|
1025
1046
|
oldVersion: dep.oldVersion,
|
|
@@ -1028,7 +1049,11 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
1028
1049
|
};
|
|
1029
1050
|
}
|
|
1030
1051
|
} catch (error) {
|
|
1031
|
-
depBar
|
|
1052
|
+
if (depBar) {
|
|
1053
|
+
depBar.update(70, { status: '❌ Commit error' });
|
|
1054
|
+
} else if (!useProgressBars) {
|
|
1055
|
+
console.log(` ❌ ${dep.name}: Error getting commits - ${error.message}`);
|
|
1056
|
+
}
|
|
1032
1057
|
result.error = {
|
|
1033
1058
|
repoUrl: cleanRepoUrl,
|
|
1034
1059
|
oldVersion: dep.oldVersion,
|
|
@@ -1038,19 +1063,38 @@ const processSingleDependency = async (dep, newerVersionDir, reposDir, multibar,
|
|
|
1038
1063
|
}
|
|
1039
1064
|
|
|
1040
1065
|
// Get GitHub Actions status for the new version
|
|
1041
|
-
depBar
|
|
1066
|
+
if (depBar) {
|
|
1067
|
+
depBar.update(80, { status: 'Getting CI status...' });
|
|
1068
|
+
}
|
|
1042
1069
|
try {
|
|
1043
1070
|
const best = commits.length > 0 ? commits[0].hash : null;
|
|
1044
1071
|
const actionsStatus = await getGitHubActionsStatus(cleanRepoUrl, dep.newVersion, best);
|
|
1045
1072
|
if (actionsStatus) {
|
|
1046
1073
|
result.ciStatus = actionsStatus;
|
|
1047
|
-
|
|
1074
|
+
if (depBar) {
|
|
1075
|
+
depBar.update(90, { status: `CI: ${actionsStatus.status}` });
|
|
1076
|
+
} else if (!useProgressBars) {
|
|
1077
|
+
console.log(` ✅ ${dep.name}: Complete (CI: ${actionsStatus.status})`);
|
|
1078
|
+
}
|
|
1048
1079
|
} else {
|
|
1049
|
-
|
|
1080
|
+
if (depBar) {
|
|
1081
|
+
depBar.update(90, { status: 'No CI found' });
|
|
1082
|
+
} else if (!useProgressBars) {
|
|
1083
|
+
console.log(` ✅ ${dep.name}: Complete (no CI)`);
|
|
1084
|
+
}
|
|
1050
1085
|
}
|
|
1051
1086
|
} catch (error) {
|
|
1052
1087
|
// Silently ignore CI status errors
|
|
1053
|
-
|
|
1088
|
+
if (depBar) {
|
|
1089
|
+
depBar.update(90, { status: 'CI check failed' });
|
|
1090
|
+
} else if (!useProgressBars) {
|
|
1091
|
+
console.log(` ✅ ${dep.name}: Complete (CI error)`);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// Final completion status
|
|
1096
|
+
if (depBar) {
|
|
1097
|
+
depBar.update(100, { status: '✅ Complete' });
|
|
1054
1098
|
}
|
|
1055
1099
|
|
|
1056
1100
|
return result;
|
|
@@ -1073,33 +1117,46 @@ const processInParallel = async (dependencies, newerVersionDir, reposDir, concur
|
|
|
1073
1117
|
return { changelogs, errors, ciStatus };
|
|
1074
1118
|
}
|
|
1075
1119
|
|
|
1120
|
+
// Detect small screen and disable progress bars if needed
|
|
1121
|
+
const terminalHeight = process.stdout.rows || 24;
|
|
1122
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
1123
|
+
const isSmallScreen = terminalHeight < 15 || terminalWidth < 60 || dependencies.length > (terminalHeight - 10);
|
|
1124
|
+
|
|
1076
1125
|
// Calculate the maximum name length for consistent padding
|
|
1077
1126
|
const maxNameLength = Math.min(
|
|
1078
1127
|
Math.max(...dependencies.map(dep => dep.name.length)),
|
|
1079
1128
|
40 // Reasonable maximum to prevent extremely long lines
|
|
1080
1129
|
);
|
|
1081
1130
|
|
|
1082
|
-
|
|
1083
|
-
const multibar = new cliProgress.MultiBar({
|
|
1084
|
-
clearOnComplete: false,
|
|
1085
|
-
hideCursor: true,
|
|
1086
|
-
format: '{name} |{bar}| {percentage}% | {status}'
|
|
1087
|
-
}, {
|
|
1088
|
-
barCompleteChar: '\u2588',
|
|
1089
|
-
barIncompleteChar: '\u2591'
|
|
1090
|
-
});
|
|
1091
|
-
|
|
1092
|
-
// Register multibar for cleanup
|
|
1093
|
-
globalCleanupState.multibar = multibar;
|
|
1131
|
+
let multibar = null;
|
|
1094
1132
|
|
|
1095
|
-
|
|
1133
|
+
if (isSmallScreen) {
|
|
1134
|
+
console.log(`\nProcessing ${dependencies.length} dependencies with concurrency limit of ${concurrency}:`);
|
|
1135
|
+
console.log('(Progress bars disabled for small screen or large dependency count)\n');
|
|
1136
|
+
} else {
|
|
1137
|
+
// Create multi progress bar
|
|
1138
|
+
multibar = new cliProgress.MultiBar({
|
|
1139
|
+
clearOnComplete: false,
|
|
1140
|
+
hideCursor: true,
|
|
1141
|
+
forceRedraw: true,
|
|
1142
|
+
format: '{name} |{bar}| {percentage}% | {status}'
|
|
1143
|
+
}, {
|
|
1144
|
+
barCompleteChar: '\u2588',
|
|
1145
|
+
barIncompleteChar: '\u2591'
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
// Register multibar for cleanup
|
|
1149
|
+
globalCleanupState.multibar = multibar;
|
|
1150
|
+
|
|
1151
|
+
console.log(`\nProcessing ${dependencies.length} dependencies with concurrency limit of ${concurrency}:\n`);
|
|
1152
|
+
}
|
|
1096
1153
|
|
|
1097
1154
|
// Create queue with concurrency limit
|
|
1098
1155
|
const queue = new PQueue({ concurrency });
|
|
1099
1156
|
|
|
1100
1157
|
// Add all dependencies to the queue
|
|
1101
1158
|
const promises = dependencies.map(dep =>
|
|
1102
|
-
queue.add(() => processSingleDependency(dep, newerVersionDir, reposDir, multibar, maxNameLength))
|
|
1159
|
+
queue.add(() => processSingleDependency(dep, newerVersionDir, reposDir, multibar, maxNameLength, !isSmallScreen))
|
|
1103
1160
|
);
|
|
1104
1161
|
|
|
1105
1162
|
// Wait for all tasks to complete
|
|
@@ -1118,13 +1175,15 @@ const processInParallel = async (dependencies, newerVersionDir, reposDir, concur
|
|
|
1118
1175
|
}
|
|
1119
1176
|
}
|
|
1120
1177
|
|
|
1121
|
-
multibar
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1178
|
+
if (multibar) {
|
|
1179
|
+
multibar.stop();
|
|
1180
|
+
|
|
1181
|
+
// Unregister multibar from cleanup
|
|
1182
|
+
globalCleanupState.multibar = null;
|
|
1183
|
+
|
|
1184
|
+
// Ensure cursor is visible after progress bars
|
|
1185
|
+
process.stdout.write('\x1b[?25h'); // Show cursor
|
|
1186
|
+
}
|
|
1128
1187
|
|
|
1129
1188
|
console.log(`\n✅ Completed processing ${dependencies.length} dependencies\n`);
|
|
1130
1189
|
|