From 80b5a6680e2fc4d2f1e425ff2e5f1cfbbd529d9e Mon Sep 17 00:00:00 2001 From: Grégoire Duchêne Date: Sun, 4 Jul 2021 15:33:18 +0100 Subject: Simplify project structure --- archlinux/PKGBUILD | 28 +++++++++ cmd/go-import-redirect/main.go | 87 -------------------------- cmd/go-import-redirect/main_aws.go | 40 ------------ deployments/archlinux/PKGBUILD | 28 --------- deployments/docker/Dockerfile | 11 ---- deployments/systemd/go-import-redirect.service | 16 ----- docker/Dockerfile | 11 ++++ internal/lib.go | 27 -------- internal/lib_test.go | 23 ------- main.go | 85 +++++++++++++++++++++++++ main_aws.go | 38 +++++++++++ resp.go | 27 ++++++++ resp_test.go | 23 +++++++ systemd/go-import-redirect.service | 16 +++++ 14 files changed, 228 insertions(+), 232 deletions(-) create mode 100644 archlinux/PKGBUILD delete mode 100644 cmd/go-import-redirect/main.go delete mode 100644 cmd/go-import-redirect/main_aws.go delete mode 100644 deployments/archlinux/PKGBUILD delete mode 100644 deployments/docker/Dockerfile delete mode 100644 deployments/systemd/go-import-redirect.service create mode 100644 docker/Dockerfile delete mode 100644 internal/lib.go delete mode 100644 internal/lib_test.go create mode 100644 main.go create mode 100644 main_aws.go create mode 100644 resp.go create mode 100644 resp_test.go create mode 100644 systemd/go-import-redirect.service diff --git a/archlinux/PKGBUILD b/archlinux/PKGBUILD new file mode 100644 index 0000000..e8a538d --- /dev/null +++ b/archlinux/PKGBUILD @@ -0,0 +1,28 @@ +# Copyright (c) 2020, Grégoire Duchêne +# +# Use of this file is governed by the ISC license that can be found in +# the LICENSE file. + +# Maintainer: Grégoire Duchêne + +pkgname=go-import-redirect +pkgver=0.1.0 +pkgrel=2 +arch=(x86_64) +url=https://github.com/gduchene/go-import-redirect +license=(custom:ISC) +makedepends=(go) +source=(git+https://github.com/gduchene/go-import-redirect.git#tag=v${pkgver}) +sha256sums=(SKIP) + +build() { + cd ${pkgname} + go build +} + +package() { + cd ${pkgname} + install -Dm755 ${pkgname} ${pkgdir}/usr/bin/${pkgname} + install -Dm644 systemd/${pkgname}.service ${pkgdir}/usr/lib/systemd/system/${pkgname}.service + install -Dm644 LICENSE ${pkgdir}/usr/share/licenses/${pkgname}/LICENSE +} diff --git a/cmd/go-import-redirect/main.go b/cmd/go-import-redirect/main.go deleted file mode 100644 index ea994b2..0000000 --- a/cmd/go-import-redirect/main.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2019, Grégoire Duchêne -// -// Use of this source code is governed by the ISC license that can be -// found in the LICENSE file. - -// +build !aws - -package main - -import ( - "context" - "fmt" - "log" - "net" - "net/http" - "os" - "os/signal" - "path" - "time" - - "golang.org/x/sys/unix" - - "go.awhk.org/go-import-redirect/internal" -) - -func redirect(resp http.ResponseWriter, req *http.Request) { - if req.Method != http.MethodGet { - resp.Header().Set("Allow", http.MethodGet) - resp.WriteHeader(http.StatusMethodNotAllowed) - return - } - - pkg := path.Join(req.Host, req.URL.Path) - resp.Header().Set("Content-Type", "text/html; charset=utf-8") - if req.URL.Query().Get("go-get") == "1" { - resp.WriteHeader(http.StatusOK) - } else { - resp.Header().Set("Location", "https://pkg.go.dev/"+pkg) - resp.WriteHeader(http.StatusFound) - } - if _, err := fmt.Fprint(resp, internal.GetBody(pkg)); err != nil { - log.Println("fmt.Fprint:", err) - } -} - -func main() { - mux := http.NewServeMux() - mux.HandleFunc("/", redirect) - srv := http.Server{Handler: mux} - - done := make(chan os.Signal, 1) - signal.Notify(done, os.Interrupt, unix.SIGTERM) - - go func() { - var ( - addr = os.Getenv("ADDR") - l net.Listener - err error - ) - if addr != "" && addr[0] == '/' { - if l, err = net.Listen("unix", addr); err != nil { - log.Fatalln("net.Listen:", err) - } - // We do not do any authorization anyway, so 0666 makes sense here. - if err = os.Chmod(addr, 0666); err != nil { - log.Fatalln("os.Chmod:", err) - } - } else { - if addr == "" { - addr = ":8080" - } - if l, err = net.Listen("tcp", addr); err != nil { - log.Fatalln("net.Listen:", err) - } - } - if err = srv.Serve(l); err != nil && err != http.ErrServerClosed { - log.Fatalln("server.ListenAndServe:", err) - } - }() - - <-done - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - if err := srv.Shutdown(ctx); err != nil && err != http.ErrServerClosed { - log.Fatalln("server.Shutdown:", err) - } -} diff --git a/cmd/go-import-redirect/main_aws.go b/cmd/go-import-redirect/main_aws.go deleted file mode 100644 index 4d4b0e7..0000000 --- a/cmd/go-import-redirect/main_aws.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2019, Grégoire Duchêne -// -// Use of this source code is governed by the ISC license that can be -// found in the LICENSE file. - -// +build aws,linux - -package main - -import ( - "context" - "net/http" - "path" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" - - "go.awhk.org/go-import-redirect/internal" -) - -func redirect(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { - var ( - pkg = path.Join(req.Headers["Host"], req.Path) - resp = events.APIGatewayProxyResponse{ - Body: internal.GetBody(pkg), - Headers: map[string]string{"Content-Type": "text/html; charset=utf-8"}, - } - ) - if v, ok := req.QueryStringParameters["go-get"]; ok && v == "1" { - resp.StatusCode = http.StatusOK - } else { - resp.Headers["Location"] = "https://pkg.go.dev/" + pkg - resp.StatusCode = http.StatusFound - } - return resp, nil -} - -func main() { - lambda.Start(redirect) -} diff --git a/deployments/archlinux/PKGBUILD b/deployments/archlinux/PKGBUILD deleted file mode 100644 index 1de09e4..0000000 --- a/deployments/archlinux/PKGBUILD +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2020, Grégoire Duchêne -# -# Use of this file is governed by the ISC license that can be found in -# the LICENSE file. - -# Maintainer: Grégoire Duchêne - -pkgname=go-import-redirect -pkgver=0.1.0 -pkgrel=2 -arch=(x86_64) -url=https://github.com/gduchene/go-import-redirect -license=(custom:ISC) -makedepends=(go) -source=(git+https://github.com/gduchene/go-import-redirect.git#tag=v${pkgver}) -sha256sums=(SKIP) - -build() { - cd ${pkgname} - go build ./cmd/${pkgname} -} - -package() { - cd ${pkgname} - install -Dm755 ${pkgname} ${pkgdir}/usr/bin/${pkgname} - install -Dm644 deployments/systemd/${pkgname}.service ${pkgdir}/usr/lib/systemd/system/${pkgname}.service - install -Dm644 LICENSE ${pkgdir}/usr/share/licenses/${pkgname}/LICENSE -} diff --git a/deployments/docker/Dockerfile b/deployments/docker/Dockerfile deleted file mode 100644 index 5cc27a9..0000000 --- a/deployments/docker/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.15 -WORKDIR /root -COPY . ./ -ENV CGO_ENABLED=0 -RUN go build ./cmd/go-import-redirect - -FROM scratch -COPY --from=0 /root/go-import-redirect /go-import-redirect - -EXPOSE 8080 -ENTRYPOINT ["/go-import-redirect"] diff --git a/deployments/systemd/go-import-redirect.service b/deployments/systemd/go-import-redirect.service deleted file mode 100644 index 0691753..0000000 --- a/deployments/systemd/go-import-redirect.service +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2020, Grégoire Duchêne -# -# Use of this file is governed by the ISC license that can be found in -# the LICENSE file. - -[Install] - WantedBy=multi-user.target - -[Service] - Environment=ADDR=%t/go-import-redirect/socket - ExecStart=go-import-redirect - DynamicUser=true - RuntimeDirectory=go-import-redirect - -[Unit] - Description=go-import-redirect diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..13dd13f --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.15 +WORKDIR /root +COPY . ./ +ENV CGO_ENABLED=0 +RUN go build + +FROM scratch +COPY --from=0 /root/go-import-redirect /go-import-redirect + +EXPOSE 8080 +ENTRYPOINT ["/go-import-redirect"] diff --git a/internal/lib.go b/internal/lib.go deleted file mode 100644 index 742a9c7..0000000 --- a/internal/lib.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2019, Grégoire Duchêne -// -// Use of this source code is governed by the ISC license that can be -// found in the LICENSE file. - -package internal - -import ( - "fmt" - "os" - "strings" -) - -func GetBody(pkg string) string { - dest := GetDest(os.Getenv("PREFIX"), os.Getenv("DEST"), pkg) - return fmt.Sprintf(` - -go-import-redirect -`, pkg, os.Getenv("VCS"), dest) -} - -func GetDest(srcPrefix, destPrefix, pkg string) string { - srcPrefix = strings.TrimRight(srcPrefix, "/") - destPrefix = strings.TrimRight(destPrefix, "/") - path := strings.TrimLeft(strings.TrimPrefix(pkg, srcPrefix), "/") - return destPrefix + "/" + strings.Split(path, "/")[0] -} diff --git a/internal/lib_test.go b/internal/lib_test.go deleted file mode 100644 index 19a880d..0000000 --- a/internal/lib_test.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2019, Grégoire Duchêne -// -// Use of this source code is governed by the ISC license that can be -// found in the LICENSE file. - -package internal - -import "testing" - -func TestGetDest(t *testing.T) { - cs := []struct{ srcPrefix, destPrefix, pkg, expected string }{ - {"src.example.com/x/", "https://example.com/git/", "src.example.com/x/foo", "https://example.com/git/foo"}, - {"src.example.com/x/", "https://example.com/git/", "src.example.com/x/foo/bar", "https://example.com/git/foo"}, - {"src.example.com/x", "https://example.com/git", "src.example.com/x/foo", "https://example.com/git/foo"}, - {"src.example.com/x", "https://example.com/git", "src.example.com/x/foo/bar", "https://example.com/git/foo"}, - } - for _, c := range cs { - actual := GetDest(c.srcPrefix, c.destPrefix, c.pkg) - if actual != c.expected { - t.Errorf("expected %s, got %s", c.expected, actual) - } - } -} diff --git a/main.go b/main.go new file mode 100644 index 0000000..c2b331e --- /dev/null +++ b/main.go @@ -0,0 +1,85 @@ +// Copyright (c) 2019, Grégoire Duchêne +// +// Use of this source code is governed by the ISC license that can be +// found in the LICENSE file. + +// +build !aws + +package main + +import ( + "context" + "fmt" + "log" + "net" + "net/http" + "os" + "os/signal" + "path" + "time" + + "golang.org/x/sys/unix" +) + +func redirect(resp http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + resp.Header().Set("Allow", http.MethodGet) + resp.WriteHeader(http.StatusMethodNotAllowed) + return + } + + pkg := path.Join(req.Host, req.URL.Path) + resp.Header().Set("Content-Type", "text/html; charset=utf-8") + if req.URL.Query().Get("go-get") == "1" { + resp.WriteHeader(http.StatusOK) + } else { + resp.Header().Set("Location", "https://pkg.go.dev/"+pkg) + resp.WriteHeader(http.StatusFound) + } + if _, err := fmt.Fprint(resp, GetBody(pkg)); err != nil { + log.Println("fmt.Fprint:", err) + } +} + +func main() { + mux := http.NewServeMux() + mux.HandleFunc("/", redirect) + srv := http.Server{Handler: mux} + + done := make(chan os.Signal, 1) + signal.Notify(done, os.Interrupt, unix.SIGTERM) + + go func() { + var ( + addr = os.Getenv("ADDR") + l net.Listener + err error + ) + if addr != "" && addr[0] == '/' { + if l, err = net.Listen("unix", addr); err != nil { + log.Fatalln("net.Listen:", err) + } + // We do not do any authorization anyway, so 0666 makes sense here. + if err = os.Chmod(addr, 0666); err != nil { + log.Fatalln("os.Chmod:", err) + } + } else { + if addr == "" { + addr = ":8080" + } + if l, err = net.Listen("tcp", addr); err != nil { + log.Fatalln("net.Listen:", err) + } + } + if err = srv.Serve(l); err != nil && err != http.ErrServerClosed { + log.Fatalln("server.ListenAndServe:", err) + } + }() + + <-done + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := srv.Shutdown(ctx); err != nil && err != http.ErrServerClosed { + log.Fatalln("server.Shutdown:", err) + } +} diff --git a/main_aws.go b/main_aws.go new file mode 100644 index 0000000..c81cfc6 --- /dev/null +++ b/main_aws.go @@ -0,0 +1,38 @@ +// Copyright (c) 2019, Grégoire Duchêne +// +// Use of this source code is governed by the ISC license that can be +// found in the LICENSE file. + +// +build aws,linux + +package main + +import ( + "context" + "net/http" + "path" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func redirect(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + var ( + pkg = path.Join(req.Headers["Host"], req.Path) + resp = events.APIGatewayProxyResponse{ + Body: GetBody(pkg), + Headers: map[string]string{"Content-Type": "text/html; charset=utf-8"}, + } + ) + if v, ok := req.QueryStringParameters["go-get"]; ok && v == "1" { + resp.StatusCode = http.StatusOK + } else { + resp.Headers["Location"] = "https://pkg.go.dev/" + pkg + resp.StatusCode = http.StatusFound + } + return resp, nil +} + +func main() { + lambda.Start(redirect) +} diff --git a/resp.go b/resp.go new file mode 100644 index 0000000..3403e17 --- /dev/null +++ b/resp.go @@ -0,0 +1,27 @@ +// Copyright (c) 2019, Grégoire Duchêne +// +// Use of this source code is governed by the ISC license that can be +// found in the LICENSE file. + +package main + +import ( + "fmt" + "os" + "strings" +) + +func GetBody(pkg string) string { + dest := GetDest(os.Getenv("PREFIX"), os.Getenv("DEST"), pkg) + return fmt.Sprintf(` + +go-import-redirect +`, pkg, os.Getenv("VCS"), dest) +} + +func GetDest(srcPrefix, destPrefix, pkg string) string { + srcPrefix = strings.TrimRight(srcPrefix, "/") + destPrefix = strings.TrimRight(destPrefix, "/") + path := strings.TrimLeft(strings.TrimPrefix(pkg, srcPrefix), "/") + return destPrefix + "/" + strings.Split(path, "/")[0] +} diff --git a/resp_test.go b/resp_test.go new file mode 100644 index 0000000..4dadf74 --- /dev/null +++ b/resp_test.go @@ -0,0 +1,23 @@ +// Copyright (c) 2019, Grégoire Duchêne +// +// Use of this source code is governed by the ISC license that can be +// found in the LICENSE file. + +package main + +import "testing" + +func TestGetDest(t *testing.T) { + cs := []struct{ srcPrefix, destPrefix, pkg, expected string }{ + {"src.example.com/x/", "https://example.com/git/", "src.example.com/x/foo", "https://example.com/git/foo"}, + {"src.example.com/x/", "https://example.com/git/", "src.example.com/x/foo/bar", "https://example.com/git/foo"}, + {"src.example.com/x", "https://example.com/git", "src.example.com/x/foo", "https://example.com/git/foo"}, + {"src.example.com/x", "https://example.com/git", "src.example.com/x/foo/bar", "https://example.com/git/foo"}, + } + for _, c := range cs { + actual := GetDest(c.srcPrefix, c.destPrefix, c.pkg) + if actual != c.expected { + t.Errorf("expected %s, got %s", c.expected, actual) + } + } +} diff --git a/systemd/go-import-redirect.service b/systemd/go-import-redirect.service new file mode 100644 index 0000000..0691753 --- /dev/null +++ b/systemd/go-import-redirect.service @@ -0,0 +1,16 @@ +# Copyright (c) 2020, Grégoire Duchêne +# +# Use of this file is governed by the ISC license that can be found in +# the LICENSE file. + +[Install] + WantedBy=multi-user.target + +[Service] + Environment=ADDR=%t/go-import-redirect/socket + ExecStart=go-import-redirect + DynamicUser=true + RuntimeDirectory=go-import-redirect + +[Unit] + Description=go-import-redirect -- cgit v1.2.3-70-g09d2