Skip to content

Commit

Permalink
Merge pull request #79 from siemens/feat/configurableExternalRef
Browse files Browse the repository at this point in the history
feat(external_ref): Make external_ref fields configurable

Reviewed-by: mishra.gaurav@siemens.com
Tested-by: mishra.gaurav@siemens.com
  • Loading branch information
GMishx authored Aug 13, 2024
2 parents 232c75b + bdb1a2d commit bfded19
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 53 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/api-swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ jobs:
check-latest: true
cache: true

- name: Code Generation
run: |
cp external_ref_fields.example.yaml external_ref_fields.yaml && go generate ./...
- name: Install swag
run: |
go install github.com/swaggo/swag/cmd/swag@latest
Expand All @@ -33,7 +37,7 @@ jobs:
- name: Check doc diff
run: |
diff swag/docs/docs.go cmd/laas/docs/docs.go > swagger-diff.txt
diff swag/docs/docs.go cmd/laas/docs/docs.go > swagger-diff.txt || true
# Check if file swagger-diff.txt is empty
if [ -s swagger-diff.txt ]
then
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
- if: matrix.build-mode == 'manual'
shell: bash
run: |
go build ./cmd/laas
cp external_ref_fields.example.yaml external_ref_fields.yaml && go generate ./... && go build ./cmd/laas
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fi
- name: Build
run: go build -v ./...
run: cp external_ref_fields.example.yaml external_ref_fields.yaml && go generate ./... && go build -v ./...

# - name: Test
# run: go test -v ./...
3 changes: 3 additions & 0 deletions .github/workflows/golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ jobs:
check-latest: true
cache: true

- name: Code Generation
run: cp external_ref_fields.example.yaml external_ref_fields.yaml && go generate ./...

- name: lint
uses: golangci/golangci-lint-action@v3
with:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ licenseRef.json
# IDE related files
/.idea
/LicenseDb.iml

external_ref_fields.yaml

pkg/models/external_ref_structs.go
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ RUN go mod download
COPY cmd/ cmd/
COPY pkg/ pkg/
COPY docs/ docs/
COPY external_ref_fields.example.yaml external_ref_fields.yaml

RUN wget https://raw.githubusercontent.com/fossology/fossology/master/install/db/licenseRef.json -O licenseRef.json

RUN CGO_ENABLED=0 GOOS=linux go build -a -o laas ./cmd/laas
RUN CGO_ENABLED=0 GOOS=linux go generate ./cmd/laas && go build -a -o laas ./cmd/laas

# Release Stage
FROM alpine:3.20 AS build-release
Expand All @@ -22,7 +23,7 @@ WORKDIR /app

COPY entrypoint.sh /app/entrypoint.sh

RUN apk add --no-cache openssl bash \
RUN apk add --no-cache openssl bash libc6-compat \
&& addgroup -S noroot \
&& adduser -S noroot -G noroot

Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ git clone https://github.com/fossology/LicenseDb.git
cd LicenseDb
```

- Create the `external_ref_fields.yaml` file in the root directory of the project and change the
values of the extra license json keys as per your requirement.

```bash
cp external_ref_fields.yaml.example external_ref_fields.yaml
vim external_ref_fields.yaml
```

- Generate Go struct for the extra fields listed in the external_ref_fields.yaml.

```bash
go generate ./...
```

- Build the project using following command.

```bash
Expand Down
8 changes: 8 additions & 0 deletions cmd/laas/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2024 Dearsh Oberoi <oberoidearsh@gmail.com>
// SPDX-FileCopyrightText: 2024 Siemens AG
//
// SPDX-License-Identifier: GPL-2.0-only

package main

//go:generate go run gen_external_ref_schema.go
87 changes: 87 additions & 0 deletions cmd/laas/gen_external_ref_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: 2024 Dearsh Oberoi <oberoidearsh@gmail.com>
// SPDX-FileCopyrightText: 2024 Siemens AG
//
// SPDX-License-Identifier: GPL-2.0-only

//go:build ignore

package main

import (
"errors"
"fmt"
"log"
"os"

"path/filepath"

"github.com/dave/jennifer/jen"
"gopkg.in/yaml.v3"
)

var (
PATH_EXTERNAL_REF_CONFIG_FILE = filepath.FromSlash("../../external_ref_fields.yaml")
PATH_EXTERNAL_REF_STRUCT_FILE = filepath.FromSlash("../../pkg/models/external_ref_structs.go")
)

// ExternalRefFieldMetadata is the metadata about the extra fields saved as json in the license external_ref column
type ExternalRefFieldMetaData struct {
StructFieldName string `yaml:"struct_field_name"`
Type string `yaml:"type"`
Name string `yaml:"name"`
}

// ExternalRefFields is the list of metadata of all extra fields
type ExternalRefFields struct {
Fields []ExternalRefFieldMetaData `yaml:"fields"`
}

func main() {
externalRefFields := ExternalRefFields{}

fieldsMetadata, err := os.ReadFile(PATH_EXTERNAL_REF_CONFIG_FILE)
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
}

err = yaml.Unmarshal(fieldsMetadata, &externalRefFields)
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
}

// REUSE-IgnoreStart

f := jen.NewFile("models")
f.Comment("SPDX-FileCopyrightText: FOSSology Community\nSPDX-License-Identifier: GPL-2.0-only\n\nThis file is autogenerated. Please do not edit it.\n")

// REUSE-IgnoreStart

var fields []jen.Code

for _, f := range externalRefFields.Fields {
field := jen.Id(f.StructFieldName).Op("*")
if f.StructFieldName == "" {
err = errors.New("field struct_field_name is missing in external_ref_fields.yaml")
}
switch f.Type {
case "boolean":
field = field.Bool()
case "string":
field = field.String()
case "int":
field = field.Int64()
default:
err = fmt.Errorf("type %s in external_ref_fields.yaml is not supported", f.Type)
}
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
return
}
field = field.Tag(map[string]string{"json": fmt.Sprintf("%s,omitempty", f.Name)})
fields = append(fields, field)
}

f.Type().Id("LicenseDBSchemaExtension").Struct(fields...)
f.Save(PATH_EXTERNAL_REF_STRUCT_FILE)

}
1 change: 1 addition & 0 deletions cmd/laas/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/joho/godotenv"

_ "github.com/dave/jennifer/jen"
_ "github.com/fossology/LicenseDb/cmd/laas/docs"
"github.com/fossology/LicenseDb/pkg/api"
"github.com/fossology/LicenseDb/pkg/db"
Expand Down
16 changes: 16 additions & 0 deletions external_ref_fields.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-FileCopyrightText: FOSSology contributors

fields:
- name: "license_suffix"
type: "string"
struct_field_name: "LicenseSuffix"
label: "License Suffix"
formComponentPath: "../components/dynamic/inputField"
componentType: "input"
- name: "license_explanation"
type: "string"
struct_field_name: "LicenseExplanation"
label: "License Explanation"
formComponentPath: "../components/dynamic/inputField"
componentType: "input"
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require (
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dave/jennifer v1.7.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE=
github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
108 changes: 73 additions & 35 deletions pkg/api/licenses.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"fmt"
"net/http"
"path/filepath"
"reflect"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -722,41 +723,78 @@ func addChangelogsForLicenseUpdate(tx *gorm.DB, username string,
UpdatedValue: &newVal,
})
}
if (oldLicense.ExternalRef.Data().InternalComment == nil && newLicense.ExternalRef.Data().InternalComment != nil) ||
(oldLicense.ExternalRef.Data().InternalComment != nil && newLicense.ExternalRef.Data().InternalComment == nil) ||
((oldLicense.ExternalRef.Data().InternalComment != nil && newLicense.ExternalRef.Data().InternalComment != nil) && (*oldLicense.ExternalRef.Data().InternalComment != *newLicense.ExternalRef.Data().InternalComment)) {
changes = append(changes, models.ChangeLog{
Field: "ExternalRef.InternalComment",
OldValue: oldLicense.ExternalRef.Data().InternalComment,
UpdatedValue: newLicense.ExternalRef.Data().InternalComment,
})
}
if (oldLicense.ExternalRef.Data().LicenseExplanation == nil && newLicense.ExternalRef.Data().LicenseExplanation != nil) ||
(oldLicense.ExternalRef.Data().LicenseExplanation != nil && newLicense.ExternalRef.Data().LicenseExplanation == nil) ||
((oldLicense.ExternalRef.Data().LicenseExplanation != nil && newLicense.ExternalRef.Data().LicenseExplanation != nil) && (*oldLicense.ExternalRef.Data().LicenseExplanation != *newLicense.ExternalRef.Data().LicenseExplanation)) {
changes = append(changes, models.ChangeLog{
Field: "ExternalRef.LicenseExplanation",
OldValue: oldLicense.ExternalRef.Data().LicenseExplanation,
UpdatedValue: newLicense.ExternalRef.Data().LicenseExplanation,
})
}
if (oldLicense.ExternalRef.Data().LicenseSuffix == nil && newLicense.ExternalRef.Data().LicenseSuffix != nil) ||
(oldLicense.ExternalRef.Data().LicenseSuffix != nil && newLicense.ExternalRef.Data().LicenseSuffix == nil) ||
((oldLicense.ExternalRef.Data().LicenseSuffix != nil && newLicense.ExternalRef.Data().LicenseSuffix != nil) && (*oldLicense.ExternalRef.Data().LicenseSuffix != *newLicense.ExternalRef.Data().LicenseSuffix)) {
changes = append(changes, models.ChangeLog{
Field: "ExternalRef.LicenseSuffix",
OldValue: oldLicense.ExternalRef.Data().LicenseSuffix,
UpdatedValue: newLicense.ExternalRef.Data().LicenseSuffix,
})
}
if (oldLicense.ExternalRef.Data().LicenseVersion == nil && newLicense.ExternalRef.Data().LicenseVersion != nil) ||
(oldLicense.ExternalRef.Data().LicenseVersion != nil && newLicense.ExternalRef.Data().LicenseVersion == nil) ||
((oldLicense.ExternalRef.Data().LicenseVersion != nil && newLicense.ExternalRef.Data().LicenseVersion != nil) && (*oldLicense.ExternalRef.Data().LicenseVersion != *newLicense.ExternalRef.Data().LicenseVersion)) {
changes = append(changes, models.ChangeLog{
Field: "ExternalRef.LicenseVersion",
OldValue: oldLicense.ExternalRef.Data().LicenseVersion,
UpdatedValue: newLicense.ExternalRef.Data().LicenseVersion,
})

oldLicenseExternalRef := oldLicense.ExternalRef.Data()
oldExternalRefVal := reflect.ValueOf(oldLicenseExternalRef)
typesOf := oldExternalRefVal.Type()

newLicenseExternalRef := newLicense.ExternalRef.Data()
newExternalRefVal := reflect.ValueOf(newLicenseExternalRef)

for i := 0; i < oldExternalRefVal.NumField(); i++ {
fieldName := typesOf.Field(i).Name

switch typesOf.Field(i).Type.String() {
case "*boolean":
oldFieldPtr, _ := oldExternalRefVal.Field(i).Interface().(*bool)
newFieldPtr, _ := newExternalRefVal.Field(i).Interface().(*bool)
if (oldFieldPtr == nil && newFieldPtr != nil) || (oldFieldPtr != nil && newFieldPtr == nil) ||
((oldFieldPtr != nil && newFieldPtr != nil) && (*oldFieldPtr != *newFieldPtr)) {
var oldVal, newVal *string
oldVal, newVal = nil, nil

if oldFieldPtr != nil {
_oldVal := fmt.Sprintf("%t", *oldFieldPtr)
oldVal = &_oldVal
}

if newFieldPtr != nil {
_newVal := fmt.Sprintf("%t", *newFieldPtr)
newVal = &_newVal
}

changes = append(changes, models.ChangeLog{
Field: fmt.Sprintf("ExternalRef.%s", fieldName),
OldValue: oldVal,
UpdatedValue: newVal,
})
}
case "*string":
oldFieldPtr, _ := oldExternalRefVal.Field(i).Interface().(*string)
newFieldPtr, _ := newExternalRefVal.Field(i).Interface().(*string)
if (oldFieldPtr == nil && newFieldPtr != nil) || (oldFieldPtr != nil && newFieldPtr == nil) ||
((oldFieldPtr != nil && newFieldPtr != nil) && (*oldFieldPtr != *newFieldPtr)) {
changes = append(changes, models.ChangeLog{
Field: fmt.Sprintf("ExternalRef.%s", fieldName),
OldValue: oldFieldPtr,
UpdatedValue: newFieldPtr,
})
}
case "*int":
oldFieldPtr, _ := oldExternalRefVal.Field(i).Interface().(*int)
newFieldPtr, _ := newExternalRefVal.Field(i).Interface().(*int)
if (oldFieldPtr == nil && newFieldPtr != nil) || (oldFieldPtr != nil && newFieldPtr == nil) ||
((oldFieldPtr != nil && newFieldPtr != nil) && (*oldFieldPtr != *newFieldPtr)) {
var oldVal, newVal *string
oldVal, newVal = nil, nil

if oldFieldPtr != nil {
_oldVal := fmt.Sprintf("%d", *oldFieldPtr)
oldVal = &_oldVal
}

if newFieldPtr != nil {
_newVal := fmt.Sprintf("%d", *newFieldPtr)
newVal = &_newVal
}

changes = append(changes, models.ChangeLog{
Field: fmt.Sprintf("ExternalRef.%s", fieldName),
OldValue: oldVal,
UpdatedValue: newVal,
})
}
}
}

if len(changes) != 0 {
Expand Down
13 changes: 0 additions & 13 deletions pkg/models/external_ref_structs.go

This file was deleted.

0 comments on commit bfded19

Please sign in to comment.