diff --git a/cmd/pkgdashcli/main.go b/cmd/pkgdashcli/main.go index ebcd145..20295a3 100644 --- a/cmd/pkgdashcli/main.go +++ b/cmd/pkgdashcli/main.go @@ -10,6 +10,7 @@ import ( "io" stdslog "log/slog" "net/http" + "net/url" "os" "os/exec" "os/user" @@ -231,12 +232,20 @@ func main() { cfg.Branches = append(cfg.Branches, branchName) } - if cfg.Source.Repository == "" { - reposiotry, err := getCurrentRepository(ctx) + if cfg.Source.Owner == "" { + owner, err := getOwnerRepository(ctx) if err != nil { log.Fatal(ctx, "failed to get current repository", err) } - cfg.Source.Repository = reposiotry + cfg.Source.Owner = owner + } + + if cfg.Source.Repository == "" { + repository, err := getCurrentRepository(ctx) + if err != nil { + log.Fatal(ctx, "failed to get current repository", err) + } + cfg.Source.Repository = repository } gitSource := source.NewSourceControl(*cfg, log) @@ -357,7 +366,44 @@ func getCurrentRepository(ctx context.Context) (string, error) { continue } - return v.URLs[0], nil + u, err := url.Parse(v.URLs[0]) + if err != nil { + continue + } + return filepath.Base(u.Path), nil + } + + return "", fmt.Errorf("failed to get remotes") +} + +func getOwnerRepository(ctx context.Context) (string, error) { + wd, err := os.Getwd() + if err != nil { + return "", err + } + + p := filepath.Clean(wd) + + repo, err := git.PlainOpen(p) + if err != nil { + return "", err + } + + cfg, err := repo.Config() + if err != nil { + return "", err + } + + for k, v := range cfg.Remotes { + if k != "origin" { + continue + } + + u, err := url.Parse(v.URLs[0]) + if err != nil { + continue + } + return filepath.Base(filepath.Dir(u.Path)), nil } return "", fmt.Errorf("failed to get remotes") @@ -425,9 +471,6 @@ func getRepoMgmt(ctx context.Context, log logger.Logger, cfg *configcli.Config) } log.Info(ctx, "try to configure scm for "+cfg.Source.APIURL) - if cfg.Source.Owner == "" { - cfg.Source.Owner = n.Machine(cfg.Source.APIURL).Get("login") - } if cfg.Source.Username == "" { cfg.Source.Username = n.Machine(cfg.Source.APIURL).Get("login") } diff --git a/go.mod b/go.mod index 0db5b6a..d8b7c06 100644 --- a/go.mod +++ b/go.mod @@ -6,14 +6,14 @@ toolchain go1.23.3 require ( github.com/envoyproxy/protoc-gen-validate v1.1.0 - github.com/go-git/go-git/v5 v5.12.0 + github.com/go-git/go-git/v5 v5.12.1-0.20241206065855-b2aea86f9eef github.com/golang-migrate/migrate/v4 v4.17.0 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.3.1 github.com/jdx/go-netrc v1.0.0 github.com/jmoiron/sqlx v1.3.5 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 go.unistack.org/micro-client-http/v3 v3.9.14 go.unistack.org/micro-codec-json/v3 v3.10.1 go.unistack.org/micro-codec-jsonpb/v3 v3.10.3 @@ -27,9 +27,9 @@ require ( go.unistack.org/micro-server-http/v3 v3.11.37 go.unistack.org/micro/v3 v3.11.12 go.unistack.org/protoc-gen-go-micro/v3 v3.10.10 - golang.org/x/mod v0.17.0 - golang.org/x/sync v0.9.0 - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d + golang.org/x/mod v0.22.0 + golang.org/x/sync v0.10.0 + golang.org/x/tools v0.28.0 google.golang.org/protobuf v1.35.2 modernc.org/sqlite v1.29.5 ) @@ -40,7 +40,7 @@ require ( github.com/cilium/ebpf v0.9.1 // indirect github.com/containerd/cgroups/v3 v3.0.1 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/cyphar/filepath-securejoin v0.3.5 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect @@ -50,7 +50,7 @@ require ( github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/silas/dag v0.0.0-20220518035006-a7e85ada93c5 // indirect - github.com/sirupsen/logrus v1.9.2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.unistack.org/metrics v0.0.1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect @@ -60,16 +60,16 @@ require ( require ( dario.cat/mergo v1.0.1 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/cloudflare/circl v1.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/go-git/go-billy/v5 v5.6.0 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/gnostic v0.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -102,16 +102,16 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/spf13/afero v1.10.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 680d30d..7653153 100644 --- a/go.sum +++ b/go.sum @@ -611,9 +611,11 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0 github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -630,7 +632,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -645,9 +646,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4= github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -671,8 +673,10 @@ github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzA github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= +github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -691,8 +695,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v0.0.0-20240618083138-03be62527ccb h1:2SoxRauy2IqekRMggrQk3yNI5X6omSnk6ugVbFywwXs= +github.com/elazarl/goproxy v0.0.0-20240618083138-03be62527ccb/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -731,12 +735,12 @@ github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2H github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-git/v5 v5.12.1-0.20241206065855-b2aea86f9eef h1:j0tyaQIIUx1waAxkytdJWKX0QGjIiz6kOZ4H2QMHJFo= +github.com/go-git/go-git/v5 v5.12.1-0.20241206065855-b2aea86f9eef/go.mod h1:zAa5oaWb3pPBi43CoTAXn+HLTLuviecdz7oyhf/fHIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -771,6 +775,8 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -1030,8 +1036,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -1090,8 +1096,9 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -1114,8 +1121,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= @@ -1208,14 +1215,12 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1231,6 +1236,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1276,6 +1283,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1340,8 +1349,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1388,8 +1397,8 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1479,8 +1488,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1494,8 +1503,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1515,8 +1524,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1594,6 +1603,8 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/source/git/gogit.go b/internal/source/git/gogit.go new file mode 100644 index 0000000..9d4a403 --- /dev/null +++ b/internal/source/git/gogit.go @@ -0,0 +1,48 @@ +//go:build gogit + +package git + +/* +import "context" + +type Repository interface { + Checkout(ctx context.Context, hash string) error +} + +type repository struct { + path string +} + +func NewRepositoryFromURL(ctx context.Context, url string) (Repository, error) { + return nil, nil +} + + +Branches() { + refIter, err := repo.Branches() // получение веток + if err != nil { + g.logger.Error(ctx, "failed to get branches", err) + return err + } + + for { + ref, err := refIter.Next() + if err != nil { + if err == io.EOF { + break + } + g.logger.Error(ctx, "ref iter error", err) + return err + } + g.logger.Info(ctx, fmt.Sprintf("check %s == %s", ref.Name().Short(), branch)) + if ref.Name().Short() == branch { + headRef = plumbing.NewHashReference(ref.Name(), ref.Hash()) + g.logger.Info(ctx, "headRef set to "+headRef.String()) + break + } + } // перебираем получение ветки и когда находим нужную выходим из цикла записав ветку в headRef + + refIter.Close() +} + +*/ diff --git a/internal/source/git/nogogit.go b/internal/source/git/nogogit.go new file mode 100644 index 0000000..dc07ab8 --- /dev/null +++ b/internal/source/git/nogogit.go @@ -0,0 +1,262 @@ +//go:build !gogit + +package git + +import ( + "bytes" + "context" + "fmt" + "io" + "os/exec" + "strings" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" +) + +type Repository interface { + Branches() ([]*plumbing.Reference, error) + // Auth(username string, password string) error + FetchContext(ctx context.Context, opts *git.FetchOptions) error + PushContext(ctx context.Context, opts *git.PushOptions) error + Head() (*plumbing.Reference, error) + Worktree() (Worktree, error) +} + +type Worktree interface { + Checkout(*git.CheckoutOptions) error + PullContext(ctx context.Context, opts *git.PullOptions) error + Status() (git.Status, error) + AddWithOptions(opts *git.AddOptions) error + Commit(msg string, opts *git.CommitOptions) (plumbing.Hash, error) + Reset(opts *git.ResetOptions) error +} + +type repository struct { + gocmd string + path string + // authUsername string + // authPassword string +} + +func PlainOpenWithOptions(path string, opts *git.PlainOpenOptions) (Repository, error) { + gopath, err := exec.LookPath("git") + if err != nil { + return nil, err + } + return &repository{path: path, gocmd: gopath}, nil +} + +/* +func (r *repository) Auth(username string, password string) error { + r.authUsername = username + r.authPassword = password + return nil +} +*/ + +func (r *repository) Branches() ([]*plumbing.Reference, error) { + var branches []*plumbing.Reference + cmd := exec.Command(r.gocmd, "show-ref", "--branches") + buf, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("output %s error %w", buf, err) + } + br := bytes.NewBuffer(buf) + for { + line, err := br.ReadString('\n') + if err != nil { + if err == io.EOF && line == "" { + break + } else if err != io.EOF && line == "" { + return nil, err + } + } + fields := strings.Fields(line) + if len(fields) != 2 { + return nil, fmt.Errorf("invalid fields %s", line) + } + branches = append(branches, plumbing.NewReferenceFromStrings(fields[1], fields[0])) + } + return branches, nil +} + +func (r *repository) FetchContext(ctx context.Context, opts *git.FetchOptions) error { + args := []string{"fetch"} + if opts.Force { + args = append(args, "-f") + } + cmd := exec.CommandContext(ctx, r.gocmd, args...) + buf, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("output %s error %w", buf, err) + } + + return nil +} + +func (r *repository) PushContext(ctx context.Context, opts *git.PushOptions) error { + args := []string{"push"} + + if opts.Force { + args = append(args, "-f") + } + + /* TODO + var refs []string + for _, ref := range opts.RefSpecs { + refs = append(refs, ref.String()) + } + + args = append(args, strings.Join(refs, " ")) + */ + cmd := exec.CommandContext(ctx, r.gocmd, args...) + buf, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("output %s error %w", buf, err) + } + + return nil +} + +func (r *repository) Head() (*plumbing.Reference, error) { + var head *plumbing.Reference + cmd := exec.Command(r.gocmd, "symbolic-ref", "--short", "HEAD") + buf, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("output %s error %w", buf, err) + } + br := bytes.NewBuffer(buf) + for { + line, err := br.ReadString('\n') + if err != nil { + if err == io.EOF && line == "" { + break + } else if err != io.EOF && line == "" { + return nil, err + } + } + fields := strings.Fields(line) + if len(fields) != 2 { + return nil, fmt.Errorf("invalid fields %s", line) + } + head = plumbing.NewReferenceFromStrings("HEAD", fields[0]) + } + return head, nil +} + +type worktree struct { + gocmd string +} + +func (r *repository) Worktree() (Worktree, error) { + return &worktree{gocmd: r.gocmd}, nil +} + +func (w *worktree) Checkout(opts *git.CheckoutOptions) error { + args := []string{"checkout"} + if opts.Create { + args = append(args, "-b", opts.Branch.Short()) + } + if opts.Force { + args = append(args, "-f") + } + if opts.Hash.IsZero() { + args = append(args, opts.Branch.Short()) + } else { + args = append(args, opts.Hash.String()) + } + cmd := exec.Command(w.gocmd, args...) + buf, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("output %s error %w", buf, err) + } + + return nil +} + +func (w *worktree) Status() (git.Status, error) { + return git.Status{}, nil +} + +func (w *worktree) Reset(opts *git.ResetOptions) error { + args := []string{"reset"} + if opts.Mode == git.HardReset { + args = append(args, "--hard") + } + + args = append(args, opts.Commit.String()) + + cmd := exec.Command(w.gocmd, args...) + buf, err := cmd.CombinedOutput() + if err != nil { + return err + } + _ = buf + return nil +} + +func (w *worktree) Commit(msg string, opts *git.CommitOptions) (plumbing.Hash, error) { + cmd := exec.Command(w.gocmd, `commit`, + fmt.Sprintf(`--author="%s <%s>"`, opts.Author.Name, opts.Author.Email), + "-m", msg, + fmt.Sprintf(`--date="%s"`, opts.Author.When.Format(`Mon Jan _2 15:04:05 2006 -0700`)), + ) + buf, err := cmd.CombinedOutput() + if err != nil { + return plumbing.ZeroHash, fmt.Errorf("output %s error %w", buf, err) + } + + var head *plumbing.Reference + cmd = exec.Command(w.gocmd, "show-ref", "HEAD") + buf, err = cmd.CombinedOutput() + if err != nil { + return plumbing.ZeroHash, err + } + br := bytes.NewBuffer(buf) + for { + line, err := br.ReadString('\n') + if err != nil { + if err == io.EOF && line == "" { + break + } else if err != io.EOF && line == "" { + return plumbing.ZeroHash, err + } + } + fields := strings.Fields(line) + if len(fields) != 2 { + return plumbing.ZeroHash, fmt.Errorf("invalid fields %s", line) + } + head = plumbing.NewReferenceFromStrings("HEAD", fields[0]) + } + + return head.Hash(), nil +} + +func (w *worktree) PullContext(ctx context.Context, opts *git.PullOptions) error { + args := []string{"pull"} + if opts.Force { + args = append(args, "-f") + } + if opts.Depth != 0 { + args = append(args, fmt.Sprintf("--depth=%d", opts.Depth)) + } + + cmd := exec.CommandContext(ctx, w.gocmd, args...) + buf, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("output %s error %w", buf, err) + } + + return nil +} + +func (w *worktree) AddWithOptions(opts *git.AddOptions) error { + cmd := exec.Command(w.gocmd, "add", opts.Path) + buf, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("output %s error %w", buf, err) + } + + return nil +} diff --git a/internal/source/gitea/gitea.go b/internal/source/gitea/gitea.go index 81e3bd4..b2ebe97 100644 --- a/internal/source/gitea/gitea.go +++ b/internal/source/gitea/gitea.go @@ -22,6 +22,7 @@ import ( "go.unistack.org/micro/v3/logger" "go.unistack.org/pkgdash/internal/configcli" "go.unistack.org/pkgdash/internal/modules" + gogit "go.unistack.org/pkgdash/internal/source/git" ) var ErrPRNotExist = errors.New("pull request does not exist") @@ -36,7 +37,6 @@ type Gitea struct { Repository string Owner string pulls []*giteaPull - baseRef *plumbing.Reference } func NewGitea(cfg configcli.Config, log logger.Logger) *Gitea { @@ -95,14 +95,16 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod } if err = tplTitle.Execute(wTitle, data); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to execute template: %v", err)) + g.logger.Error(ctx, "failed to execute template", err) + return err } if err = tplBody.Execute(wBody, data); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to execute template: %v", err)) + g.logger.Error(ctx, "failed to execute template", err) + return err } // открытие гит репозитория с опцией обхода репозитория для нахождения .git - repo, err := git.PlainOpenWithOptions(".", &git.PlainOpenOptions{DetectDotGit: true}) + repo, err := gogit.PlainOpenWithOptions(".", &git.PlainOpenOptions{DetectDotGit: true}) if err != nil { g.logger.Fatal(ctx, fmt.Sprintf("failed to open repo: %v", err)) } @@ -111,51 +113,43 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod Auth: &httpauth.BasicAuth{Username: g.Username, Password: g.Password}, Force: true, }); err != nil && err != git.NoErrAlreadyUpToDate { - g.logger.Fatal(ctx, fmt.Sprintf("failed to fetch repo : %v", err)) + g.logger.Error(ctx, "failed to fetch repo", err) + return err } // обновляем репозиторий - var headRef *plumbing.Reference // вроде ссылка на гит + var headRef *plumbing.Reference - if g.baseRef == nil { - g.baseRef, err = repo.Head() - if err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("Error head: %s", err)) - } - } - - refIter, err := repo.Branches() // получение веток + branches, err := repo.Branches() if err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to get branches: %v", err)) + g.logger.Error(ctx, "cant get repo branches", err) return err } - for { - ref, err := refIter.Next() - if err != nil { + + for _, ref := range branches { + if ref.Name().Short() == branch { + + headRef = plumbing.NewHashReference(ref.Name(), ref.Hash()) + g.logger.Info(ctx, "headRef set to "+headRef.String()) break } - if ref.Name().Short() == branch { // todo вот тут возможно нужно переделать - headRef = ref - break - } - } // перебираем получение ветки и когда находим нужную выходим из цикла записав ветку в headRef - refIter.Close() + } if headRef == nil { - g.logger.Fatal(ctx, "failed to get repo branch head") + g.logger.Error(ctx, "failed to get repo branch head") return err } // Не получили нужную ветку - g.logger.Info(ctx, fmt.Sprintf("repo head %s", headRef)) + g.logger.Info(ctx, "repo head "+headRef.String()) wtree, err := repo.Worktree() // todo вроде рабочее дерево не нужно if err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to get worktree: %v", err)) + g.logger.Error(ctx, "failed to get worktree", err) + return err } - defer g.checkout(*wtree, *g.baseRef) g.pulls, err = g.GetPulls(ctx, g.URL, g.Owner, g.Repository, g.Password) if err != nil && err != ErrPRNotExist { - g.logger.Error(ctx, fmt.Sprintf("GetPulls error: %s", err)) + g.logger.Error(ctx, "GetPulls error", err) return err } @@ -168,32 +162,47 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod g.logger.Info(ctx, fmt.Sprintf("update %s from %s to %s", path, mod.Module.Version, mod.Version)) - g.logger.Info(ctx, "reset worktree") - if err = wtree.Reset(&git.ResetOptions{Commit: headRef.Hash(), Mode: git.HardReset}); err != nil { - g.logger.Error(ctx, fmt.Sprintf("failed to reset repo branch: %v", err)) - } // вроде меняем ветку todo вроде можно удалить + wstatus, err := wtree.Status() + if err != nil { + g.logger.Error(ctx, "failed to get worktree status", err) + return err + } + g.logger.Info(ctx, "worktree status "+wstatus.String()) + /* + g.logger.Info(ctx, "try to reset worktree to "+headRef.Hash().String()) + if err = wtree.Reset(&git.ResetOptions{Commit: headRef.Hash(), Mode: git.HardReset}); err != nil { + g.logger.Error(ctx, "failed to reset repo branch to "+headRef.Hash().String(), err) + return err + } // вроде меняем ветку todo вроде можно удалить + */ if err = wtree.PullContext(ctx, &git.PullOptions{ - Auth: &httpauth.BasicAuth{Username: g.Username, Password: g.Password}, - Depth: 1, + Auth: &httpauth.BasicAuth{Username: g.Username, Password: g.Password}, + // Depth: 1, // RemoteURL : Force: true, RemoteName: "origin", }); err != nil && err != git.NoErrAlreadyUpToDate { g.logger.Error(ctx, fmt.Sprintf("failed to pull repo: %v", err)) // подтягиваем изменения с удаленого репозитория + return err } g.logger.Info(ctx, fmt.Sprintf("checkout ref %s", headRef)) + if err = wtree.Checkout(&git.CheckoutOptions{ Hash: headRef.Hash(), Branch: plumbing.NewBranchReferenceName(fmt.Sprintf("pkgdash/go_modules/%s-%s", path, mod.Version)), Create: true, Force: true, - }); err != nil && err != git.ErrBranchExists && err != git.ErrInvalidReference { + }); err != nil && err != git.ErrBranchExists { g.logger.Error(ctx, fmt.Sprintf("failed to checkout tree: %v", err)) return err } // создаем новую ветку + defer func() { + _ = g.checkout(wtree, headRef) + }() + epath, err := exec.LookPath("go") if errors.Is(err, exec.ErrDot) { err = nil @@ -207,27 +216,32 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod cmd = exec.CommandContext(ctx, epath, "mod", "edit", fmt.Sprintf("-droprequire=%s", mod.Module.Path)) if out, err = cmd.CombinedOutput(); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to run go mod edit: %s err: %v", out, err)) + g.logger.Error(ctx, fmt.Sprintf("failed to run go mod edit: %s err: %v", out, err)) + return err } cmd = exec.CommandContext(ctx, epath, "mod", "edit", fmt.Sprintf("-require=%s@%s", path, mod.Version)) if out, err = cmd.CombinedOutput(); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to run go mod edit: %s err: %v", out, err)) + g.logger.Error(ctx, fmt.Sprintf("failed to run go mod edit: %s err: %v", out, err)) + return err } // пытаемся выполнить команду go mod edit с новой версией модуля cmd = exec.CommandContext(ctx, epath, "mod", "tidy") if out, err = cmd.CombinedOutput(); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to run go mod tidy: %s err: %v", out, err)) + g.logger.Error(ctx, fmt.Sprintf("failed to run go mod tidy: %s err: %v", out, err)) + return err } // пытаемся выполнить команду go mod tidy пытаемся подтянуть новую версию модуля g.logger.Info(ctx, "worktree add go.mod") - if _, err = wtree.Add("go.mod"); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to add file: %v", err)) + if err = wtree.AddWithOptions(&git.AddOptions{Path: "go.mod"}); err != nil { + g.logger.Error(ctx, fmt.Sprintf("failed to add file: %v", err)) + return err } g.logger.Info(ctx, "worktree add go.sum") - if _, err = wtree.Add("go.sum"); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to add file: %v", err)) + if err = wtree.AddWithOptions(&git.AddOptions{Path: "go.sum"}); err != nil { + g.logger.Error(ctx, fmt.Sprintf("failed to add file: %v", err)) + return err } g.logger.Info(ctx, "worktree commit") @@ -240,7 +254,8 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod }, }) // хотим за коммитить изменения if err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to commit: %v", err)) + g.logger.Error(ctx, fmt.Sprintf("failed to commit: %v", err)) + return err } refspec := gitconfig.RefSpec(fmt.Sprintf("+refs/heads/pkgdash/go_modules/%s-%s:refs/heads/pkgdash/go_modules/%s-%s", path, mod.Version, path, mod.Version)) // todo как будто нужно переделать @@ -252,7 +267,8 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod Auth: &httpauth.BasicAuth{Username: g.Username, Password: g.Password}, Force: true, }); err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to push repo branch: %v", err)) + g.logger.Error(ctx, "failed to push repo branch", err) + return err } // пытаемся за пушить изменения body := map[string]string{ @@ -265,11 +281,11 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod buf, err = json.Marshal(body) if err != nil { + g.logger.Error(ctx, "failed to marshal", err) return err } g.logger.Info(ctx, fmt.Sprintf("marshal body: %s", buf)) - req, err := http.NewRequestWithContext( ctx, http.MethodPost, @@ -277,6 +293,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod bytes.NewReader(buf), ) if err != nil { + g.logger.Error(ctx, "http request error", err) return err } req.Header.Add("Accept", "application/json") @@ -285,6 +302,7 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod rsp, err := http.DefaultClient.Do(req) if err != nil { + g.logger.Error(ctx, "failed to call http request", err) return err } // Вроде создаем новый реквест на создание пулл реквеста if rsp.StatusCode != http.StatusCreated { @@ -294,11 +312,6 @@ func (g *Gitea) RequestOpen(ctx context.Context, branch string, path string, mod g.logger.Info(ctx, fmt.Sprintf("PR create for %s-%s", path, mod.Version)) - repo, err = git.PlainOpenWithOptions(".", &git.PlainOpenOptions{DetectDotGit: true}) - if err != nil { - g.logger.Fatal(ctx, fmt.Sprintf("failed to open repo: %v", err)) - } - return nil } @@ -475,9 +488,9 @@ func (g *Gitea) GetPulls(ctx context.Context, url, owner, repo, password string) return pullsAll, nil } -func (g *Gitea) checkout(w git.Worktree, ref plumbing.Reference) { +func (g *Gitea) checkout(w gogit.Worktree, ref *plumbing.Reference) error { ctx := context.Background() - g.logger.Debug(ctx, fmt.Sprintf("Checkout: %s", ref.Name().Short())) + g.logger.Debug(ctx, "checkout: "+ref.Name().Short()) if err := w.Checkout(&git.CheckoutOptions{ Branch: ref.Name(), @@ -485,6 +498,8 @@ func (g *Gitea) checkout(w git.Worktree, ref plumbing.Reference) { Force: true, Keep: false, }); err != nil { - g.logger.Error(ctx, fmt.Sprintf("failed to reset: %v", err)) + g.logger.Error(ctx, "failed to reset", err) + return err } + return nil }