@@ -14,73 +14,108 @@ import {
1414} from '@github/dependency-submission-toolkit'
1515import { YAMLMap } from 'yaml' ;
1616
17- /**getManifestFromEnvironmentFile(document, fileName) {
18- core.debug(`getManifestFromEnvironmentFile processing ${fileName}`);
19-
20- let manifest = new Manifest("Environment", fileName);
21-
22-
23- /**
24- let manifest = new Manifest(document.name, fileName);
25-
26- core.debug(`Processing ${document.packages?.length} packages`);
27-
28- document.packages?.forEach(pkg => {
29- let packageName = pkg.name;
30- let packageVersion = pkg.packageVersion;
31- let referenceLocator = pkg.externalRefs?.find(ref => ref.referenceCategory === "PACKAGE-MANAGER" && ref.referenceType === "purl")?.referenceLocator;
32- let genericPurl = `pkg:generic/${packageName}@${packageVersion}`;
33- // SPDX 2.3 defines a purl field
34- let purl;
35- if (pkg.purl != undefined) {
36- purl = pkg.purl;
37- } else if (referenceLocator != undefined) {
38- purl = referenceLocator;
39- } else {
40- purl = genericPurl;
41- }
42-
43- // Working around weird encoding issues from an SBOM generator
44- // Find the last instance of %40 and replace it with @
45- purl = replaceVersionEscape(purl);
46-
47- let relationships = document.relationships?.find(rel => rel.relatedSpdxElement == pkg.SPDXID && rel.relationshipType == "DEPENDS_ON" && rel.spdxElementId != "SPDXRef-RootPackage");
48- if (relationships != null && relationships.length > 0) {
49- manifest.addIndirectDependency(new Package(purl));
50- } else {
17+ /**getManifestFromEnvironmentFile(document, fileName) {
18+ core.debug(`getManifestFromEnvironmentFile processing ${fileName}`);
19+
20+ let manifest = new Manifest("Environment", fileName);
21+
22+
23+ /**
24+ let manifest = new Manifest(document.name, fileName);
25+
26+ core.debug(`Processing ${document.packages?.length} packages`);
27+
28+ document.packages?.forEach(pkg => {
29+ let packageName = pkg.name;
30+ let packageVersion = pkg.packageVersion;
31+ let referenceLocator = pkg.externalRefs?.find(ref => ref.referenceCategory === "PACKAGE-MANAGER" && ref.referenceType === "purl")?.referenceLocator;
32+ let genericPurl = `pkg:generic/${packageName}@${packageVersion}`;
33+ // SPDX 2.3 defines a purl field
34+ let purl;
35+ if (pkg.purl != undefined) {
36+ purl = pkg.purl;
37+ } else if (referenceLocator != undefined) {
38+ purl = referenceLocator;
39+ } else {
40+ purl = genericPurl;
41+ }
42+
43+ // Working around weird encoding issues from an SBOM generator
44+ // Find the last instance of %40 and replace it with @
45+ purl = replaceVersionEscape(purl);
46+
47+ let relationships = document.relationships?.find(rel => rel.relatedSpdxElement == pkg.SPDXID && rel.relationshipType == "DEPENDS_ON" && rel.spdxElementId != "SPDXRef-RootPackage");
48+ if (relationships != null && relationships.length > 0) {
49+ manifest.addIndirectDependency(new Package(purl));
50+ } else {
51+ manifest.addDirectDependency(new Package(purl));
52+ }
53+ });
54+ return manifest;
55+ }*/
56+
57+ /***/
58+
59+ export default class CondaParser {
60+
61+ static searchFiles ( filePath = "" , filePattern = "" ) {
62+ if ( filePath == "" ) {
63+ let filePath = core . getInput ( 'filePath' ) ;
64+ }
65+ if ( filePattern == "" ) {
66+ let filePattern = core . getInput ( 'filePattern' ) ;
67+ }
68+
69+ return glob . sync ( `${ filePath } /${ filePattern } ` , { } ) ;
70+ }
71+
72+ static getManifestsFromEnvironmentFiles ( files : string [ ] ) {
73+ core . debug ( `Processing ${ files . length } files` ) ;
74+ let manifests : any [ ] = [ ] ;
75+ files ?. forEach ( filePath => {
76+ core . debug ( `Processing ${ filePath } ` ) ;
77+ const contents = fs . readFileSync ( filePath , 'utf8' )
78+ manifests . push ( CondaParser . getManifestFromYaml ( yaml . parse ( contents ) , filePath ) ) ;
79+ } ) ;
80+ return manifests ;
81+ }
82+
83+ // Gets a Manifest object from an environment.yaml
84+ static getManifestFromYaml ( yaml : any , filePath : string ) {
85+ core . debug ( `getManifestFromEnvironmentFile processing ${ yaml } ` ) ;
86+
87+ let manifest = new Manifest ( yaml . name , filePath ) ;
88+ yaml . dependencies ?. forEach ( ( dependency : any ) => {
89+ let purl = "" ;
90+ // If it's an object with the collection `pip`, then these are PyPI dependencies
91+ if ( dependency instanceof Object && dependency . pip != null ) {
92+ dependency . pip . forEach ( ( pipDependency :string ) => {
93+ purl = this . getPurlFromDependency ( pipDependency , "pypi" ) ;
94+ manifest . addDirectDependency ( new Package ( purl ) ) ;
95+ } ) ;
96+ } else {
97+ purl = this . getPurlFromDependency ( dependency , "conda" ) ;
5198 manifest . addDirectDependency ( new Package ( purl ) ) ;
52- }
99+ }
53100 } ) ;
54101 return manifest ;
55- }*/
56-
57- /***/
58-
59- export default class CondaParser {
60-
61- static searchFiles ( filePath = "" , filePattern = "" ) {
62- if ( filePath == "" ) {
63- let filePath = core . getInput ( 'filePath' ) ;
64- }
65- if ( filePattern == "" ) {
66- let filePattern = core . getInput ( 'filePattern' ) ;
67- }
68-
69- return glob . sync ( `${ filePath } /${ filePattern } ` , { } ) ;
70- }
71-
72- static getManifestsFromEnvironmentFiles ( files :string [ ] ) {
73- core . debug ( `Processing ${ files . length } files` ) ;
74- let manifests : any [ ] = [ ] ;
75- files ?. forEach ( filePath => {
76- core . debug ( `Processing ${ filePath } ` ) ;
77- const contents = fs . readFileSync ( filePath , 'utf8' )
78- manifests . push ( yaml . parse ( contents ) ) ;
79- } ) ;
80- return manifests ;
81- }
82-
83- static getManifestFromYaml ( yaml :any ) {
84-
85- }
102+ }
103+
104+ // Gets a purl string from an environment file's list of dependencies
105+ static getPurlFromDependency ( dependency : string , ecosystem : string ) {
106+ // Versions look like "python=3.8" or if nested in a pip section like "pytorch==1.0"
107+ // Split on the '=' to separate the packageName and version
108+ let delimiter = ( ecosystem == "pypi" ) ? "==" : "=" ;
109+ let split = dependency . split ( delimiter ) ;
110+ let packageName = split [ 0 ] ;
111+ // If there is a version specified, use it, otherwise, leave it off.
112+ let version = ( split . length > 1 ) ? `@${ split [ 1 ] } ` : "" ;
113+
114+ // If it's a PyPI dependency, then normalize the package name
115+ if ( ecosystem == "pypi" ) {
116+ packageName = packageName . toLowerCase ( ) . replace ( "_" , "-" ) ;
117+ }
118+
119+ return `pkg:${ ecosystem } /${ packageName } ${ version } ` ;
120+ }
86121}
0 commit comments