Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Build
run: go build ./...

- name: Lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.11.3

- name: Test
run: go test -race -coverprofile=coverage.out ./...
16 changes: 11 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func initConfig() {
if err != nil {
klog.Exitf("failed to download config: %s", err.Error())
}
defer os.Remove(cfgFile)
defer func() { _ = os.Remove(cfgFile) }()
}

// Read config
Expand Down Expand Up @@ -206,14 +206,14 @@ func downloadConfig(cfgURL string) (string, error) {
if err != nil {
return "", &errors.StatusError{}
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()

size, err := io.Copy(file, resp.Body)
if err != nil {
return "", err
}

defer file.Close()
defer func() { _ = file.Close() }()

tmpConfig := file.Name()
klog.V(2).Infof("downloaded config file %s with size %d", tmpConfig, size)
Expand Down Expand Up @@ -249,7 +249,7 @@ var findCmd = &cobra.Command{
kubeContext := viper.GetString("context")

format := viper.GetString("format")
if !(format == output.TableFormat || format == output.JSONFormat) {
if format != output.TableFormat && format != output.JSONFormat {
klog.Exitf("--format flag value is not valid. Run `nova find --help` to see flag options")
}

Expand Down Expand Up @@ -383,11 +383,17 @@ func handleHelm(kubeContext string) (*output.Output, error) {

if viper.GetBool("poll-artifacthub") {
ahClient, err := nova_helm.NewArtifactHubCachedPackageClient(version)
if err != nil {
return nil, fmt.Errorf("error setting up artifact hub client: %v", err)
}
helmClient, err := nova_helm.NewHelmRepoHubCachedPackageClient(version)
if err != nil {
return nil, fmt.Errorf("error setting up artifact hub client: %s", err)
return nil, fmt.Errorf("error setting up helm repo hub client: %v", err)
}
packages, err := ahClient.List()
if err != nil {
return nil, fmt.Errorf("error listing artifacthub packages: %v", err)
}
helmRepos, err := helmClient.ListRepo()
if err != nil {
return nil, fmt.Errorf("error getting artifacthub package repos: %v", err)
Expand Down
14 changes: 0 additions & 14 deletions pkg/containers/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package containers

import (
"context"
"encoding/json"
"reflect"
"testing"
Expand Down Expand Up @@ -379,16 +378,3 @@ func TestPreReleaseRegex(t *testing.T) {
}
}

func setupKubeObjects(t *testing.T, c *Client) {
_, err := c.Kube.Client.CoreV1().Pods(testNamespace).Create(context.TODO(), testPodSpec, metav1.CreateOptions{})
if err != nil {
t.Errorf("Error creating pod: %v", err)
}
}

func teardownKubeObjects(t *testing.T, c *Client) {
err := c.Kube.Client.CoreV1().Pods(testNamespace).Delete(context.TODO(), testPodName, metav1.DeleteOptions{})
if err != nil {
t.Errorf("Error deleting pod: %v", err)
}
}
8 changes: 3 additions & 5 deletions pkg/helm/artifacthub.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,7 @@ func (ac *ArtifactHubPackageClient) SearchPackages(searchTerm string) ([]Artifac
klog.V(5).Infof("found %d packages matching '%s'", totalCount, searchTerm)

ret := make([]ArtifactHubPackageSearch, totalCount)
for i, p := range firstSet.Packages {
ret[i] = p
}
copy(ret, firstSet.Packages)
if totalCount > maxArtifactHubRequestLimit {
wg := sync.WaitGroup{}
for i := maxArtifactHubRequestLimit; i < totalCount; i += maxArtifactHubRequestLimit {
Expand Down Expand Up @@ -286,7 +284,7 @@ func (ac *ArtifactHubPackageClient) Search(searchTerm string, offset int) (ret A
}
}
if resp.StatusCode == http.StatusOK {
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
err := json.NewDecoder(resp.Body).Decode(&ret)
if err != nil {
klog.V(3).Infof("error decoding search json with search term '%s': %s", searchTerm, err)
Expand Down Expand Up @@ -336,7 +334,7 @@ func (ac *ArtifactHubPackageClient) getSpecific(path string) (ret ArtifactHubPac
}
}
if resp.StatusCode == http.StatusOK {
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
err := json.NewDecoder(resp.Body).Decode(&ret.Package)
if err != nil {
klog.V(3).Infof("error decoding response for path %s:\n%v", path, err)
Expand Down
1 change: 1 addition & 0 deletions pkg/helm/findscore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ var ahubPackage = ArtifactHubHelmPackage{
var helmRelease = &release.Release{
Name: "test",
Namespace: "test",
Info: &release.Info{},
Chart: &chart.Chart{
Metadata: &chart.Metadata{
Name: "test",
Expand Down
2 changes: 0 additions & 2 deletions pkg/helm/helm_repo_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ const (
helmExporterAPIRoot = "https://artifacthub.io/api/v1/helm-exporter"
)

var helmRepocacheFile = ""

// ArtifactHubCachedPackageClient provides the various pieces to interact with the ArtifactHubCached API.
type ArtifactHelmCachedPackageClient struct {
APIRoot string
Expand Down
4 changes: 2 additions & 2 deletions pkg/output/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ func TestFileOutput_Send(t *testing.T) {
assert.Nil(t, existsErr)

if existsErr == nil {
os.Remove(path)
_ = os.Remove(path)
}

_, existsCSVErr := os.Stat(pathcsv)
assert.Nil(t, existsCSVErr)

if existsErr == nil {
os.Remove(pathcsv)
_ = os.Remove(pathcsv)
}

}
40 changes: 20 additions & 20 deletions pkg/output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ func (output Output) ToFile(filename string) error {
}
case ".csv":
file, err := os.Create(filename)
defer file.Close()
if err != nil {
return err
}
defer func() { _ = file.Close() }()
w := csv.NewWriter(file)
defer w.Flush()
header := []string{"Release Name", "Chart Name", "Namespace", "HelmVersion", "Installed", "Latest", "Old", "Deprecated"}
Expand All @@ -156,9 +156,9 @@ func (output Output) ToFile(filename string) error {
row := []string{rl.ReleaseName, rl.ChartName, rl.Namespace, rl.HelmVersion, rl.Installed.Version, rl.Latest.Version, strconv.FormatBool(rl.IsOld), strconv.FormatBool(rl.Deprecated)}
data = append(data, row)
}
w.WriteAll(data)
_ = w.WriteAll(data)
default:
return errors.New("File format is not supported. The supported file format are json and csv only")
return errors.New("file format is not supported. The supported file format are json and csv only")
}
return nil
}
Expand All @@ -172,21 +172,21 @@ func (output Output) Print(format string, wide, showOld bool) {
switch format {
case JSONFormat:
data, _ := marshalWithoutHTMLEscaping(output.HelmReleases)
fmt.Fprintln(os.Stdout, string(data))
_, _ = fmt.Fprintln(os.Stdout, string(data))
case TableFormat:
w := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
header := "Release Name\t"
if wide {
header += "Chart Name\tNamespace\tHelmVersion\t"
}
header += "Installed\tLatest\tOld\tDeprecated"
fmt.Fprintln(w, header)
_, _ = fmt.Fprintln(w, header)
separator := "============\t"
if wide {
separator += "==========\t=========\t===========\t"
}
separator += "=========\t======\t===\t=========="
fmt.Fprintln(w, separator)
_, _ = fmt.Fprintln(w, separator)

for _, release := range output.HelmReleases {
if (!output.IncludeAll && release.Latest.Version == "") || (showOld && !release.IsOld) {
Expand All @@ -202,9 +202,9 @@ func (output Output) Print(format string, wide, showOld bool) {
line += release.Latest.Version + "\t"
line += fmt.Sprintf("%t", release.IsOld) + "\t"
line += fmt.Sprintf("%t", release.Deprecated) + "\t"
fmt.Fprintln(w, line)
_, _ = fmt.Fprintln(w, line)
}
w.Flush()
_ = w.Flush()
default:
klog.Errorf("Output format is not supported. The supported formats are json and table only")
}
Expand Down Expand Up @@ -289,14 +289,14 @@ func (output ContainersOutput) Print(format string) {
switch format {
case JSONFormat:
data, _ := marshalWithoutHTMLEscaping(output)
fmt.Fprintln(os.Stdout, string(data))
_, _ = fmt.Fprintln(os.Stdout, string(data))
case TableFormat:
w := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
if len(output.ContainerImages) != 0 {
header := "Container Name\tCurrent Version\tOld\tLatest\tLatest Minor\tLatest Patch"
fmt.Fprintln(w, header)
_, _ = fmt.Fprintln(w, header)
separator := "==============\t===============\t===\t======\t=============\t============="
fmt.Fprintln(w, separator)
_, _ = fmt.Fprintln(w, separator)

for _, c := range output.ContainerImages {
if !output.IncludeAll && c.LatestVersion == c.CurrentVersion {
Expand All @@ -308,25 +308,25 @@ func (output ContainersOutput) Print(format string) {
line += c.LatestVersion + "\t"
line += c.LatestMinorVersion + "\t"
line += c.LatestPatchVersion + "\t"
fmt.Fprintln(w, line)
_, _ = fmt.Fprintln(w, line)
}
}

if len(output.ErrImages) == 0 {
w.Flush()
_ = w.Flush()
return
}
fmt.Fprintln(w, "\n\nErrors:")
_, _ = fmt.Fprintln(w, "\n\nErrors:")
errHeader := "Container Name\tError"
fmt.Fprintln(w, errHeader)
_, _ = fmt.Fprintln(w, errHeader)
errSeparator := "==============\t====="
fmt.Fprintln(w, errSeparator)
_, _ = fmt.Fprintln(w, errSeparator)
for _, e := range output.ErrImages {
line := e.Image + "\t"
line += e.Err + "\t"
fmt.Fprintln(w, line)
_, _ = fmt.Fprintln(w, line)
}
w.Flush()
_ = w.Flush()
if output.LatestStringFound {
fmt.Printf("Found a container utilizing the 'latest' tag. This is bad practice and should be avoided.\n\n")
}
Expand Down Expand Up @@ -376,7 +376,7 @@ func (output HelmAndContainersOutput) Print(format string, wide, showOld bool) {
IncludeAll: output.Helm.IncludeAll,
}
data, _ := marshalWithoutHTMLEscaping(outputFormat)
fmt.Fprintln(os.Stdout, string(data))
_, _ = fmt.Fprintln(os.Stdout, string(data))
}
}

Expand Down Expand Up @@ -408,7 +408,7 @@ func (output HelmAndContainersOutput) ToFile(filename string) error {
klog.Errorf("Error writing to file %s: %v", filename, err)
}
default:
return errors.New("File format is not supported. The supported file format is json only")
return errors.New("file format is not supported. The supported file format is json only")
}
return nil
}
Expand Down
Loading