@@ -3,8 +3,10 @@ import JSON5 from "json5";
3
3
import { execSync } from "node:child_process" ;
4
4
import * as fs from "node:fs" ;
5
5
import path from "node:path" ;
6
+ import semver from 'semver'
6
7
7
8
import { getFrameworks } from "./helpers/frameworks.js" ;
9
+ import { rebuildSingleFramework } from "./rebuild-single-framework.js" ;
8
10
9
11
/**
10
12
* @typedef {Object } Framework
@@ -14,6 +16,23 @@ import { getFrameworks } from "./helpers/frameworks.js";
14
16
15
17
const frameworks = getFrameworks ( ) ;
16
18
19
+
20
+ function performUpdate ( frameworkPath , frameworkName ) {
21
+ console . log ( `Updating ${ frameworkName } ` ) ;
22
+ try {
23
+ const npmCmd = `ncu -u` ;
24
+ execSync ( npmCmd , {
25
+ cwd : frameworkPath ,
26
+ stdio : "inherit" ,
27
+ } ) ;
28
+ rebuildSingleFramework ( { frameworks : [ frameworkName ] , ci : false } ) ;
29
+ return `Sucessfully updated ${ frameworkPath } ` ;
30
+ } catch ( error ) {
31
+ console . error ( `Failed to update ${ frameworkPath } . Error Code ${ error . status } and message: ${ error . message } ` ) ;
32
+ return `Failed to update ${ frameworkPath } ` ;
33
+ }
34
+ }
35
+
17
36
/**
18
37
* Looks for duplicate frameworks
19
38
* @param {{type: string, name: string}[] } frameworks
@@ -29,9 +48,56 @@ function findDuplicateFrameworks(frameworks) {
29
48
const duplicateFrameworks = findDuplicateFrameworks ( frameworks ) ;
30
49
const frameworksCache = new Map ( ) ;
31
50
32
- /**
33
- * @param {string } packageName
34
- */
51
+ function getVersionFromPackageLock ( packageJSONLockPath , packageNames ) {
52
+ if ( ! fs . existsSync ( packageJSONLockPath ) ) {
53
+ throw new Error ( `package-lock.json not found at ${ packageJSONLockPath } ` ) ;
54
+ }
55
+
56
+ let versions = { } ;
57
+
58
+ for ( let packageName of packageNames ) {
59
+ const packageLockJSON = JSON . parse ( fs . readFileSync ( packageJSONLockPath , "utf8" ) ) ;
60
+ const packageVersion =
61
+ packageLockJSON . dependencies ?. [ packageName ] ?. version ||
62
+ packageLockJSON . packages ?. [ `node_modules/${ packageName } ` ] ?. version ||
63
+ "ERROR: Not found in package-lock" ;
64
+ versions [ packageName ] = packageVersion ;
65
+ }
66
+ return versions ;
67
+ }
68
+
69
+ function shouldUpdate ( packageJSONLockPath , packageNames , DEBUG ) {
70
+ try {
71
+ let versions = getVersionFromPackageLock ( packageJSONLockPath , packageNames ) ;
72
+ console . log ( versions ) ;
73
+
74
+ for ( let packageName of packageNames ) {
75
+ const npmCmd = `npm view ${ packageName } version` ;
76
+
77
+
78
+ const newestVersion = execSync ( npmCmd , {
79
+ stdio : [ "ignore" , "pipe" , "ignore" ] ,
80
+ } ) . toString ( ) ;
81
+
82
+ let res = semver . diff ( versions [ packageName ] , newestVersion ) ;
83
+ console . log ( `Latest version for ${ packageName } is ${ newestVersion } and the
84
+ current version is ${ versions [ packageName ] } comparison result is ${ res } ` ) ;
85
+ if ( res === 'major' || res === 'minor' ) {
86
+ if ( DEBUG ) {
87
+ console . log ( `Update required for ${ packageName } ` ) ;
88
+ }
89
+ return true ;
90
+ }
91
+ }
92
+ } catch ( error ) {
93
+ console . error (
94
+ `Failed to get latest versions for ${ packageNames } . Error Code ${ error . status } and message: ${ error . message } `
95
+ ) ;
96
+ return { isObsolete : false , lastUpdate : null , packageNames } ;
97
+ }
98
+ return false ;
99
+ }
100
+
35
101
function maybeObsolete ( packageName ) {
36
102
try {
37
103
const npmCmd = `npm view ${ packageName } time` ;
@@ -82,14 +148,19 @@ const manualChecks = [];
82
148
* @param {Object } options
83
149
* @param {boolean } options.debug
84
150
*/
85
- export function checkObsoleteFrameworks ( { debug } ) {
86
- console . log ( "Check obsolete frameworks" , "debug" , debug ) ;
151
+ export function updateFrameworks ( { type, debug } ) {
152
+ let types = type || [ "keyed" , "non-keyed" ] ;
153
+ console . log ( "Check implementations for updates" , "debug" , debug , "type" , type ) ;
154
+ let log = [ ] ;
87
155
88
156
const DEBUG = debug ;
89
157
90
158
for ( const { name, type } of frameworks ) {
159
+ if ( ! types . includes ( type ) ) continue
160
+ console . log ( `Checking ${ type } /${ name } ` ) ;
91
161
const frameworkPath = path . join ( "frameworks" , type , name ) ;
92
162
const packageJSONPath = path . join ( frameworkPath , "package.json" ) ;
163
+ const packageJSONLockPath = path . join ( frameworkPath , "package-lock.json" ) ;
93
164
94
165
if ( ! fs . existsSync ( packageJSONPath ) ) {
95
166
missingPackageWarnings . push ( `WARN: skipping ${ type } /${ name } since there's no package.json` ) ;
@@ -109,28 +180,29 @@ export function checkObsoleteFrameworks({ debug }) {
109
180
}
110
181
111
182
const packages = mainPackages . split ( ":" ) ;
112
- const isPackageObsolete = packages . map ( ( element ) => maybeObsolete ( element ) ) ;
113
-
114
- if ( DEBUG ) {
115
- console . log ( `Results for ${ type } / ${ name } ${ isPackageObsolete } ` ) ;
116
- }
117
-
118
- const anyPackageObsolete = isPackageObsolete . some ( ( packageFramework ) => packageFramework . isObsolete ) ;
119
-
120
- if ( anyPackageObsolete ) {
121
- const formattedPackages = isPackageObsolete
122
- . map ( ( result ) => `${ result . packageName } :${ result . lastUpdate } ` )
123
- . join ( ", " ) ;
124
-
125
- console . log ( `Last npm update for ${ type } /${ name } - ${ mainPackages } is older than a year: ${ formattedPackages } ` ) ;
126
- continue ;
127
- }
128
-
129
- if ( DEBUG ) {
130
- console . log ( `Last npm update for ${ type } / ${ name } ${ mainPackages } is newer than a year` ) ;
183
+ const update = shouldUpdate ( packageJSONLockPath , packages ) ;
184
+
185
+ if ( update ) {
186
+ log . push ( performUpdate ( frameworkPath , type + "/" + name ) ) ;
187
+ } else {
188
+ const isPackageObsolete = packages . map ( ( element ) => maybeObsolete ( element ) ) ;
189
+ const anyPackageObsolete = isPackageObsolete . some ( ( packageFramework ) => packageFramework . isObsolete ) ;
190
+
191
+ if ( anyPackageObsolete ) {
192
+ const formattedPackages = isPackageObsolete
193
+ . map ( ( result ) => `${ result . packageName } :${ result . lastUpdate } ` )
194
+ . join ( ", " ) ;
195
+
196
+ console . log ( `Last npm update for ${ type } /${ name } - ${ mainPackages } is older than a year: ${ formattedPackages } ` ) ;
197
+ log . push ( `Retire ${ type } / ${ name } - ${ mainPackages } is older than a year` ) ;
198
+ }
199
+ else if ( DEBUG ) {
200
+ log . push ( `Nothing to do for ${ type } / ${ name } ` ) ;
201
+ }
131
202
}
132
203
}
133
204
205
+ console . log ( "Log:\n" , log . join ( "\n" ) ) ;
134
206
if ( missingPackageWarnings . length > 0 ) console . warn ( "\nWarnings:\n" + missingPackageWarnings . join ( "\n" ) ) ;
135
207
if ( manualChecks . length > 0 )
136
208
console . warn ( "\nThe following frameworks must be checked manually\n" + manualChecks . join ( "\n" ) ) ;
0 commit comments