Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement individual upload/download from both artifactory and github. #7

Merged
merged 2 commits into from
Mar 2, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/ghDownload.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var ghDownloadCmd = &cobra.Command{
Short: "Downloads assets from Github",
Long: `This command can be used to download assets from Github.`,
Run: func(cmd *cobra.Command, args []string) {
gh.DownloadAssets(ReadGithubConfiguration(), false)
gh.DownloadAssets(ReadGithubConfiguration(), ".", false, "")
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var rootCmd = &cobra.Command{
Short: "Application to retrieve artifacts from github.",
Long: `This application by default retrieves zap artifacts, with the right arguments, it can be used to retrieve assets from any public github repo.`,
Run: func(cmd *cobra.Command, args []string) {
gh.DefaultAction(ReadGithubConfiguration())
gh.DefaultAction(ReadGithubConfiguration(), ReadArtifactoryConfiguration())
},
}

Expand Down
27 changes: 27 additions & 0 deletions cmd/rtDelete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copyright © 2024 Silicon Labs
*/
package cmd

import (
"silabs/get-zap/jf"

"github.com/spf13/cobra"
)

var rtDeleteCmd = &cobra.Command{
Use: "delete",
Short: "Deletes a file on artifactory",
Long: `Performs a file delete of a given pattern.`,
Run: func(cmd *cobra.Command, args []string) {
file, err := cmd.Flags().GetString("file")
cobra.CheckErr(err)
jf.ArtifactoryDelete(ReadArtifactoryConfiguration(), file)
},
}

func init() {
rtCmd.AddCommand(rtDeleteCmd)
rtDeleteCmd.Flags().StringP("file", "f", "", "File to upload")
rtDeleteCmd.MarkFlagRequired("file")
}
6 changes: 5 additions & 1 deletion cmd/rtDownload.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ var rtDownloadCmd = &cobra.Command{
Short: "Downloads a file from Artifactory",
Long: `Performs a download of one or more files from Artifactory.`,
Run: func(cmd *cobra.Command, args []string) {
jf.ArtifactoryDownload(ReadArtifactoryConfiguration())
file, err := cmd.Flags().GetString("file")
cobra.CheckErr(err)
jf.ArtifactoryDownload(ReadArtifactoryConfiguration(), file)
},
}

func init() {
rtCmd.AddCommand(rtDownloadCmd)
rtDownloadCmd.Flags().StringP("file", "f", "", "File to upload")
rtDownloadCmd.MarkFlagRequired("file")
}
8 changes: 6 additions & 2 deletions cmd/rtUpload.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Copyright © 2024 Silicon Labs
package cmd

import (
"fmt"
"silabs/get-zap/jf"

"github.com/spf13/cobra"
)
Expand All @@ -14,10 +14,14 @@ var rtUploadCmd = &cobra.Command{
Short: "Uploads a file to artifactory",
Long: `Performs an upload of specified files to artifactory.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("upload called")
file, err := cmd.Flags().GetString("file")
cobra.CheckErr(err)
jf.ArtifactoryUpload(ReadArtifactoryConfiguration(), file)
},
}

func init() {
rtCmd.AddCommand(rtUploadCmd)
rtUploadCmd.Flags().StringP("file", "f", "", "File to upload")
rtUploadCmd.MarkFlagRequired("file")
}
78 changes: 73 additions & 5 deletions gh/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ Copyright © 2024 Silicon Labs
package gh

import (
"context"
"crypto/tls"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"

"github.com/google/go-github/github"
"github.com/spf13/cobra"
)

type DownloadOptions struct {
Expand Down Expand Up @@ -52,9 +56,73 @@ func DefaultSecurityOptions() *DownloadOptions {
return &s
}

// If local only is true, then only assets matching the local platform will be downloaded
func DownloadAssets(cfg *GithubConfiguration, destinationDirectory string, localOnly bool, suffixOnly string) {

client := CreateGithubClient(cfg)
var release *github.RepositoryRelease
// Get latest release
if cfg.Release == "latest" {
r, _, err := client.Repositories.GetLatestRelease(context.Background(), cfg.Owner, cfg.Repo)
cobra.CheckErr(err)
release = r
} else if cfg.Release == "all" {
fmt.Println("Downloading assets for all releases is not supported. Please use 'latest' or specific release.")
return
} else {
release = findRelease(client, cfg.Owner, cfg.Repo, cfg.Release)
if release == nil {
fmt.Printf("Could not find release '%v'\n", cfg.Release)
return
}
}
fmt.Printf("Downloading assets for release '%v' of repo '%v/%v':\n", release.GetTagName(), cfg.Owner, cfg.Repo)
printRelease(client, cfg.Owner, cfg.Repo, release)
assets, _, err := client.Repositories.ListReleaseAssets(context.Background(), cfg.Owner, cfg.Repo, release.GetID(), &github.ListOptions{})
cobra.CheckErr(err)
for _, asset := range assets {

if localOnly {
assetOs, assetArch := DetermineAssetPlatform(asset.GetName())
if !IsLocalAsset(assetOs, assetArch) {
fmt.Printf("Skipping asset '%v' [os='%v', arch='%v'] as it does not match the local platform.\n", asset.GetName(), assetOs, assetArch)
continue
}
}

if suffixOnly != "" && !strings.HasSuffix(asset.GetName(), suffixOnly) {
fmt.Printf("Skipping asset '%v' as it does not have the suffix '%v'.\n", asset.GetName(), suffixOnly)
continue
}

rc, redirect, err := client.Repositories.DownloadReleaseAsset(context.Background(), cfg.Owner, cfg.Repo, asset.GetID())
cobra.CheckErr(err)
err = os.MkdirAll(release.GetName(), 0775)
cobra.CheckErr(err)
if rc != nil {
err = downloadFileFromReadCloser(rc, release.GetName(), asset.GetName())
cobra.CheckErr(err)
} else {
err = downloadFileFromUrl(redirect, release.GetName(), asset.GetName(), DefaultSecurityOptions())
cobra.CheckErr(err)
}
}
}

func downloadFileFromReadCloser(rc io.ReadCloser, destinationDirectory string, destinationPath string) error {
defer rc.Close()
output, err := os.Create(destinationDirectory + "/" + destinationPath)
if err != nil {
return err
}
defer output.Close()
_, err = io.Copy(output, rc)
return err
}

// This function downloads a file from a given URL and puts it into the
// destination path.
func DownloadFileFromUrl(urlAsString string, destinationPath string, sec *DownloadOptions) error {
func downloadFileFromUrl(urlAsString string, destinationDirectory string, destinationPath string, sec *DownloadOptions) error {

tlsConfig := &tls.Config{}
if sec.skipCertCheck {
Expand All @@ -76,7 +144,7 @@ func DownloadFileFromUrl(urlAsString string, destinationPath string, sec *Downlo
}

if !sec.allowHttp && u.Scheme == "http" {
return fmt.Errorf("Only secure encrypted HTTPS protocol is allowed. Downloads via HTTP are blocked: %v", urlAsString)
return fmt.Errorf("only secure encrypted HTTPS protocol is allowed, downloads via HTTP are blocked: %v", urlAsString)
}

// Security alert: Let's do an actual get now
Expand All @@ -85,15 +153,15 @@ func DownloadFileFromUrl(urlAsString string, destinationPath string, sec *Downlo
return err
}
if response.StatusCode != http.StatusOK {
return errors.New(fmt.Sprintf("HTTP error: %v", response.StatusCode))
return fmt.Errorf("HTTP error: %v", response.StatusCode)
}

defer response.Body.Close()

len := response.ContentLength
fmt.Printf("Downloading %v bytes to %v ...\n", len, destinationPath)

output, err := os.Create(destinationPath)
output, err := os.Create(destinationDirectory + "/" + destinationPath)
if err != nil {
return err
}
Expand Down
65 changes: 4 additions & 61 deletions gh/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ package gh
import (
"context"
"fmt"
"io"
"runtime"
"silabs/get-zap/jf"
"strings"

"github.com/google/go-github/github"
Expand Down Expand Up @@ -38,9 +38,9 @@ func CreateGithubClient(cfg *GithubConfiguration) *github.Client {
return client
}

func DefaultAction(cfg *GithubConfiguration) {
fmt.Printf("Downloading release '%v' of repo '%v/%v' for the platform '%v/%v'...\n", cfg.Release, cfg.Owner, cfg.Repo, runtime.GOOS, runtime.GOARCH)
DownloadAssets(cfg, true)
func DefaultAction(ghCfg *GithubConfiguration, rtCfg *jf.ArtifactoryConfiguration) {
fmt.Printf("Downloading release '%v' of repo '%v/%v' for the platform '%v/%v'...\n", ghCfg.Release, ghCfg.Owner, ghCfg.Repo, runtime.GOOS, runtime.GOARCH)
DownloadAssets(ghCfg, ".", true, ".zip")
}

func DetermineAssetPlatform(assetName string) (os string, arch string) {
Expand Down Expand Up @@ -74,63 +74,6 @@ func IsLocalAsset(assetOs string, assetArch string) bool {
return true
}

// If local only is true, then only assets matching the local platform will be downloaded
func DownloadAssets(cfg *GithubConfiguration, localOnly bool) {

client := CreateGithubClient(cfg)
var release *github.RepositoryRelease
// Get latest release
if cfg.Release == "latest" {
r, _, err := client.Repositories.GetLatestRelease(context.Background(), cfg.Owner, cfg.Repo)
cobra.CheckErr(err)
release = r
} else if cfg.Release == "all" {
fmt.Println("Downloading assets for all releases is not supported. Please use 'latest' or specific release.")
return
} else {
release = findRelease(client, cfg.Owner, cfg.Repo, cfg.Release)
if release == nil {
fmt.Printf("Could not find release '%v'\n", cfg.Release)
return
}
}
fmt.Printf("Downloading assets for release '%v' of repo '%v/%v':\n", release.GetTagName(), cfg.Owner, cfg.Repo)
printRelease(client, cfg.Owner, cfg.Repo, release)
assets, _, err := client.Repositories.ListReleaseAssets(context.Background(), cfg.Owner, cfg.Repo, release.GetID(), &github.ListOptions{})
cobra.CheckErr(err)
for _, asset := range assets {

if localOnly {
assetOs, assetArch := DetermineAssetPlatform(asset.GetName())
if !IsLocalAsset(assetOs, assetArch) {
fmt.Printf("Skipping asset '%v' [os='%v', arch='%v'] as it does not match the local platform.\n", asset.GetName(), assetOs, assetArch)
continue
}
}

rc, redirect, err := client.Repositories.DownloadReleaseAsset(context.Background(), cfg.Owner, cfg.Repo, asset.GetID())
cobra.CheckErr(err)
if rc != nil {
fmt.Printf("Not redirected.\n")
buff := make([]byte, 10*1024)
n, err := rc.Read(buff)
fmt.Printf("Read %d bytes\n", n)
if n > 0 {
fmt.Printf("Read %d bytes\n", n)
} else {
if err == io.EOF {
rc.Close()
fmt.Println("Eof")
} else {
cobra.CheckErr(err)
}
}
} else {
DownloadFileFromUrl(redirect, asset.GetName(), DefaultSecurityOptions())
}
}
}

func findRelease(client *github.Client, owner string, repo string, tag string) *github.RepositoryRelease {
allReleases, _, err := client.Repositories.ListReleases(context.Background(), owner, repo, &github.ListOptions{})
cobra.CheckErr(err)
Expand Down
38 changes: 31 additions & 7 deletions jf/artifactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (cfg *ArtifactoryConfiguration) IsValid() bool {

func (cfg *ArtifactoryConfiguration) CreateDetails() *auth.ServiceDetails {
if !cfg.IsValid() {
cobra.CheckErr(fmt.Errorf("Invalid artifactory configuration. You need to provide url, api key and user either via command line, environment variables, or configuration file."))
cobra.CheckErr(fmt.Errorf("invalid artifactory configuration, you need to provide url, api key and user either via command line, environment variables, or configuration file"))
}
rtDetails := rtAuth.NewArtifactoryDetails()
rtDetails.SetUrl(cfg.Url)
Expand All @@ -37,7 +37,28 @@ func (cfg *ArtifactoryConfiguration) CreateDetails() *auth.ServiceDetails {
return &rtDetails
}

func ArtifactoryDownload(cfg *ArtifactoryConfiguration) {
func ArtifactoryDelete(cfg *ArtifactoryConfiguration, pattern string) {
rtDetails := cfg.CreateDetails()

s, err := config.NewConfigBuilder().SetServiceDetails(*rtDetails).Build()
cobra.CheckErr(err)

m, err := artifactory.New(s)
cobra.CheckErr(err)

params := services.NewDeleteParams()
params.Pattern = cfg.Repo + "/" + pattern
fmt.Printf("Deleting files from %v/%v: %v\n", cfg.Url, cfg.Repo, params.Pattern)

pathsToDelete, err := m.GetPathsToDelete(params)
cobra.CheckErr(err)
defer pathsToDelete.Close()
cnt, err := m.DeleteFiles(pathsToDelete)
cobra.CheckErr(err)
fmt.Printf("Deleted files: %v\n", cnt)
}

func ArtifactoryDownload(cfg *ArtifactoryConfiguration, pattern string) {

rtDetails := cfg.CreateDetails()

Expand All @@ -48,15 +69,15 @@ func ArtifactoryDownload(cfg *ArtifactoryConfiguration) {
cobra.CheckErr(err)

params := services.NewDownloadParams()
params.Pattern = cfg.Repo + "/" + cfg.Path
fmt.Println("Downloading files from", cfg.Url, "with pattern", params.Pattern)
params.Pattern = cfg.Repo + "/" + pattern
fmt.Printf("Downloading files from %v/%v: %v\n", cfg.Url, cfg.Repo, params.Pattern)
success, failures, err := m.DownloadFiles(params)
cobra.CheckErr(err)

fmt.Printf("Download files: success %v, failure %v\n", success, failures)
fmt.Printf("Downloaded files: success %v, failure %v\n", success, failures)
}

func ArtifactoryUpload(cfg *ArtifactoryConfiguration) {
func ArtifactoryUpload(cfg *ArtifactoryConfiguration, pattern string) {
rtDetails := cfg.CreateDetails()

s, err := config.NewConfigBuilder().SetServiceDetails(*rtDetails).Build()
Expand All @@ -66,8 +87,11 @@ func ArtifactoryUpload(cfg *ArtifactoryConfiguration) {
cobra.CheckErr(err)

params := services.NewUploadParams()
params.Pattern = pattern
fmt.Printf("Uploading files to %v/%v: %v\n", cfg.Url, cfg.Repo, params.Pattern)
params.Target = cfg.Repo + "/"

success, failures, err := m.UploadFiles(params)
cobra.CheckErr(err)
fmt.Printf("Upload files: success %v, failure %v\n", success, failures)
fmt.Printf("Uploaded files: success %v, failure %v\n", success, failures)
}