Skip to content

Commit

Permalink
Closes #11: Add update Maven Group repository feature (#16)
Browse files Browse the repository at this point in the history
* Closes #11: Add update Maven Group repository feature

Signed-off-by: Ricardo Zanini <[email protected]>

* Increasing code coverage on MavenGroupService

Signed-off-by: Ricardo Zanini <[email protected]>

* Reconfiguring codecov to use actions and lower threshold :D

Signed-off-by: Ricardo Zanini <[email protected]>

* Fixing codecov flag

Signed-off-by: Ricardo Zanini <[email protected]>

* Testing codecov threshold

Signed-off-by: Ricardo Zanini <[email protected]>

* Fixing renaming and error coverage branch
  • Loading branch information
ricardozanini authored Jul 22, 2020
1 parent 9ef6a23 commit e84c204
Show file tree
Hide file tree
Showing 11 changed files with 358 additions and 141 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/integration-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,16 @@ jobs:
- name: Run Unit Tests
run: go test ./nexus/... -count=1 -coverprofile=coverage.txt -covermode=atomic

- name: Validate codecov yaml file
run: curl -vvv --data-binary @codecov.yml https://codecov.io/validate

- name: Send Coverage Report
run: bash <(curl -s https://codecov.io/bash) -F aicura
uses: codecov/codecov-action@v1
with:
file: ./coverage.txt
flags: aicura
name: aicura-test
fail_ci_if_error: true

integration_test:
name: Integration Tests
Expand Down
2 changes: 1 addition & 1 deletion codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ coverage:
project:
aicura:
target: auto
threshold: 3%
threshold: 5%
flags:
- aicura
6 changes: 5 additions & 1 deletion nexus/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type Client struct {

UserService *UserService
MavenProxyRepositoryService *MavenProxyRepositoryService
MavenGroupRepositoryService *MavenGroupRepositoryService
mavenRepositoryService *mavenRepositoryService
}

// ClientBuilder fluent API to build a new Nexus Client
Expand Down Expand Up @@ -93,6 +95,7 @@ func (b *ClientBuilder) Build() *Client {
if b.logger == nil {
b.logger = getLogger(false)
}
b.shared.logger = b.logger
return b.Client
}

Expand All @@ -107,11 +110,12 @@ func NewClient(baseURL string) *ClientBuilder {
c.baseURL = serverURL.ResolveReference(&url.URL{Path: apiPath})
c.apiVersion = defaultNewAPIVersion
c.shared.client = c
c.shared.logger = c.logger

// services builder
c.UserService = (*UserService)(&c.shared)
c.MavenProxyRepositoryService = (*MavenProxyRepositoryService)(&c.shared)
c.MavenGroupRepositoryService = (*MavenGroupRepositoryService)(&c.shared)
c.mavenRepositoryService = (*mavenRepositoryService)(&c.shared)

return &ClientBuilder{c}
}
Expand Down
25 changes: 16 additions & 9 deletions nexus/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ import (
)

const (
repositoriesPath = "/repositories"
repositoryFormatMaven2 = "maven2"
repositoriesPath = "/repositories"
)

// Repository is the base structure for Nexus repositories
type Repository struct {
Name string `json:"name,omitempty"`
Format *string `json:"format,omitempty"`
Type *RepositoryType `json:"type,omitempty"`
URL *string `json:"url,omitempty"`
Online *bool `json:"online,omitempty"`
Name string `json:"name,omitempty"`
Format *RepositoryFormat `json:"format,omitempty"`
Type *RepositoryType `json:"type,omitempty"`
URL *string `json:"url,omitempty"`
Online *bool `json:"online,omitempty"`
}

// Storage ...
Expand Down Expand Up @@ -76,15 +75,23 @@ const (
RepositoryTypeGroup RepositoryType = "group"
)

func filterRepositoryJSONByFormat(jsonRepos json.RawMessage, format string) ([]byte, error) {
// RepositoryFormat describes supported API repositories format
type RepositoryFormat string

const (
// RepositoryFormatMaven2 ...
RepositoryFormatMaven2 RepositoryFormat = "maven2"
)

func filterRepository(jsonRepos json.RawMessage, format RepositoryFormat, repoType RepositoryType) ([]byte, error) {
// converts into a generic Go type (the JsonPath parser does not work with raw/bytes/string types)
jsonData := interface{}(nil)
if err := json.Unmarshal(jsonRepos, &jsonData); err != nil {
return nil, err
}
builder := gval.Full(jsonpath.PlaceholderExtension())
// filter using JsonPath only the repositories that we are interested to
path, err := builder.NewEvaluable(fmt.Sprintf(`$..[?(@.format == "%s")]`, format))
path, err := builder.NewEvaluable(fmt.Sprintf(`$..[?(@.format == "%s" && @.type == "%s")]`, format, repoType))
if err != nil {
return nil, err
}
Expand Down
70 changes: 20 additions & 50 deletions nexus/repositories_maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@

package nexus

import (
"context"
"encoding/json"

"golang.org/x/sync/errgroup"
)
import "encoding/json"

const repositoriesMavenProxyPath = "/repositories/maven/proxy"

Expand Down Expand Up @@ -91,62 +86,37 @@ type MavenProxyRepository struct {
RoutingRule string `json:"routingRule,omitempty"`
}

// MavenProxyRepositoryService service to handle all Maven Proxy Repositories operations
type MavenProxyRepositoryService service
// MavenGroupRepository structure for Maven Group Repository
type MavenGroupRepository struct {
Repository `json:",inline"`
Group MavenGroup `json:"group"`
Storage Storage `json:"storage,omitempty"`
}

// Add adds new Proxy Maven repositories to the Nexus Server
func (m *MavenProxyRepositoryService) Add(repositories ...MavenProxyRepository) error {
if len(repositories) == 0 {
m.logger.Warnf("Called AddRepository with no repositories to add")
return nil
}
errs, _ := errgroup.WithContext(context.Background())
for _, repo := range repositories {
errs.Go(func() error {
req, err := m.client.post(m.client.appendVersion(repositoriesMavenProxyPath), "", repo)
if err != nil {
return err
}
_, err = m.client.do(req, nil)
return err
})
}
return errs.Wait()
// MavenGroup describes a collection of Maven repositories in a given group
type MavenGroup struct {
MemberNames []string `json:"memberNames"`
}

// List lists all maven repositories from the Nexus Server
func (m *MavenProxyRepositoryService) List() ([]MavenProxyRepository, error) {
type mavenRepositoryService service

func (m *mavenRepositoryService) list(repoType RepositoryType, unmarshalValue interface{}) error {
req, err := m.client.get(m.client.appendVersion(repositoriesPath), "")
if err != nil {
return nil, err
return err
}
var jsonRepos json.RawMessage
_, err = m.client.do(req, &jsonRepos)
if err != nil {
return nil, err
return err
}
filtered, err := filterRepositoryJSONByFormat(jsonRepos, repositoryFormatMaven2)
filtered, err := filterRepository(jsonRepos, RepositoryFormatMaven2, repoType)
if err != nil {
return nil, err
return err
}
if filtered != nil {
repositories := []MavenProxyRepository{}
err = json.Unmarshal(filtered, &repositories)
return repositories, err
}
return nil, nil
}

// GetRepoByName gets the repository by name or nil if not found
func (m *MavenProxyRepositoryService) GetRepoByName(name string) (*MavenProxyRepository, error) {
repos, err := m.List()
if err != nil {
return nil, err
}
for _, repo := range repos {
if repo.Name == name {
return &repo, nil
}
err = json.Unmarshal(filtered, unmarshalValue)
return err
}
return nil, nil
return nil
}
54 changes: 54 additions & 0 deletions nexus/repositories_maven_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2020 Aicura Nexus Client and/or its authors
//
// This file is part of Aicura Nexus Client.
//
// Aicura Nexus Client is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Aicura Nexus Client is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Aicura Nexus Client. If not, see <https://www.gnu.org/licenses/>.

package nexus

import "fmt"

// MavenGroupRepositoryService service to handle all Maven Proxy Repositories operations
type MavenGroupRepositoryService service

// Update updates a given Maven Group repository
func (m *MavenGroupRepositoryService) Update(repo MavenGroupRepository) error {
req, err := m.client.put(m.client.appendVersion(fmt.Sprintf("/repositories/maven/group/%s", repo.Name)), "", repo)
if err != nil {
return err
}
_, err = m.client.do(req, nil)
return err
}

// List lists all maven repositories from the Nexus Server
func (m *MavenGroupRepositoryService) List() ([]MavenGroupRepository, error) {
repositories := []MavenGroupRepository{}
err := m.client.mavenRepositoryService.list(RepositoryTypeGroup, &repositories)
return repositories, err
}

// GetRepoByName gets the repository by name or nil if not found
func (m *MavenGroupRepositoryService) GetRepoByName(name string) (*MavenGroupRepository, error) {
repos, err := m.List()
if err != nil {
return nil, err
}
for _, repo := range repos {
if repo.Name == name {
return &repo, nil
}
}
return nil, nil
}
66 changes: 66 additions & 0 deletions nexus/repositories_maven_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2020 Aicura Nexus Client and/or its authors
//
// This file is part of Aicura Nexus Client.
//
// Aicura Nexus Client is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Aicura Nexus Client is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Aicura Nexus Client. If not, see <https://www.gnu.org/licenses/>.

package nexus

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMavenGroupRepositoryService_Update(t *testing.T) {
s := newServerWrapper(t).WithResponse(allRepositoriesMockData).Build()
defer s.teardown()

repos, err := s.Client().MavenGroupRepositoryService.List()
assert.NoError(t, err)
assert.NotEmpty(t, repos)

if len(repos) > 0 { //sanity check to not panic
s = newServerWrapper(t).Build()
apacheMavenRepoMockData.Name = apacheMavenRepoMockData.Name + "3"
err := s.Client().MavenProxyRepositoryService.Add(apacheMavenRepoMockData)
assert.NoError(t, err)

repos[0].Group.MemberNames = append(repos[0].Group.MemberNames, apacheMavenRepoMockData.Name)
err = s.Client().MavenGroupRepositoryService.Update(repos[0])
assert.NoError(t, err)
}
}

func TestMavenGroupRepositoryService_List(t *testing.T) {
s := newServerWrapper(t).WithResponse(allRepositoriesMockData).Build()
defer s.teardown()
repos, err := s.Client().MavenGroupRepositoryService.List()
assert.NoError(t, err)
assert.NotEmpty(t, repos)
for _, repo := range repos {
if repo.Name == "maven-public" {
assert.Equal(t, RepositoryTypeGroup, *repo.Type)
}
}
}

func TestMavenGroupRepositoryService_GetByName(t *testing.T) {
s := newServerWrapper(t).WithResponse(allRepositoriesMockData).Build()
defer s.teardown()
repo, err := s.Client().MavenGroupRepositoryService.GetRepoByName("maven-public")
assert.NoError(t, err)
assert.Equal(t, "maven-public", repo.Name)
assert.Equal(t, RepositoryTypeGroup, *repo.Type)
}
68 changes: 68 additions & 0 deletions nexus/repositories_maven_proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2020 Aicura Nexus Client and/or its authors
//
// This file is part of Aicura Nexus Client.
//
// Aicura Nexus Client is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Aicura Nexus Client is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Aicura Nexus Client. If not, see <https://www.gnu.org/licenses/>.

package nexus

import (
"context"

"golang.org/x/sync/errgroup"
)

// MavenProxyRepositoryService service to handle all Maven Proxy Repositories operations
type MavenProxyRepositoryService service

// Add adds new Proxy Maven repositories to the Nexus Server
func (m *MavenProxyRepositoryService) Add(repositories ...MavenProxyRepository) error {
if len(repositories) == 0 {
m.logger.Warnf("Called AddRepository with no repositories to add")
return nil
}
errs, _ := errgroup.WithContext(context.Background())
for _, repo := range repositories {
errs.Go(func() error {
req, err := m.client.post(m.client.appendVersion(repositoriesMavenProxyPath), "", repo)
if err != nil {
return err
}
_, err = m.client.do(req, nil)
return err
})
}
return errs.Wait()
}

// List lists all maven repositories from the Nexus Server
func (m *MavenProxyRepositoryService) List() ([]MavenProxyRepository, error) {
repositories := []MavenProxyRepository{}
err := m.client.mavenRepositoryService.list(RepositoryTypeProxy, &repositories)
return repositories, err
}

// GetRepoByName gets the repository by name or nil if not found
func (m *MavenProxyRepositoryService) GetRepoByName(name string) (*MavenProxyRepository, error) {
repos, err := m.List()
if err != nil {
return nil, err
}
for _, repo := range repos {
if repo.Name == name {
return &repo, nil
}
}
return nil, nil
}
Loading

0 comments on commit e84c204

Please sign in to comment.