Skip to content

Commit b2e8f20

Browse files
dira271641dira271641
authored andcommitted
feat(dig) relationship detailed ship view
1 parent 9052b7a commit b2e8f20

File tree

5 files changed

+198
-1
lines changed

5 files changed

+198
-1
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ By default uses _$HOME/sbom.spdx.json_ file to load the data. (you can pass cust
1919
with --config option
2020
![Sample](https://github.com/dineshr93/sq/blob/main/sample2.png?raw=true)
2121

22+
with relation dig option
23+
![Sample](https://github.com/dineshr93/sq/blob/main/dig.png?raw=true)
24+
2225
## Getting Started
2326

2427
Contains following commands
@@ -70,8 +73,22 @@ Flags:
7073
-t, --toggle Help message for toggle
7174
7275
Use "sq [command] --help" for more information about a command.
76+
================================================================
77+
>sq rels dig -h
78+
dig the relationship and show actual packages and files
79+
80+
For Ex:
81+
To list all relationship: ./sq rels dig
7382
83+
Usage:
84+
sq rels dig [flags]
85+
86+
Flags:
87+
-h, --help help for dig
7488
89+
Global Flags:
90+
--config string YOUR SBOM JSON FILE (default is $CURRENT_DIR/sbom.spdx.json)
91+
=================================================================
7592
Alternatively if UI is small to fit every thing, you can save the output to the file
7693
7794
sq meta > sbom-meta.txt

cmd/dig.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
3+
*/
4+
package cmd
5+
6+
import (
7+
"fmt"
8+
"os"
9+
10+
"github.com/dineshr93/sq/model"
11+
"github.com/spf13/cobra"
12+
"github.com/spf13/viper"
13+
)
14+
15+
// digCmd represents the dig command
16+
var digCmd = &cobra.Command{
17+
Use: "dig",
18+
Short: "dig the relationship and show actual packages and files",
19+
Long: `dig the relationship and show actual packages and files
20+
21+
For Ex:
22+
To list all relationship: ./sq rels dig`,
23+
Run: func(cmd *cobra.Command, args []string) {
24+
// fmt.Println("digging")
25+
dataFile := string(viper.ConfigFileUsed())
26+
s := &model.SPDX{}
27+
if err := s.Load(dataFile); err != nil {
28+
fmt.Fprintln(os.Stderr, err.Error())
29+
os.Exit(1)
30+
}
31+
32+
rels := s.Relationships
33+
lenRels := len(rels)
34+
35+
if len(args) > 0 {
36+
// fmt.Sprintln(len(args))
37+
// i, err := strconv.Atoi(args[0])
38+
// if err != nil {
39+
// panic(err)
40+
// }
41+
// s.PrintDigRels(i)
42+
s.PrintDigRels()
43+
} else {
44+
// fmt.Sprintln(lenRels)
45+
if lenRels > 0 {
46+
s.PrintDigRels()
47+
}
48+
}
49+
},
50+
}
51+
52+
func init() {
53+
relsCmd.AddCommand(digCmd)
54+
55+
// Here you will define your flags and configuration settings.
56+
57+
// Cobra supports Persistent Flags which will work for this command
58+
// and all subcommands, e.g.:
59+
// digCmd.PersistentFlags().String("foo", "", "A help for foo")
60+
61+
// Cobra supports local flags which will only run when this command
62+
// is called directly, e.g.:
63+
// digCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
64+
}

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func init() {
4747
// Cobra supports persistent flags, which, if defined here,
4848
// will be global for your application.
4949

50-
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.sq.yaml)")
50+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "YOUR SBOM JSON FILE (default is $CURRENT_DIR/sbom.spdx.json)")
5151

5252
// Cobra also supports local flags, which will only run
5353
// when this action is called directly.

dig.png

739 KB
Loading

model/spdx.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,119 @@ func (s *SPDX) PrintRels(np int) {
382382
table.Println()
383383

384384
}
385+
386+
func removeDuplicateStr(strSlice []string) []string {
387+
allKeys := make(map[string]bool)
388+
list := []string{}
389+
for _, item := range strSlice {
390+
if _, value := allKeys[item]; !value {
391+
allKeys[item] = true
392+
list = append(list, item)
393+
}
394+
}
395+
return list
396+
}
397+
398+
// func (s *SPDX) getrelspdxelem(spdxID string) (string, Relationships) {
399+
// rels := s.Relationships
400+
// for _, rel := range rels {
401+
// if rel.SpdxElementID == spdxID {
402+
// return rel.RelatedSpdxElement, rel
403+
// }
404+
// }
405+
// return "", Relationships{}
406+
// }
407+
func (s *SPDX) getdependson(d int, rel1 Relationships) {
408+
pkgs := s.Packages
409+
var nextSPDXidDetail string
410+
var SPDXidDetail string
411+
// fmt.Println("===================DEPENDS_ON======================")
412+
for _, pkg := range pkgs {
413+
if pkg.Spdxid == rel1.SpdxElementID {
414+
SPDXidDetail = fmt.Sprintf("%v %v version: %v", blue(pkg.Name), yellow("|"), blue(pkg.VersionInfo))
415+
}
416+
if pkg.Spdxid == rel1.RelatedSpdxElement {
417+
nextSPDXidDetail = fmt.Sprintf("%v %v version: %v", blue(pkg.Name), yellow("|"), blue(pkg.VersionInfo))
418+
}
419+
420+
}
421+
422+
fmt.Println(fmt.Sprintf("%v =====> %v Pkg %v =====> %v", SPDXidDetail, green("DEPENDS_ON"), blue(fmt.Sprintf("%d", d)), nextSPDXidDetail))
423+
}
424+
func (s *SPDX) getspdxpkg(d int, spdxID string, rel1 Relationships) {
425+
pkgs := s.Packages
426+
var filespdxids []string
427+
var SPDXidDetail string
428+
// var nextSPDXid string
429+
// var rel Relationships
430+
for _, pkg := range pkgs {
431+
if pkg.Spdxid == spdxID {
432+
SPDXidDetail = fmt.Sprintf("%v | version: %v", yellow(pkg.Name), yellow(pkg.VersionInfo))
433+
if len(pkg.HasFiles) > 0 {
434+
435+
filespdxids = pkg.HasFiles
436+
for i, filespdx := range filespdxids {
437+
s.getspdxfile(i, filespdx, SPDXidDetail)
438+
}
439+
}
440+
// d++
441+
// nextSPDXid, rel = s.getrelspdxelem(spdxID)
442+
// if nextSPDXid != "" {
443+
// s.getspdxpkg(d, nextSPDXid, rel)
444+
// }
445+
}
446+
}
447+
}
448+
func (s *SPDX) getspdxfile(i int, spdxID string, SPDXidDetail string) {
449+
files := s.Files
450+
for _, file := range files {
451+
if file.Spdxid == spdxID {
452+
i++
453+
fmt.Println(green(fmt.Sprintf("%v %v %v File %v %v %v", SPDXidDetail, yellow("---->"), red("CONTAINS"), blue(fmt.Sprintf("%d", i)), yellow("---->"), red(file.FileName))))
454+
}
455+
456+
}
457+
// n = 0
458+
// return ""
459+
}
460+
461+
func (s *SPDX) PrintDigRels() {
462+
rels := s.Relationships
463+
var rel Relationships
464+
var n int
465+
_ = n
466+
lenrels := len(rels)
467+
var spdxids []string = make([]string, lenrels)
468+
// var licenseinfo string
469+
//
470+
for id := 0; id < lenrels; id++ {
471+
rel = rels[id]
472+
spdxids = append(spdxids, rel.SpdxElementID)
473+
}
474+
unique_spdxIDs := removeDuplicateStr(spdxids)
475+
len_unique_spdxIDs := len(unique_spdxIDs)
476+
fmt.Println("No. of unique spdxID :", len_unique_spdxIDs)
477+
// _ = len_unique_spdxIDs
478+
var d int
479+
480+
fmt.Println(red("===================DESCRIBES======================"))
481+
for _, rel1 := range rels {
482+
switch rt := rel1.RelationshipType; rt {
483+
case "DESCRIBES":
484+
d++
485+
s.getspdxpkg(d, rel1.RelatedSpdxElement, rel1)
486+
}
487+
488+
}
489+
d = 0
490+
fmt.Println(red("===================DEPENDS_ON======================"))
491+
for _, rel1 := range rels {
492+
switch rt := rel1.RelationshipType; rt {
493+
case "DEPENDS_ON":
494+
d++
495+
s.getdependson(d, rel1)
496+
s.getspdxpkg(d, rel1.RelatedSpdxElement, rel1)
497+
}
498+
}
499+
500+
}

0 commit comments

Comments
 (0)