Skip to content

Commit

Permalink
Merge pull request #58 from 030/gh7-uploads3
Browse files Browse the repository at this point in the history
Gh7 uploads3
  • Loading branch information
030 authored Jun 2, 2019
2 parents 1f101cc + 5b0c768 commit 41b71de
Show file tree
Hide file tree
Showing 69 changed files with 443 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
*.pom*
.vscode
maven-metadata*
download
download
39 changes: 35 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,52 @@ matrix:
include:
- os: linux
dist: bionic
env:
- ARTIFACT_PUBLICATION=false
- NEXUS_VERSION=latest
- NEXUS_API_VERSION=v1
- os: linux
dist: bionic
env:
- ARTIFACT_PUBLICATION=true
- NEXUS_VERSION=3.16.2
- NEXUS_API_VERSION=v1
- os: linux
dist: bionic
env:
- ARTIFACT_PUBLICATION=false
- NEXUS_VERSION=3.9.0
- NEXUS_API_VERSION=beta
- os: osx
env: SHA512_CMD="shasum -a 512"
env:
- ARTIFACT_PUBLICATION=true
- SHA512_CMD="shasum -a 512"
- NEXUS_VERSION=3.16.2
- NEXUS_API_VERSION=v1
- os: windows
env:
- ARTIFACT_PUBLICATION=true
- NEXUS_VERSION=3.16.2
- NEXUS_API_VERSION=v1
addons:
sonarcloud:
organization: 030-github
token:
secure: $SONAR_TOKEN
before_script:
- |
echo 'n3drPass: admin123' > ${HOME}/.n3dr.yaml
echo "NEXUS_API_VERSION=${NEXUS_API_VERSION}" > .env
script:
- diff -u <(echo -n) <(gofmt -d ./)
- export DELIVERABLE="n3dr-${TRAVIS_OS_NAME}"
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then go test -short -cover -v -coverprofile=coverage.txt -covermode=atomic ./...; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$ARTIFACT_PUBLICATION" ]; then go test -short -cover -v -coverprofile=coverage.txt -covermode=atomic ./...; fi
- go build -o $DELIVERABLE
- $SHA512_CMD $DELIVERABLE > ${DELIVERABLE}.sha512.txt
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then sonar-scanner -Dsonar.projectKey=030_n3dr -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.coverage.exclusions=cmd/**,**/*_test.go -Dsonar.go.coverage.reportPaths="coverage.txt"; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then bash <(curl -s https://codecov.io/bash); fi
- chmod +x $DELIVERABLE
- if [ $TRAVIS_OS_NAME == linux ]; then ./integration-tests.sh $NEXUS_VERSION $NEXUS_API_VERSION ./${DELIVERABLE}; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$ARTIFACT_PUBLICATION" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then sonar-scanner -Dsonar.projectKey=030_n3dr -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.coverage.exclusions=cmd/**,**/*_test.go -Dsonar.go.coverage.reportPaths="coverage.txt"; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$ARTIFACT_PUBLICATION" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then bash <(curl -s https://codecov.io/bash); fi
deploy:
provider: releases
api_key: $GITHUB_TOKEN
Expand All @@ -34,3 +64,4 @@ deploy:
skip_cleanup: true
on:
tags: true
condition: $ARTIFACT_PUBLICATION == true
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [3.1.0] - 2019-06-02
### Added
- Upload artifacts to a specific Nexus3 repository.

## [3.0.0] - 2019-05-21
### Added
- Enable debug logging.
Expand Down Expand Up @@ -82,7 +86,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Download all artifacts from a certain Nexus3 repository.

[Unreleased]: https://github.com/030/n3dr/compare/2.3.0...HEAD
[Unreleased]: https://github.com/030/n3dr/compare/3.1.0...HEAD
[3.1.0]: https://github.com/030/n3dr/compare/3.0.0...3.1.0
[3.0.0]: https://github.com/030/n3dr/compare/2.3.0...3.0.0
[2.3.0]: https://github.com/030/n3dr/compare/2.2.1...2.3.0
[2.2.1]: https://github.com/030/n3dr/compare/2.2.0...2.2.1
[2.2.0]: https://github.com/030/n3dr/compare/2.1.1...2.2.0
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# n3dr

[![GoDoc Widget]][GoDoc]
[![Build Status](https://travis-ci.org/030/n3dr.svg?branch=master)](https://travis-ci.org/030/n3dr)
[![Go Report Card](https://goreportcard.com/badge/github.com/030/n3dr)](https://goreportcard.com/report/github.com/030/n3dr)
![DevOps SE Questions](https://img.shields.io/stackexchange/devops/t/n3dr.svg)
Expand Down Expand Up @@ -158,3 +159,6 @@ There is a number of equivalent tools:

The difference is that n3dr is able to download artifacts from all Nexus3
repositories.

[GoDoc]: https://godoc.org/github.com/030/n3dr
[GoDoc Widget]: https://godoc.org/github.com/030/n3dr?status.svg
6 changes: 4 additions & 2 deletions cli/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (

const (
pingURI = "/service/metrics/ping"
assetURI = "/service/rest/v1/assets?repository="
assetURI1 = "/service/rest/"
assetURI2 = "/assets?repository="
tokenErrMsg = "Token should be either a hexadecimal or \"null\" and not: "
)

Expand All @@ -32,10 +33,11 @@ type Nexus3 struct {
User string
Pass string
Repository string
APIVersion string
}

func (n Nexus3) downloadURL(token string) ([]byte, error) {
assetURL := n.URL + assetURI + n.Repository
assetURL := n.URL + assetURI1 + n.APIVersion + assetURI2 + n.Repository
constructDownloadURL := assetURL
if !(token == "null") {
constructDownloadURL = assetURL + "&continuationToken=" + token
Expand Down
16 changes: 0 additions & 16 deletions cli/backup_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cli

import (
"os"
"reflect"
"testing"

Expand All @@ -13,21 +12,6 @@ const (
errMsgTxt = "Error incorrect. Expected: %v. Actual: %v"
)

var n = Nexus3{
URL: "http://localhost:9999",
User: "admin",
Pass: "admin123",
Repository: "maven-releases",
}

// See https://stackoverflow.com/a/34102842/2777965
func TestMain(m *testing.M) {
setup()
code := m.Run()
shutdown()
os.Exit(code)
}

func TestContinuationTokenHash(t *testing.T) {
actual, _ := n.continuationTokenRecursion("null")
actualSize := len(actual)
Expand Down
26 changes: 23 additions & 3 deletions cli/utils_test.go → cli/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,35 @@ import (
"os/exec"
"path/filepath"
"strconv"
"testing"
"time"

"github.com/030/go-utils"
log "github.com/sirupsen/logrus"

mp "github.com/030/go-curl/utils"
)

// See https://stackoverflow.com/a/34102842/2777965
func TestMain(m *testing.M) {
setup()
code := m.Run()
shutdown()
os.Exit(code)
}

const (
testFilesDir = "testFiles"
)

var n = Nexus3{
URL: "http://localhost:9999",
User: "admin",
Pass: "admin123",
Repository: "maven-releases",
APIVersion: "v1",
}

func setup() {
// Start docker nexus
cmd := exec.Command("bash", "-c", "docker run -d -p 9999:8081 --name nexus sonatype/nexus3:3.16.1")
Expand Down Expand Up @@ -96,10 +115,11 @@ func (n Nexus3) pong() bool {

func (n Nexus3) submitArtifact(d string, f string) {
path := filepath.Join(d, f)
cmd := exec.Command("bash", "-c", "curl -u "+n.User+":"+n.Pass+" -X POST \""+n.URL+"/service/rest/v1/components?repository="+n.Repository+"\" -H \"accept: application/json\" -H \"Content-Type: multipart/form-data\" -F \"maven2.asset1=@"+path+".pom\" -F \"maven2.asset1.extension=pom\" -F \"maven2.asset2=@"+path+".jar\" -F \"maven2.asset2.extension=jar\"")
stdoutStderr, err := cmd.CombinedOutput()
url := n.URL + "/service/rest/v1/components?repository=" + n.Repository
u := mp.Upload{URL: url, Username: n.User, Password: n.Pass}
err := u.MultipartUpload("maven2.asset1=@" + path + ".pom,maven2.asset1.extension=pom,maven2.asset2=@" + path + ".jar,maven2.asset2.extension=jar")
if err != nil {
log.Fatal(err, string(stdoutStderr))
log.Fatal(err)
}
}

Expand Down
4 changes: 2 additions & 2 deletions cli/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func (n Nexus3) repositories() string {
// Generated by curl-to-Go: https://mholt.github.io/curl-to-go
log.Debug("Consult repositories URL: " + n.URL)
req, err := http.NewRequest("GET", n.URL+"/service/rest/v1/repositories", nil)
req, err := http.NewRequest("GET", n.URL+"/service/rest/"+n.APIVersion+"/repositories", nil)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -64,7 +64,7 @@ func (n Nexus3) CountRepositories() {
// Downloads retrieves artifacts from all repositories
func (n Nexus3) Downloads() error {
for _, name := range n.repositoriesSlice() {
n := Nexus3{URL: n.URL, User: n.User, Pass: n.Pass, Repository: name.(string)}
n := Nexus3{URL: n.URL, User: n.User, Pass: n.Pass, Repository: name.(string), APIVersion: n.APIVersion}
err := n.StoreArtifactsOnDisk()
if err != nil {
return err
Expand Down
89 changes: 89 additions & 0 deletions cli/upload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package cli

import (
"fmt"
"os"
"path/filepath"
"strings"

mp "github.com/030/go-curl/utils"
log "github.com/sirupsen/logrus"
)

var foldersWithPOM strings.Builder

func (n Nexus3) detectFoldersWithPOM(d string) error {
err := filepath.Walk(d, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if !f.IsDir() && filepath.Ext(path) == ".pom" {
fmt.Println(path)
foldersWithPOM.WriteString(filepath.Dir(path) + ",")
}
return nil
})
if err != nil {
return err
}
return nil
}

// Upload posts an artifact as a multipart to a specific nexus3 repository
func (n Nexus3) Upload() error {
err3 := n.detectFoldersWithPOM(n.Repository)
if err3 != nil {
return err3
}

foldersWithPOMString := strings.TrimSuffix(foldersWithPOM.String(), ",")
foldersWithPOMStringSlice := strings.Split(foldersWithPOMString, ",")

for _, v := range foldersWithPOMStringSlice {
var s strings.Builder
err := filepath.Walk(v, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}

if !f.IsDir() {
if filepath.Ext(path) == ".pom" {
log.Debug("POM found " + path)
s.WriteString("maven2.asset1=@" + path + ",")
s.WriteString("maven2.asset1.extension=pom,")
}

if filepath.Ext(path) == ".jar" {
log.Debug("JAR found " + path)
s.WriteString("maven2.asset2=@" + path + ",")
s.WriteString("maven2.asset2.extension=jar,")
}

if filepath.Ext(path) == ".war" {
log.Debug("WAR found " + path)
s.WriteString("maven2.asset3=@" + path + ",")
s.WriteString("maven2.asset3.extension=war,")
}
}
return nil
})

if err != nil {
return err
}

multipartString := strings.TrimSuffix(s.String(), ",")
url := n.URL + "/service/rest/" + n.APIVersion + "/components?repository=" + n.Repository
log.WithFields(log.Fields{
"multipart": multipartString,
"url": url,
}).Debug("URL")

u := mp.Upload{URL: url, Username: n.User, Password: n.Pass}
err2 := u.MultipartUpload(multipartString)
if err2 != nil {
return err2
}
}
return nil
}
13 changes: 13 additions & 0 deletions cli/upload_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cli

import (
"testing"
)

func TestUploads(t *testing.T) {
err := n.Upload()
want := "HTTPStatusCode: '400'; ResponseMessage: 'Repository does not allow updating assets: maven-releases'; ErrorMessage: '<nil>'"
if err.Error() == want {
t.Errorf("Error expected. Got '%v'. Want '%v'", err, want)
}
}
8 changes: 3 additions & 5 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (
"github.com/spf13/viper"
)

var n3drRepo string

// backupCmd represents the backup command
var backupCmd = &cobra.Command{
Use: "backup",
Expand All @@ -35,7 +33,7 @@ reside in a certain Nexus3 repository`,
enableDebug()
},
Run: func(cmd *cobra.Command, args []string) {
n := cli.Nexus3{URL: n3drURL, User: n3drUser, Pass: viper.GetString("n3drPass"), Repository: n3drRepo}
n := cli.Nexus3{URL: n3drURL, User: n3drUser, Pass: viper.GetString("n3drPass"), Repository: n3drRepo, APIVersion: apiVersion}
err := n.StoreArtifactsOnDisk()
if err != nil {
log.Fatal(err)
Expand All @@ -44,7 +42,7 @@ reside in a certain Nexus3 repository`,
}

func init() {
backupCmd.PersistentFlags().StringVarP(&n3drRepo, "n3drRepo", "r", "", "The Nexus3 repository")
backupCmd.MarkPersistentFlagRequired("n3drRepo")
rootCmd.AddCommand(backupCmd)
backupCmd.Flags().StringVarP(&n3drRepo, "n3drRepo", "r", "", "The Nexus3 repository")
backupCmd.MarkFlagRequired("n3drRepo")
}
2 changes: 1 addition & 1 deletion cmd/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ download artifacts from all repositories`,
os.Exit(0)
}
pw := viper.GetString("n3drPass")
n := cli.Nexus3{URL: n3drURL, User: n3drUser, Pass: pw}
n := cli.Nexus3{URL: n3drURL, User: n3drUser, Pass: pw, APIVersion: apiVersion}
if names {
n.RepositoryNames()
}
Expand Down
11 changes: 7 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ import (
)

var (
cfgFile string
n3drURL string
n3drUser string
debug bool
cfgFile string
n3drURL string
n3drUser string
n3drRepo string
debug bool
apiVersion string
)

// rootCmd represents the base command when called without any subcommands
Expand Down Expand Up @@ -59,6 +61,7 @@ func init() {
rootCmd.PersistentFlags().StringP("n3drPass", "p", "", "The Nexus3 password")
rootCmd.PersistentFlags().StringVarP(&n3drURL, "n3drURL", "n", "", "The Nexus3 URL")
rootCmd.PersistentFlags().StringVarP(&n3drUser, "n3drUser", "u", "", "The Nexus3 user")
rootCmd.PersistentFlags().StringVarP(&apiVersion, "apiVersion", "v", "v1", "The Nexus3 APIVersion, e.g. v1 or beta")

rootCmd.MarkPersistentFlagRequired("n3drURL")
rootCmd.MarkPersistentFlagRequired("n3drUser")
Expand Down
Loading

0 comments on commit 41b71de

Please sign in to comment.