Compare commits

...

8 Commits

Author SHA1 Message Date
6757ac5d93 updated dependencies
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2023-03-17 13:21:04 +01:00
cf1a9cc244 replaced ioutil.ReadAll by io.ReadAll
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 17:14:46 +01:00
7ca46df26a updated ci
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2022-10-30 16:18:04 +01:00
61fac95456 updated dependencies
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-16 11:44:12 +02:00
85c47819b3 updated .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-26 12:08:54 +01:00
70203a1ae8 updated g2g handle of github api pages
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2021-12-25 16:39:32 +01:00
174289b1fe updated g2g dependencies
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2021-11-07 21:13:07 +01:00
0c587b783f removed golang version from drone-ci
All checks were successful
continuous-integration/drone/push Build is passing
2021-08-30 19:40:34 +02:00
25 changed files with 284 additions and 367 deletions

View File

@ -1,89 +1,74 @@
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
name: cleanup-before name: build-linux
steps: steps:
- name: clean - name: build-linux-amd64
image: alpine image: golang
commands: commands:
- rm -rf /build/* - go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
volumes:
- name: build
path: /build
when:
event: tag
volumes:
- name: build
host:
path: /tmp/g2g/build
---
kind: pipeline
type: docker
name: default-linux-amd64
steps:
- name: build
image: golang:1.17
commands:
- ./ci-build.sh build
environment: environment:
GOOS: linux GOOS: linux
GOARCH: amd64 GOARCH: amd64
volumes: GOOPTIONS: -mod=vendor
- name: build SRCFILES: cmd/g2g/*.go
path: /build PROJECTNAME: g2g
when:
volumes: event:
- name: build exclude:
host: - tag
path: /tmp/g2g/build - name: build-linux-arm64
image: golang
depends_on:
- cleanup-before
---
kind: pipeline
type: docker
name: default-linux-arm64
steps:
- name: build
image: golang:1.17
commands: commands:
- ./ci-build.sh build - go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
environment: environment:
GOOS: linux GOOS: linux
GOARCH: arm64 GOARCH: arm64
volumes: GOOPTIONS: -mod=vendor
- name: build SRCFILES: cmd/g2g/*.go
path: /build PROJECTNAME: g2g
when:
volumes: event:
- name: build exclude:
host: - tag
path: /tmp/g2g/build
depends_on:
- cleanup-before
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
name: gitea-release name: gitea-release-linux
steps: steps:
- name: move - name: build-linux-amd64
image: alpine image: golang
commands: commands:
- mv build/* ./ - go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
volumes: - tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
- name: build - echo $PROJECTNAME $DRONE_TAG > VERSION
path: /drone/src/build environment:
GOOS: linux
GOARCH: amd64
GOOPTIONS: -mod=vendor
SRCFILES: cmd/g2g/*.go
PROJECTNAME: g2g
when: when:
event: tag event:
- tag
- name: build-linux-arm64
image: golang
commands:
- go build -o $PROJECTNAME $GOOPTIONS $SRCFILES
- tar -czvf $PROJECTNAME-$DRONE_TAG-$GOOS-$GOARCH.tar.gz $PROJECTNAME
- echo $PROJECTNAME $DRONE_TAG > VERSION
environment:
GOOS: linux
GOARCH: arm64
GOOPTIONS: -mod=vendor
SRCFILES: cmd/g2g/*.go
PROJECTNAME: g2g
when:
event:
- tag
- name: release - name: release
image: plugins/gitea-release image: plugins/gitea-release
settings: settings:
@ -95,50 +80,6 @@ steps:
- sha256 - sha256
- sha512 - sha512
title: VERSION title: VERSION
volumes:
- name: build
path: /drone/src/build
when: when:
event: tag event:
- name: ls - tag
image: alpine
commands:
- find .
volumes:
- name: build
path: /drone/src/build
when:
event: tag
volumes:
- name: build
host:
path: /tmp/g2g/build
depends_on:
- default-linux-amd64
- default-linux-arm64
---
kind: pipeline
type: docker
name: cleanup-after
steps:
- name: clean
image: alpine
commands:
- rm -rf /build/*
volumes:
- name: build
path: /build
when:
event: tag
volumes:
- name: build
host:
path: /tmp/g2g/build
depends_on:
- gitea-release

17
.vscode/launch.json vendored
View File

@ -1,17 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"env": {},
"args": []
}
]
}

View File

@ -1,3 +0,0 @@
{
"go.formatTool": "goimports"
}

View File

@ -1,19 +0,0 @@
# g2g Makefile
GOCMD=go
GOBUILDCMD=${GOCMD} build
GOOPTIONS=-mod=vendor -ldflags="-s -w"
VERSION := $(shell cat ./VERSION)
RMCMD=rm
BINNAME=g2g
SRCFILES=cmd/g2g/*.go
all: build
build:
${GOBUILDCMD} ${GOOPTIONS} ${SRCFILES}
clean:
${RMCMD} -f ${BINNAME}

View File

@ -21,17 +21,14 @@ make
request_timeout=1200s request_timeout=1200s
threads=4 threads=4
github_stars_pages="https://api.github.com/users/%s/starred?page=%d"
github_max_per_page=500
github_page_num=3
github_auth_username="user" github_auth_username="user"
github_auth_password="pass" github_auth_password="pass"
gitea_username="user" gitea_username="user"
gitea_dest_username="user_or_org" gitea_dest_username="user_or_org"
gitea_repo_url_tmpl="https://gogs.example.com/api/v1/repos/%s/%s" gitea_repo_url_tmpl="https://git.example.com/api/v1/repos/%s/%s"
gitea_orgs_url_tmpl="https://git.paulbsd.com/api/v1/orgs/%s" gitea_orgs_url_tmpl="https://git.example.com/api/v1/orgs/%s"
gitea_migrate_url="https://gogs.example.com/api/v1/repos/migrate" gitea_migrate_url="https://git.example.com/api/v1/repos/migrate"
gitea_auth_token="token xxxx" gitea_auth_token="token xxxx"
gitea_mirror=true gitea_mirror=true
``` ```
@ -49,7 +46,7 @@ gitea_mirror=true
## License ## License
```text ```text
Copyright (c) 2020 PaulBSD Copyright (c) 2020, 2021 PaulBSD
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@ -1 +1 @@
0.9 1.0.4

View File

@ -1,62 +0,0 @@
#!/bin/bash
set -e
PROJECTNAME=g2g
RELEASENAME=${PROJECTNAME}
VERSION="0"
GOOPTIONS="-mod=vendor"
SRCFILES=cmd/g2g/*.go
build() {
echo "Begin of build"
if [[ ! -z $DRONE_TAG ]]
then
echo "Drone tag set, let's do a release"
VERSION=$DRONE_TAG
echo "${PROJECTNAME} ${VERSION}" > /build/VERSION
elif [[ ! -z $DRONE_TAG ]]
then
echo "Drone not set, let's only do a build"
VERSION=$DRONE_COMMIT
fi
if [[ ! -z $VERSION && ! -z $GOOS && ! -z $GOARCH ]]
then
echo "Let's set a release name"
RELEASENAME=${PROJECTNAME}-${VERSION}-${GOOS}-${GOARCH}
fi
echo "Building project"
go build -o ${PROJECTNAME} ${GOOPTIONS} ${SRCFILES}
if [[ ! -z $DRONE_TAG ]]
then
echo "Let's make archives"
mkdir -p /build
tar -czvf /build/${RELEASENAME}.tar.gz ${PROJECTNAME}
fi
echo "Removing binary file"
rm ${PROJECTNAME}
echo "End of build"
}
clean() {
rm -rf $RELEASEDIR
}
case $1 in
"build")
build
;;
"clean")
clean
;;
*)
echo "No options choosen"
exit 1
;;
esac

View File

@ -2,16 +2,13 @@
request_timeout=1200s request_timeout=1200s
threads=4 threads=4
github_stars_pages="https://api.github.com/users/%s/starred?page=%d"
github_max_per_page=500
github_page_num=3
github_auth_username="user" github_auth_username="user"
github_auth_password="pass" github_auth_password="pass"
gitea_username="user" gitea_username="user"
gitea_dest_username="user_or_org" gitea_dest_username="user_or_org"
gitea_repo_url_tmpl="https://gogs.example.com/api/v1/repos/%s/%s" gitea_repo_url_tmpl="https://git.example.com/api/v1/repos/%s/%s"
gitea_orgs_url_tmpl="https://gogs.example.com/api/v1/orgs/%s" gitea_orgs_url_tmpl="https://git.example.com/api/v1/orgs/%s"
gitea_migrate_url="https://gogs.example.com/api/v1/repos/migrate" gitea_migrate_url="https://git.example.com/api/v1/repos/migrate"
gitea_auth_token="token xxxx" gitea_auth_token="token xxxx"
gitea_mirror=true gitea_mirror=true

11
go.mod
View File

@ -1,10 +1,7 @@
module git.paulbsd.com/paulbsd/g2g module git.paulbsd.com/paulbsd/g2g
go 1.17 go 1.20
require ( require gopkg.in/ini.v1 v1.67.0
github.com/gopherjs/gopherjs v0.0.0-20210406100015-1e088ea4ee04 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect require github.com/stretchr/testify v1.7.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
gopkg.in/ini.v1 v1.62.0
)

29
go.sum
View File

@ -1,17 +1,12 @@
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/gopherjs/gopherjs v0.0.0-20210406100015-1e088ea4ee04 h1:Enykqupm0u6qiUZAc+SiFkMJVqt4o8knNcKJu8NdlJ0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gopherjs/gopherjs v0.0.0-20210406100015-1e088ea4ee04/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View File

@ -32,8 +32,6 @@ func (config *Config) GetConfig() error {
type Config struct { type Config struct {
G2gRequestTimeout time.Duration `ini:"g2g_request_timeout"` G2gRequestTimeout time.Duration `ini:"g2g_request_timeout"`
G2gThreads int `ini:"g2g_threads"` G2gThreads int `ini:"g2g_threads"`
GitHubMaxPerPage int `ini:"github_max_per_page"`
GitHubPageNum int `ini:"github_page_num"`
GitHubAuthUsername string `ini:"github_auth_username"` GitHubAuthUsername string `ini:"github_auth_username"`
GitHubAuthPassword string `ini:"github_auth_password"` GitHubAuthPassword string `ini:"github_auth_password"`
GitHubContentType string GitHubContentType string

View File

@ -5,7 +5,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io"
"log" "log"
"net/http" "net/http"
"sync" "sync"
@ -17,10 +17,11 @@ import (
func GetReposFromGitHub(config *config.Config) ([]GitHubRepo, error) { func GetReposFromGitHub(config *config.Config) ([]GitHubRepo, error) {
var repopartiallist []GitHubRepo var repopartiallist []GitHubRepo
var repofulllist []GitHubRepo var repofulllist []GitHubRepo
var pagenum = 1
fmt.Println("Getting GitHub starred repos") fmt.Println("Getting GitHub starred repos")
for num := 1; num <= config.GitHubPageNum; num++ { for {
url := fmt.Sprintf("https://api.github.com/users/%s/starred?per_page=%d&page=%d", config.GitHubAuthUsername, config.GitHubMaxPerPage, num) url := fmt.Sprintf("https://api.github.com/users/%s/starred?page=%d", config.GitHubAuthUsername, pagenum)
fmt.Println(url) fmt.Println(url)
resp, err := GetGitHubResponse(config, url) resp, err := GetGitHubResponse(config, url)
@ -28,7 +29,7 @@ func GetReposFromGitHub(config *config.Config) ([]GitHubRepo, error) {
return nil, err return nil, err
} }
respbody, err := ioutil.ReadAll(resp.Body) respbody, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -38,12 +39,17 @@ func GetReposFromGitHub(config *config.Config) ([]GitHubRepo, error) {
return nil, err return nil, err
} }
if len(repopartiallist) == 0 {
break
}
for _, elem := range repopartiallist { for _, elem := range repopartiallist {
repofulllist = append(repofulllist, elem) repofulllist = append(repofulllist, elem)
} }
pagenum++
} }
fmt.Println(fmt.Sprintf("%d repositories fetched from Github", len(repofulllist))) fmt.Printf("%d repositories fetched from Github\n", len(repofulllist))
return repofulllist, nil return repofulllist, nil
} }
@ -64,7 +70,7 @@ func GetGitHubResponse(config *config.Config, url string) (*http.Response, error
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Error on status code %s", resp.Status) return nil, fmt.Errorf("error on status code %s", resp.Status)
} }
return resp, nil return resp, nil
@ -77,6 +83,9 @@ func CheckGiteaExistingRepo(config *config.Config, repo GitHubRepo) (bool, error
gitearepourl := fmt.Sprintf(config.GiteaRepoURLTmpl, config.GiteaDestUsername, repo.Name) gitearepourl := fmt.Sprintf(config.GiteaRepoURLTmpl, config.GiteaDestUsername, repo.Name)
req, err := http.NewRequest("GET", gitearepourl, nil) req, err := http.NewRequest("GET", gitearepourl, nil)
if err != nil {
return false, err
}
req.Header.Set("Authorization", config.GiteaAuthToken) req.Header.Set("Authorization", config.GiteaAuthToken)
client := &http.Client{} client := &http.Client{}
@ -90,7 +99,7 @@ func CheckGiteaExistingRepo(config *config.Config, repo GitHubRepo) (bool, error
} else if resp.StatusCode == http.StatusNotFound { } else if resp.StatusCode == http.StatusNotFound {
isExists = false isExists = false
} else { } else {
return false, fmt.Errorf("Can't determine error, cancelling, error %s in gitea webservice", resp.Status) return false, fmt.Errorf("can't determine error, cancelling, error %s in gitea webservice", resp.Status)
} }
return isExists, nil return isExists, nil
@ -116,15 +125,18 @@ func GetGiteaUserUID(config *config.Config) error {
} }
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
err = errors.New("Error invoking gitea webservice") err = errors.New("error invoking gitea webservice")
return err return err
} }
respbody, err := ioutil.ReadAll(resp.Body) respbody, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(respbody, &giteaorg) err = json.Unmarshal(respbody, &giteaorg)
if err != nil { if err != nil {
err = errors.New("Failed to parse user ID from gitea webservice, check auth") err = errors.New("failed to parse user ID from gitea webservice, check auth")
return err return err
} }
@ -158,20 +170,39 @@ func MigrateReposToGitea(config *config.Config, wg *sync.WaitGroup, jobs chan Gi
for { for {
elem, more := <-jobs elem, more := <-jobs
if more { if more {
client := &http.Client{}
existingrepo, err := CheckGiteaExistingRepo(config, elem) existingrepo, err := CheckGiteaExistingRepo(config, elem)
if err != nil { if err != nil {
return err return err
} }
if !existingrepo { if !existingrepo {
err = MigrateRepo(elem, config)
if err != nil {
log.Println(err)
continue
}
} else {
fmt.Printf("Not migrating, %s exists in gitea\n", elem.Name)
}
} else {
fmt.Printf("All repo migrated on thread num %d\n", thr)
wg.Done()
done <- true
return nil
}
}
}
func MigrateRepo(elem GitHubRepo, config *config.Config) (err error) {
client := &http.Client{}
repo := GiteaRepo{ repo := GiteaRepo{
UID: config.GiteaUID, UID: config.GiteaUID,
RepoName: elem.Name, RepoName: elem.Name,
Mirror: true, Mirror: true,
CloneAddr: elem.CloneURL} CloneAddr: elem.CloneURL}
jsondata, err := json.Marshal(repo) jsondata, err := json.Marshal(repo)
if err != nil {
return err
}
req, err := http.NewRequest("POST", config.GiteaMigrateURL, bytes.NewBufferString(string(jsondata))) req, err := http.NewRequest("POST", config.GiteaMigrateURL, bytes.NewBufferString(string(jsondata)))
if err != nil { if err != nil {
return err return err
@ -182,27 +213,17 @@ func MigrateReposToGitea(config *config.Config, wg *sync.WaitGroup, jobs chan Gi
client.Timeout = config.G2gRequestTimeout client.Timeout = config.G2gRequestTimeout
fmt.Println(fmt.Sprintf("Migrating repo %s to gitea rest api", elem.Name)) fmt.Printf("Migrating repo %s to gitea rest api\n", elem.Name)
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return err return err
} }
if resp.StatusCode != 201 { if resp.StatusCode != 201 {
err = fmt.Errorf("Error when migrating repo %s to gitea with status code %d on gitea webservice", elem.Name, resp.StatusCode) err = fmt.Errorf("error when migrating repo %s to gitea with status code %d on gitea webservice", elem.Name, resp.StatusCode)
log.Println(err) log.Println(err)
} }
} else { return err
fmt.Println(fmt.Sprintf("Not migrating, %s exists in gitea", elem.Name))
}
} else {
fmt.Println(fmt.Sprintf("All repo migrated on thread num %d", thr))
wg.Done()
done <- true
return nil
}
}
} }
// GitHubRepo githubrepo struct // GitHubRepo githubrepo struct

12
vendor/gopkg.in/ini.v1/.editorconfig generated vendored Normal file
View File

@ -0,0 +1,12 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*_test.go]
trim_trailing_whitespace = false

1
vendor/gopkg.in/ini.v1/.gitignore generated vendored
View File

@ -4,3 +4,4 @@ ini.sublime-workspace
testdata/conf_reflect.ini testdata/conf_reflect.ini
.idea .idea
/.vscode /.vscode
.DS_Store

27
vendor/gopkg.in/ini.v1/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,27 @@
linters-settings:
staticcheck:
checks: [
"all",
"-SA1019" # There are valid use cases of strings.Title
]
nakedret:
max-func-lines: 0 # Disallow any unnamed return statement
linters:
enable:
- deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
- nakedret
- gofmt
- rowserrcheck
- unconvert
- goimports
- unparam

4
vendor/gopkg.in/ini.v1/README.md generated vendored
View File

@ -1,6 +1,6 @@
# INI # INI
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/go-ini/ini/Go?logo=github&style=for-the-badge)](https://github.com/go-ini/ini/actions?query=workflow%3AGo) [![GitHub Workflow Status](https://img.shields.io/github/checks-status/go-ini/ini/main?logo=github&style=for-the-badge)](https://github.com/go-ini/ini/actions?query=branch%3Amain)
[![codecov](https://img.shields.io/codecov/c/github/go-ini/ini/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/go-ini/ini) [![codecov](https://img.shields.io/codecov/c/github/go-ini/ini/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/go-ini/ini)
[![GoDoc](https://img.shields.io/badge/GoDoc-Reference-blue?style=for-the-badge&logo=go)](https://pkg.go.dev/github.com/go-ini/ini?tab=doc) [![GoDoc](https://img.shields.io/badge/GoDoc-Reference-blue?style=for-the-badge&logo=go)](https://pkg.go.dev/github.com/go-ini/ini?tab=doc)
[![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/go-ini/ini) [![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/go-ini/ini)
@ -24,7 +24,7 @@ Package ini provides INI file read and write functionality in Go.
## Installation ## Installation
The minimum requirement of Go is **1.6**. The minimum requirement of Go is **1.13**.
```sh ```sh
$ go get gopkg.in/ini.v1 $ go get gopkg.in/ini.v1

9
vendor/gopkg.in/ini.v1/codecov.yml generated vendored
View File

@ -4,6 +4,13 @@ coverage:
project: project:
default: default:
threshold: 1% threshold: 1%
informational: true
patch:
defualt:
only_pulls: true
informational: true
comment: comment:
layout: 'diff, files' layout: 'diff'
github_checks: false

View File

@ -14,12 +14,9 @@
package ini package ini
const ( var (
// Deprecated: Use "DefaultSection" instead. // Deprecated: Use "DefaultSection" instead.
DEFAULT_SECTION = DefaultSection DEFAULT_SECTION = DefaultSection
)
var (
// Deprecated: AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE. // Deprecated: AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
AllCapsUnderscore = SnackCase AllCapsUnderscore = SnackCase
) )

15
vendor/gopkg.in/ini.v1/error.go generated vendored
View File

@ -32,3 +32,18 @@ func IsErrDelimiterNotFound(err error) bool {
func (err ErrDelimiterNotFound) Error() string { func (err ErrDelimiterNotFound) Error() string {
return fmt.Sprintf("key-value delimiter not found: %s", err.Line) return fmt.Sprintf("key-value delimiter not found: %s", err.Line)
} }
// ErrEmptyKeyName indicates the error type of no key name is found which there should be one.
type ErrEmptyKeyName struct {
Line string
}
// IsErrEmptyKeyName returns true if the given error is an instance of ErrEmptyKeyName.
func IsErrEmptyKeyName(err error) bool {
_, ok := err.(ErrEmptyKeyName)
return ok
}
func (err ErrEmptyKeyName) Error() string {
return fmt.Sprintf("empty key name: %s", err.Line)
}

42
vendor/gopkg.in/ini.v1/file.go generated vendored
View File

@ -142,6 +142,12 @@ func (f *File) GetSection(name string) (*Section, error) {
return secs[0], err return secs[0], err
} }
// HasSection returns true if the file contains a section with given name.
func (f *File) HasSection(name string) bool {
section, _ := f.GetSection(name)
return section != nil
}
// SectionsByName returns all sections with given name. // SectionsByName returns all sections with given name.
func (f *File) SectionsByName(name string) ([]*Section, error) { func (f *File) SectionsByName(name string) ([]*Section, error) {
if len(name) == 0 { if len(name) == 0 {
@ -168,8 +174,9 @@ func (f *File) SectionsByName(name string) ([]*Section, error) {
func (f *File) Section(name string) *Section { func (f *File) Section(name string) *Section {
sec, err := f.GetSection(name) sec, err := f.GetSection(name)
if err != nil { if err != nil {
// Note: It's OK here because the only possible error is empty section name, if name == "" {
// but if it's empty, this piece of code won't be executed. name = DefaultSection
}
sec, _ = f.NewSection(name) sec, _ = f.NewSection(name)
return sec return sec
} }
@ -335,6 +342,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
// Use buffer to make sure target is safe until finish encoding. // Use buffer to make sure target is safe until finish encoding.
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
lastSectionIdx := len(f.sectionList) - 1
for i, sname := range f.sectionList { for i, sname := range f.sectionList {
sec := f.SectionWithIndex(sname, f.sectionIndexes[i]) sec := f.SectionWithIndex(sname, f.sectionIndexes[i])
if len(sec.Comment) > 0 { if len(sec.Comment) > 0 {
@ -364,12 +372,13 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
} }
} }
isLastSection := i == lastSectionIdx
if sec.isRawSection { if sec.isRawSection {
if _, err := buf.WriteString(sec.rawBody); err != nil { if _, err := buf.WriteString(sec.rawBody); err != nil {
return nil, err return nil, err
} }
if PrettySection { if PrettySection && !isLastSection {
// Put a line between sections // Put a line between sections
if _, err := buf.WriteString(LineBreak); err != nil { if _, err := buf.WriteString(LineBreak); err != nil {
return nil, err return nil, err
@ -435,16 +444,14 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
kname = `"""` + kname + `"""` kname = `"""` + kname + `"""`
} }
for _, val := range key.ValueWithShadows() { writeKeyValue := func(val string) (bool, error) {
if _, err := buf.WriteString(kname); err != nil { if _, err := buf.WriteString(kname); err != nil {
return nil, err return false, err
} }
if key.isBooleanType { if key.isBooleanType {
if kname != sec.keyList[len(sec.keyList)-1] {
buf.WriteString(LineBreak) buf.WriteString(LineBreak)
} return true, nil
continue KeyList
} }
// Write out alignment spaces before "=" sign // Write out alignment spaces before "=" sign
@ -461,10 +468,27 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
val = `"` + val + `"` val = `"` + val + `"`
} }
if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
return false, err
}
return false, nil
}
shadows := key.ValueWithShadows()
if len(shadows) == 0 {
if _, err := writeKeyValue(""); err != nil {
return nil, err return nil, err
} }
} }
for _, val := range shadows {
exitLoop, err := writeKeyValue(val)
if err != nil {
return nil, err
} else if exitLoop {
continue KeyList
}
}
for _, val := range key.nestedValues { for _, val := range key.nestedValues {
if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil {
return nil, err return nil, err
@ -472,7 +496,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
} }
} }
if PrettySection { if PrettySection && !isLastSection {
// Put a line between sections // Put a line between sections
if _, err := buf.WriteString(LineBreak); err != nil { if _, err := buf.WriteString(LineBreak); err != nil {
return nil, err return nil, err

12
vendor/gopkg.in/ini.v1/ini.go generated vendored
View File

@ -1,5 +1,3 @@
// +build go1.6
// Copyright 2014 Unknwon // Copyright 2014 Unknwon
// //
// Licensed under the Apache License, Version 2.0 (the "License"): you may // Licensed under the Apache License, Version 2.0 (the "License"): you may
@ -25,15 +23,15 @@ import (
) )
const ( const (
// DefaultSection is the name of default section. You can use this constant or the string literal.
// In most of cases, an empty string is all you need to access the section.
DefaultSection = "DEFAULT"
// Maximum allowed depth when recursively substituing variable names. // Maximum allowed depth when recursively substituing variable names.
depthValues = 99 depthValues = 99
) )
var ( var (
// DefaultSection is the name of default section. You can use this var or the string literal.
// In most of cases, an empty string is all you need to access the section.
DefaultSection = "DEFAULT"
// LineBreak is the delimiter to determine or compose a new line. // LineBreak is the delimiter to determine or compose a new line.
// This variable will be changed to "\r\n" automatically on Windows at package init time. // This variable will be changed to "\r\n" automatically on Windows at package init time.
LineBreak = "\n" LineBreak = "\n"
@ -125,6 +123,8 @@ type LoadOptions struct {
ReaderBufferSize int ReaderBufferSize int
// AllowNonUniqueSections indicates whether to allow sections with the same name multiple times. // AllowNonUniqueSections indicates whether to allow sections with the same name multiple times.
AllowNonUniqueSections bool AllowNonUniqueSections bool
// AllowDuplicateShadowValues indicates whether values for shadowed keys should be deduplicated.
AllowDuplicateShadowValues bool
} }
// DebugFunc is the type of function called to log parse events. // DebugFunc is the type of function called to log parse events.

24
vendor/gopkg.in/ini.v1/key.go generated vendored
View File

@ -54,6 +54,7 @@ func (k *Key) addShadow(val string) error {
return errors.New("cannot add shadow to auto-increment or boolean key") return errors.New("cannot add shadow to auto-increment or boolean key")
} }
if !k.s.f.options.AllowDuplicateShadowValues {
// Deduplicate shadows based on their values. // Deduplicate shadows based on their values.
if k.value == val { if k.value == val {
return nil return nil
@ -63,6 +64,7 @@ func (k *Key) addShadow(val string) error {
return nil return nil
} }
} }
}
shadow := newKey(k.s, k.name, val) shadow := newKey(k.s, k.name, val)
shadow.isShadow = true shadow.isShadow = true
@ -108,15 +110,24 @@ func (k *Key) Value() string {
return k.value return k.value
} }
// ValueWithShadows returns raw values of key and its shadows if any. // ValueWithShadows returns raw values of key and its shadows if any. Shadow
// keys with empty values are ignored from the returned list.
func (k *Key) ValueWithShadows() []string { func (k *Key) ValueWithShadows() []string {
if len(k.shadows) == 0 { if len(k.shadows) == 0 {
if k.value == "" {
return []string{}
}
return []string{k.value} return []string{k.value}
} }
vals := make([]string, len(k.shadows)+1)
vals[0] = k.value vals := make([]string, 0, len(k.shadows)+1)
for i := range k.shadows { if k.value != "" {
vals[i+1] = k.shadows[i].value vals = append(vals, k.value)
}
for _, s := range k.shadows {
if s.value != "" {
vals = append(vals, s.value)
}
} }
return vals return vals
} }
@ -781,10 +792,8 @@ func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]u
return vals, err return vals, err
} }
type Parser func(str string) (interface{}, error) type Parser func(str string) (interface{}, error)
// parseTimesFormat transforms strings to times in given format. // parseTimesFormat transforms strings to times in given format.
func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) {
vals := make([]time.Time, 0, len(strs)) vals := make([]time.Time, 0, len(strs))
@ -801,7 +810,6 @@ func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnO
return vals, err return vals, err
} }
// doParse transforms strings to different types // doParse transforms strings to different types
func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) { func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) {
vals := make([]interface{}, 0, len(strs)) vals := make([]interface{}, 0, len(strs))

47
vendor/gopkg.in/ini.v1/parser.go generated vendored
View File

@ -131,7 +131,7 @@ func readKeyName(delimiters string, in []byte) (string, int, error) {
// Check if key name surrounded by quotes. // Check if key name surrounded by quotes.
var keyQuote string var keyQuote string
if line[0] == '"' { if line[0] == '"' {
if len(line) > 6 && string(line[0:3]) == `"""` { if len(line) > 6 && line[0:3] == `"""` {
keyQuote = `"""` keyQuote = `"""`
} else { } else {
keyQuote = `"` keyQuote = `"`
@ -164,6 +164,10 @@ func readKeyName(delimiters string, in []byte) (string, int, error) {
if endIdx < 0 { if endIdx < 0 {
return "", -1, ErrDelimiterNotFound{line} return "", -1, ErrDelimiterNotFound{line}
} }
if endIdx == 0 {
return "", -1, ErrEmptyKeyName{line}
}
return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil
} }
@ -232,7 +236,7 @@ func (p *parser) readValue(in []byte, bufferSize int) (string, error) {
} }
var valQuote string var valQuote string
if len(line) > 3 && string(line[0:3]) == `"""` { if len(line) > 3 && line[0:3] == `"""` {
valQuote = `"""` valQuote = `"""`
} else if line[0] == '`' { } else if line[0] == '`' {
valQuote = "`" valQuote = "`"
@ -289,12 +293,8 @@ func (p *parser) readValue(in []byte, bufferSize int) (string, error) {
hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote { hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote {
line = line[1 : len(line)-1] line = line[1 : len(line)-1]
} else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols { } else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols {
if strings.Contains(line, `\;`) { line = strings.ReplaceAll(line, `\;`, ";")
line = strings.Replace(line, `\;`, ";", -1) line = strings.ReplaceAll(line, `\#`, "#")
}
if strings.Contains(line, `\#`) {
line = strings.Replace(line, `\#`, "#", -1)
}
} else if p.options.AllowPythonMultilineValues && lastChar == '\n' { } else if p.options.AllowPythonMultilineValues && lastChar == '\n' {
return p.readPythonMultilines(line, bufferSize) return p.readPythonMultilines(line, bufferSize)
} }
@ -306,15 +306,9 @@ func (p *parser) readPythonMultilines(line string, bufferSize int) (string, erro
parserBufferPeekResult, _ := p.buf.Peek(bufferSize) parserBufferPeekResult, _ := p.buf.Peek(bufferSize)
peekBuffer := bytes.NewBuffer(parserBufferPeekResult) peekBuffer := bytes.NewBuffer(parserBufferPeekResult)
indentSize := 0
for { for {
peekData, peekErr := peekBuffer.ReadBytes('\n') peekData, peekErr := peekBuffer.ReadBytes('\n')
if peekErr != nil { if peekErr != nil && peekErr != io.EOF {
if peekErr == io.EOF {
p.debug("readPythonMultilines: io.EOF, peekData: %q, line: %q", string(peekData), line)
return line, nil
}
p.debug("readPythonMultilines: failed to peek with error: %v", peekErr) p.debug("readPythonMultilines: failed to peek with error: %v", peekErr)
return "", peekErr return "", peekErr
} }
@ -333,19 +327,6 @@ func (p *parser) readPythonMultilines(line string, bufferSize int) (string, erro
return line, nil return line, nil
} }
// Determine indent size and line prefix.
currentIndentSize := len(peekMatches[1])
if indentSize < 1 {
indentSize = currentIndentSize
p.debug("readPythonMultilines: indent size is %d", indentSize)
}
// Make sure each line is indented at least as far as first line.
if currentIndentSize < indentSize {
p.debug("readPythonMultilines: end of value, current indent: %d, expected indent: %d, line: %q", currentIndentSize, indentSize, line)
return line, nil
}
// Advance the parser reader (buffer) in-sync with the peek buffer. // Advance the parser reader (buffer) in-sync with the peek buffer.
_, err := p.buf.Discard(len(peekData)) _, err := p.buf.Discard(len(peekData))
if err != nil { if err != nil {
@ -353,8 +334,7 @@ func (p *parser) readPythonMultilines(line string, bufferSize int) (string, erro
return "", err return "", err
} }
// Handle indented empty line. line += "\n" + peekMatches[0]
line += "\n" + peekMatches[1][indentSize:] + peekMatches[2]
} }
} }
@ -465,6 +445,8 @@ func (f *File) parse(reader io.Reader) (err error) {
// Reset auto-counter and comments // Reset auto-counter and comments
p.comment.Reset() p.comment.Reset()
p.count = 1 p.count = 1
// Nested values can't span sections
isLastValueEmpty = false
inUnparseableSection = false inUnparseableSection = false
for i := range f.options.UnparseableSections { for i := range f.options.UnparseableSections {
@ -485,8 +467,9 @@ func (f *File) parse(reader io.Reader) (err error) {
kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line) kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line)
if err != nil { if err != nil {
switch {
// Treat as boolean key when desired, and whole line is key name. // Treat as boolean key when desired, and whole line is key name.
if IsErrDelimiterNotFound(err) { case IsErrDelimiterNotFound(err):
switch { switch {
case f.options.AllowBooleanKeys: case f.options.AllowBooleanKeys:
kname, err := p.readValue(line, parserBufferSize) kname, err := p.readValue(line, parserBufferSize)
@ -504,6 +487,8 @@ func (f *File) parse(reader io.Reader) (err error) {
case f.options.SkipUnrecognizableLines: case f.options.SkipUnrecognizableLines:
continue continue
} }
case IsErrEmptyKeyName(err) && f.options.SkipUnrecognizableLines:
continue
} }
return err return err
} }

2
vendor/gopkg.in/ini.v1/section.go generated vendored
View File

@ -217,7 +217,7 @@ func (s *Section) KeysHash() map[string]string {
defer s.f.lock.RUnlock() defer s.f.lock.RUnlock()
} }
hash := map[string]string{} hash := make(map[string]string, len(s.keysHash))
for key, value := range s.keysHash { for key, value := range s.keysHash {
hash[key] = value hash[key] = value
} }

10
vendor/modules.txt vendored
View File

@ -1,9 +1,5 @@
# github.com/gopherjs/gopherjs v0.0.0-20210406100015-1e088ea4ee04 # github.com/stretchr/testify v1.7.0
## explicit ## explicit; go 1.13
# github.com/smartystreets/assertions v1.2.0 # gopkg.in/ini.v1 v1.67.0
## explicit
# github.com/smartystreets/goconvey v1.6.4
## explicit
# gopkg.in/ini.v1 v1.62.0
## explicit ## explicit
gopkg.in/ini.v1 gopkg.in/ini.v1