@@ -111,6 +111,9 @@ export class Extractor {
111
111
component . evidence = new CDX . Models . ComponentEvidence ( {
112
112
licenses : new CDX . Models . LicenseRepository ( this . getLicenseEvidence ( dirname ( pkg . path ) , logger ) )
113
113
} )
114
+ for ( const line of this . getCopyrightEvidence ( dirname ( pkg . path ) , logger ) ) {
115
+ component . evidence . copyright . add ( line )
116
+ }
114
117
}
115
118
116
119
component . purl = this . #purlFactory. makeFromComponent ( component )
@@ -130,6 +133,46 @@ export class Extractor {
130
133
}
131
134
}
132
135
136
+ readonly #COPYRIGHT_FILENAME_PATTERN = / ^ (?: U N ) ? L I C E N [ C S ] E | .\. L I C E N [ C S ] E $ | ^ N O T I C E $ | ^ C O P Y R I G H T N O T I C E $ / i
137
+
138
+ public * getCopyrightEvidence ( packageDir : string , logger ?: WebpackLogger ) : Generator < string > {
139
+ let pcis
140
+ try {
141
+ pcis = readdirSync ( packageDir , { withFileTypes : true } )
142
+ } catch ( e ) {
143
+ logger ?. warn ( 'collecting license evidence in' , packageDir , 'failed:' , e )
144
+ return
145
+ }
146
+ for ( const pci of pcis ) {
147
+ if (
148
+ ! pci . isFile ( ) ||
149
+ ! this . #COPYRIGHT_FILENAME_PATTERN. test ( pci . name )
150
+ ) {
151
+ continue
152
+ }
153
+ const fp = join ( packageDir , pci . name )
154
+ try {
155
+ // Add copyright evidence
156
+ const linesStartingWithCopyright = readFileSync ( fp ) . toString ( 'utf-8' )
157
+ . split ( / \r \n ? | \n / )
158
+ . map ( line => line . trimStart ( ) )
159
+ . filter ( trimmedLine => {
160
+ return trimmedLine . startsWith ( 'opyright' , 1 ) && // include copyright statements
161
+ ! trimmedLine . startsWith ( 'opyright notice' , 1 ) && // exclude lines from license text
162
+ ! trimmedLine . startsWith ( 'opyright and related rights' , 1 ) &&
163
+ ! trimmedLine . startsWith ( 'opyright license to reproduce' , 1 )
164
+ } )
165
+ . filter ( ( value , index , list ) => index === 0 || value !== list [ 0 ] ) // remove duplicates
166
+
167
+ for ( const line of linesStartingWithCopyright ) {
168
+ yield line
169
+ }
170
+ } catch ( e ) { // may throw if `readFileSync()` fails
171
+ logger ?. warn ( 'collecting copyright evidences from' , fp , 'failed:' , e )
172
+ }
173
+ }
174
+ }
175
+
133
176
readonly #LICENSE_FILENAME_PATTERN = / ^ (?: U N ) ? L I C E N [ C S ] E | .\. L I C E N [ C S ] E $ | ^ N O T I C E $ / i
134
177
135
178
public * getLicenseEvidence ( packageDir : string , logger ?: WebpackLogger ) : Generator < CDX . Models . License > {
@@ -150,6 +193,7 @@ export class Extractor {
150
193
151
194
const contentType = getMimeForTextFile ( pci . name )
152
195
if ( contentType === undefined ) {
196
+ logger ?. warn ( `could not determine content-type for ${ pci . name } ` )
153
197
continue
154
198
}
155
199
0 commit comments