From 9179a6691c72f9b86415dcfa24c65ac502fafcb1 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 26 Feb 2024 22:06:03 +0530 Subject: [PATCH 01/10] :sparkles: Added support for multiple-binary Now it's capable of handling if binary name differs from reponame and also previous state will work as same as it was working. --- README.md | 2 ++ handler/handler.go | 22 ++++++++++++++-------- handler/handler_execute.go | 8 ++++++++ scripts/install.sh.tmpl | 4 ++++ scripts/install.txt.tmpl | 1 + 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 30e356b..744a3ec 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ curl https://i.jpillora.com/! | bash * `type=homebrew` is **not** working at the moment – see [Homebrew](#homebrew) * `?insecure=1` Force `curl`/`wget` to skip certificate checks * `?as=` Force the binary to be named as this parameter value +* `?bin=` Binary name, if `repository name` and `binary name` in release differs. + * **eg:**: repo_name is **foobar** and binary name is **fb** in release then `?bin=fb`. ## Security diff --git a/handler/handler.go b/handler/handler.go index 76c0db5..ac4df6f 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -31,9 +31,9 @@ var ( ) type Query struct { - User, Program, AsProgram, Release string - MoveToPath, Search, Insecure bool - SudoMove bool // deprecated: not used, now automatically detected + User, Program, AsProgram, BinaryName, Release string + MoveToPath, Search, Insecure bool + SudoMove bool // deprecated: not used, now automatically detected } type Result struct { @@ -107,11 +107,12 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } q := Query{ - User: "", - Program: "", - Release: "", - Insecure: r.URL.Query().Get("insecure") == "1", - AsProgram: r.URL.Query().Get("as"), + User: "", + Program: "", + Release: "", + BinaryName: r.URL.Query().Get("bin"), + Insecure: r.URL.Query().Get("insecure") == "1", + AsProgram: r.URL.Query().Get("as"), } // set query from route path := strings.TrimPrefix(r.URL.Path, "/") @@ -124,6 +125,11 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { q.User, rest = splitHalf(path, "/") q.Program, q.Release = splitHalf(rest, "@") // no program? treat first part as program, use default user + + if q.AsProgram == "" && q.BinaryName != "" { + q.AsProgram = q.BinaryName + } + if q.Program == "" { q.Program = q.User q.User = h.Config.User diff --git a/handler/handler_execute.go b/handler/handler_execute.go index f04292c..3ac146a 100644 --- a/handler/handler_execute.go +++ b/handler/handler_execute.go @@ -117,6 +117,14 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { //only binary containers are supported //TODO deb,rpm etc fext := getFileExt(url) + + if q.BinaryName != "" { + //filter by binary with it's name + if !strings.Contains(ga.Name[0:len(q.BinaryName)+1], fmt.Sprint(q.BinaryName, "-")) { + continue + } + } + if fext == "" && ga.Size > 1024*1024 { fext = ".bin" // +1MB binary } diff --git a/scripts/install.sh.tmpl b/scripts/install.sh.tmpl index 5a7101d..9d74c63 100644 --- a/scripts/install.sh.tmpl +++ b/scripts/install.sh.tmpl @@ -17,6 +17,7 @@ function install { #settings USER="{{ .User }}" PROG="{{ .Program }}" + BIN_NAME="{{ .BinaryName }}" ASPROG="{{ .AsProgram }}" MOVE="{{ .MoveToPath }}" RELEASE="{{ .Release }}" @@ -93,6 +94,9 @@ function install { #got URL! download it... echo -n "{{ if .MoveToPath }}Installing{{ else }}Downloading{{ end }}" echo -n " $USER/$PROG" + if [ ! -z "$BIN_NAME" ]; then + echo -n "/$BIN_NAME" + fi if [ ! -z "$RELEASE" ]; then echo -n " $RELEASE" fi diff --git a/scripts/install.txt.tmpl b/scripts/install.txt.tmpl index bb601f5..752e4d7 100644 --- a/scripts/install.txt.tmpl +++ b/scripts/install.txt.tmpl @@ -1,6 +1,7 @@ repository: https://github.com/{{ .User }}/{{ .Program }} user: {{ .User }} program: {{ .Program }}{{if .AsProgram }} +binary-name: {{.BinaryName}} as: {{ .AsProgram }}{{end}} release: {{ .Release }} move-into-path: {{ .MoveToPath }} From c78f2265892d09962eea1012e58ac39fede9a6f0 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 26 Feb 2024 22:09:21 +0530 Subject: [PATCH 02/10] :memo: README update updated issue with formatting in readme for line query_params -> bin. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 744a3ec..38768f4 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ curl https://i.jpillora.com/! | bash * `type=homebrew` is **not** working at the moment – see [Homebrew](#homebrew) * `?insecure=1` Force `curl`/`wget` to skip certificate checks * `?as=` Force the binary to be named as this parameter value -* `?bin=` Binary name, if `repository name` and `binary name` in release differs. - * **eg:**: repo_name is **foobar** and binary name is **fb** in release then `?bin=fb`. +* `?bin=` Binary name, if **repository name** and **binary name** in release differs. + * **eg**: repo_name is **foobar** and binary name is **fb** in release then `?bin=fb`. ## Security From 63b3903fe79f4fd7bd6e43ffa38c69ecb68565e4 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 26 Feb 2024 22:35:58 +0530 Subject: [PATCH 03/10] :bulb: Updated comment corrected wrong comment. --- handler/handler_execute.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler/handler_execute.go b/handler/handler_execute.go index 3ac146a..c90eaa8 100644 --- a/handler/handler_execute.go +++ b/handler/handler_execute.go @@ -119,7 +119,7 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { fext := getFileExt(url) if q.BinaryName != "" { - //filter by binary with it's name + //filter binary with it's name if !strings.Contains(ga.Name[0:len(q.BinaryName)+1], fmt.Sprint(q.BinaryName, "-")) { continue } From d4466a84bd89af1dea57e250d2a721529e8c7c47 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 26 Feb 2024 22:47:55 +0530 Subject: [PATCH 04/10] :bug: Fixed issue with template in txt template. --- scripts/install.txt.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install.txt.tmpl b/scripts/install.txt.tmpl index 752e4d7..3894793 100644 --- a/scripts/install.txt.tmpl +++ b/scripts/install.txt.tmpl @@ -1,7 +1,7 @@ repository: https://github.com/{{ .User }}/{{ .Program }} user: {{ .User }} -program: {{ .Program }}{{if .AsProgram }} -binary-name: {{.BinaryName}} +program: {{ .Program }}{{if .BinaryName }} +binary-name: {{.BinaryName}}{{end}}{{if .AsProgram }} as: {{ .AsProgram }}{{end}} release: {{ .Release }} move-into-path: {{ .MoveToPath }} From 410560b1df67061e06dc8302b7fc58d23bd9b2a3 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Tue, 27 Feb 2024 08:10:54 +0530 Subject: [PATCH 05/10] :recycle: Refactored typo from bin to select --- README.md | 4 ++-- handler/handler.go | 22 +++++++++++----------- handler/handler_execute.go | 4 ++-- scripts/install.sh.tmpl | 6 +++--- scripts/install.txt.tmpl | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 38768f4..b171beb 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ curl https://i.jpillora.com/! | bash * `type=homebrew` is **not** working at the moment – see [Homebrew](#homebrew) * `?insecure=1` Force `curl`/`wget` to skip certificate checks * `?as=` Force the binary to be named as this parameter value -* `?bin=` Binary name, if **repository name** and **binary name** in release differs. - * **eg**: repo_name is **foobar** and binary name is **fb** in release then `?bin=fb`. +* `?select=` Select binary, if **repository name** and **binary name** in release differs. + * **eg**: repo_name is **foobar** and binary name is **fb-client** and **fb-server** in release, Then `?select=fb-client` & `?select=fb-server` accordingly. ## Security diff --git a/handler/handler.go b/handler/handler.go index ac4df6f..1a2c231 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -31,9 +31,9 @@ var ( ) type Query struct { - User, Program, AsProgram, BinaryName, Release string - MoveToPath, Search, Insecure bool - SudoMove bool // deprecated: not used, now automatically detected + User, Program, AsProgram, Selected, Release string + MoveToPath, Search, Insecure bool + SudoMove bool // deprecated: not used, now automatically detected } type Result struct { @@ -107,12 +107,12 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } q := Query{ - User: "", - Program: "", - Release: "", - BinaryName: r.URL.Query().Get("bin"), - Insecure: r.URL.Query().Get("insecure") == "1", - AsProgram: r.URL.Query().Get("as"), + User: "", + Program: "", + Release: "", + Selected: r.URL.Query().Get("select"), + Insecure: r.URL.Query().Get("insecure") == "1", + AsProgram: r.URL.Query().Get("as"), } // set query from route path := strings.TrimPrefix(r.URL.Path, "/") @@ -126,8 +126,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { q.Program, q.Release = splitHalf(rest, "@") // no program? treat first part as program, use default user - if q.AsProgram == "" && q.BinaryName != "" { - q.AsProgram = q.BinaryName + if q.AsProgram == "" && q.Selected != "" { + q.AsProgram = q.Selected } if q.Program == "" { diff --git a/handler/handler_execute.go b/handler/handler_execute.go index c90eaa8..81bc77e 100644 --- a/handler/handler_execute.go +++ b/handler/handler_execute.go @@ -118,9 +118,9 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { //TODO deb,rpm etc fext := getFileExt(url) - if q.BinaryName != "" { + if q.Selected != "" { //filter binary with it's name - if !strings.Contains(ga.Name[0:len(q.BinaryName)+1], fmt.Sprint(q.BinaryName, "-")) { + if !strings.Contains(ga.Name[0:len(q.Selected)+1], fmt.Sprint(q.Selected, "-")) { continue } } diff --git a/scripts/install.sh.tmpl b/scripts/install.sh.tmpl index 9d74c63..4c3c9e6 100644 --- a/scripts/install.sh.tmpl +++ b/scripts/install.sh.tmpl @@ -17,7 +17,7 @@ function install { #settings USER="{{ .User }}" PROG="{{ .Program }}" - BIN_NAME="{{ .BinaryName }}" + SEL_BIN="{{ .Selected }}" ASPROG="{{ .AsProgram }}" MOVE="{{ .MoveToPath }}" RELEASE="{{ .Release }}" @@ -94,8 +94,8 @@ function install { #got URL! download it... echo -n "{{ if .MoveToPath }}Installing{{ else }}Downloading{{ end }}" echo -n " $USER/$PROG" - if [ ! -z "$BIN_NAME" ]; then - echo -n "/$BIN_NAME" + if [ ! -z "$SEL_BIN" ]; then + echo -n "/$SEL_BIN" fi if [ ! -z "$RELEASE" ]; then echo -n " $RELEASE" diff --git a/scripts/install.txt.tmpl b/scripts/install.txt.tmpl index 3894793..f1688b9 100644 --- a/scripts/install.txt.tmpl +++ b/scripts/install.txt.tmpl @@ -1,7 +1,7 @@ repository: https://github.com/{{ .User }}/{{ .Program }} user: {{ .User }} -program: {{ .Program }}{{if .BinaryName }} -binary-name: {{.BinaryName}}{{end}}{{if .AsProgram }} +program: {{ .Program }}{{if .Selected }} +binary-name: {{.Selected}}{{end}}{{if .AsProgram }} as: {{ .AsProgram }}{{end}} release: {{ .Release }} move-into-path: {{ .MoveToPath }} From 9e8b9059054fcafad7e79539687e9bfbfe730b68 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Tue, 27 Feb 2024 08:13:40 +0530 Subject: [PATCH 06/10] :memo: Updated missing changes, as per last commit --- scripts/install.txt.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install.txt.tmpl b/scripts/install.txt.tmpl index f1688b9..2791377 100644 --- a/scripts/install.txt.tmpl +++ b/scripts/install.txt.tmpl @@ -1,7 +1,7 @@ repository: https://github.com/{{ .User }}/{{ .Program }} user: {{ .User }} program: {{ .Program }}{{if .Selected }} -binary-name: {{.Selected}}{{end}}{{if .AsProgram }} +selected-binary: {{.Selected}}{{end}}{{if .AsProgram }} as: {{ .AsProgram }}{{end}} release: {{ .Release }} move-into-path: {{ .MoveToPath }} From 310b6cfd3d3c59191642d00893e8dcb4625bb6c9 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Thu, 29 Feb 2024 16:15:04 +0530 Subject: [PATCH 07/10] :bug: Fixed issue with index out of bound --- handler/handler_execute.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler/handler_execute.go b/handler/handler_execute.go index 81bc77e..d0e12a7 100644 --- a/handler/handler_execute.go +++ b/handler/handler_execute.go @@ -120,7 +120,7 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { if q.Selected != "" { //filter binary with it's name - if !strings.Contains(ga.Name[0:len(q.Selected)+1], fmt.Sprint(q.Selected, "-")) { + if len(ga.Name) > len(q.Selected)+1 && !strings.Contains(ga.Name[0:len(q.Selected)+1], fmt.Sprint(q.Selected, "-")) { continue } } From 89b869c06f5ed635a8743a94476da60d2cf515d1 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Thu, 29 Feb 2024 19:14:42 +0530 Subject: [PATCH 08/10] Added support of windows. (#1) * :sparkles: Added support of windows * :memo: Docs updated added download url for windows in readme. * :construction_worker: Added docker-build to github-actions. * :bookmark: Fixed issue with ci * :bug: Fixed ci issue * :art: Improved names of jobs and ci, in workfile --- .github/workflows/ci.yml | 58 ++++++++++++++++++-- .gitignore | 1 + Dockerfile | 16 ++++++ README.md | 1 + Taskfile.yaml | 12 +++++ go.mod | 2 +- handler/handler.go | 10 +++- handler/handler_execute.go | 11 ++-- scripts/install.ps1.tmpl | 108 +++++++++++++++++++++++++++++++++++++ scripts/scripts.go | 3 ++ 10 files changed, 211 insertions(+), 11 deletions(-) create mode 100644 Dockerfile create mode 100644 Taskfile.yaml create mode 100644 scripts/install.ps1.tmpl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af7defe..21601c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,12 @@ -name: CI +name: Build & Release on: pull_request: {} push: {} workflow_dispatch: inputs: {} jobs: - ci: - name: CI + build-binary: + name: build-binary runs-on: ubuntu-latest steps: - name: Checkout @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: '1.22' check-latest: true cache: true - name: Build @@ -31,4 +31,52 @@ jobs: version: latest args: release --rm-dist --config .github/goreleaser.yml env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + docker-build: + runs-on: ubuntu-latest + name: Deploy to Docker Image + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Image Tag from branch name + if: startsWith(github.ref, 'refs/heads/release') + run: | + set +e + IMAGE_TAG=$(echo ${GITHUB_REF#refs/heads/} | sed 's/release-//g') + echo "$IMAGE_TAG" | grep -i '\-nightly$' + if [ $? -ne 0 ]; then + IMAGE_TAG="$IMAGE_TAG-nightly" + fi + set -e + + echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV + echo "OVERRIDE_PUSHED_IMAGE=true" >> $GITHUB_ENV + + - name: Create Image Tag from tag + if: startsWith(github.ref, 'refs/tags/') + run: | + IMAGE_TAG=$(echo ${GITHUB_REF#refs/tags/}) + + echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV + echo "OVERRIDE_PUSHED_IMAGE=false" >> $GITHUB_ENV + + - name: Build & Push Image + if: startsWith(github.ref, 'refs/heads/release') || startsWith(github.ref, 'refs/tags/') + run: | + image_name="ghcr.io/${{ github.repository }}" + + docker build -t $image_name:$IMAGE_TAG . + docker push $image_name:$IMAGE_TAG + diff --git a/.gitignore b/.gitignore index 32081ed..c8ff98f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ tmp/ test.sh +bin diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0444507 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:1.18.3-alpine3.16 AS base +USER 1001 +ENV GOPATH=/tmp/go +ENV GOCACHE=/tmp/go-cache +WORKDIR /tmp/app +COPY . . +RUN go mod download -x + +RUN CGO_ENABLED=0 go build -o /tmp/bin/bin-installer ./main.go +RUN chmod +x /tmp/bin/bin-installer + +FROM gcr.io/distroless/static-debian11:nonroot +LABEL org.opencontainers.image.source=https://github.com/kloudlite/bin-installer +COPY --from=base /tmp/bin/bin-installer ./bin-installer +CMD ["./bin-installer"] diff --git a/README.md b/README.md index b171beb..4f2eb5e 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ curl https://i.jpillora.com/! | bash ``` *Or you can use* `wget -qO- | bash` +*For windows use* `iwr | iex` **Path API** diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 0000000..997a75d --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,12 @@ +version: 3 + +tasks: + run: + cmds: + - go run main.go + dev: + cmds: + - nodemon -q -e 'go,tmpl' --signal SIGTERM --exec "echo '# building' && task build && echo '# build success' && ./bin/installer || exit" + build: + cmds: + - go build -o ./bin/installer main.go diff --git a/go.mod b/go.mod index da7d879..2527e28 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/jpillora/installer -go 1.18 +go 1.19 require ( github.com/jpillora/opts v1.1.2 diff --git a/handler/handler.go b/handler/handler.go index 1a2c231..61defda 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -26,6 +26,7 @@ const ( var ( isTermRe = regexp.MustCompile(`(?i)^(curl|wget)\/`) isHomebrewRe = regexp.MustCompile(`(?i)^homebrew`) + isPowershell = regexp.MustCompile(`(?i)windows`) errMsgRe = regexp.MustCompile(`[^A-Za-z0-9\ :\/\.]`) errNotFound = errors.New("not found") ) @@ -76,12 +77,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { qtype = "script" case isHomebrewRe.MatchString(ua): qtype = "ruby" + case isPowershell.MatchString(ua): + qtype = "powershell" default: qtype = "text" } } // type specific error response - showError := func(msg string, code int) { + showError := func(msg string, _ int) { // prevent shell injection cleaned := errMsgRe.ReplaceAllString(msg, "") if qtype == "script" { @@ -102,6 +105,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") ext = "txt" script = string(scripts.Text) + case "powershell": + w.Header().Set("Content-Type", "text/plain") + ext = "ps1" + script = string(scripts.Powershell) default: showError("Unknown type", http.StatusInternalServerError) return @@ -166,6 +173,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { showError(err.Error(), http.StatusBadGateway) return } + // load template t, err := template.New("installer").Parse(script) if err != nil { diff --git a/handler/handler_execute.go b/handler/handler_execute.go index d0e12a7..d93e9d5 100644 --- a/handler/handler_execute.go +++ b/handler/handler_execute.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/http" + "slices" "strings" "time" ) @@ -128,6 +129,7 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { if fext == "" && ga.Size > 1024*1024 { fext = ".bin" // +1MB binary } + switch fext { case ".bin", ".zip", ".tar.bz", ".tar.bz2", ".bz2", ".gz", ".tar.gz", ".tgz": // valid @@ -140,10 +142,11 @@ func (h *Handler) getAssetsNoCache(q Query) (string, Assets, error) { arch := getArch(ga.Name) //windows not supported yet if os == "windows" { - log.Printf("fetched asset is for windows: %s", ga.Name) - //TODO: powershell - // EG: iwr https://deno.land/x/install/install.ps1 -useb | iex - continue + // with windows system commands, only zip can be extracted + if !slices.Contains([]string{".zip"}, fext) { + log.Printf("windows don't support fileextension %s ", fext) + continue + } } //unknown os, cant use if os == "" { diff --git a/scripts/install.ps1.tmpl b/scripts/install.ps1.tmpl new file mode 100644 index 0000000..e8aa18b --- /dev/null +++ b/scripts/install.ps1.tmpl @@ -0,0 +1,108 @@ +$user = "{{.User}}" +$prog="{{ .Program }}" +$sel_bin="{{ .Selected }}" +$asProgram="{{ .AsProgram }}" +$move="{{ .MoveToPath }}" +$release="{{ .Release }}" +$insecure="{{ .Insecure }}" + +$arch = "$env:PROCESSOR_ARCHITECTURE".ToLower() +$url = "" +$fext = "" + +{{- range .Assets}} {{- if eq .OS "windows" }} +if ("{{.Arch}}" -eq $arch -and "{{.Type}}" -eq ".zip"){ + $url = "{{.URL}}" + $fext = "{{.Type}}" +} +{{- end}} {{- end}} + +if($url -eq ""){ + echo "No asset for platform windows-$arch" + return +} + + +if ($move -eq "true"){ + # $out_dir="$env:USERPROFILE\bin" + $out_dir="C:\bin" +}else{ + $out_dir="$PWD" +} + +# Create the destination directory if it doesn't exist +if (-not (Test-Path $out_dir)) { + New-Item -ItemType Directory -Force -Path $out_dir +} + +$filename = "" + +# to extract another file type rather than zip, third party application is needed. +# so as windows only capable of extracting zip file with system commands. +switch ($fext) +{ + .zip { + $filename = "app-$prog-$arch.zip"; + } +} + +if("" -eq $filename){ + echo "file extension $fext not supported" + return +} + +$zipFilePath = "$env:TEMP\$filename"; +$extPath = "$env:TEMP\$prog" + +# Downloading File +if($sel_bin){ + echo "[#] downloading $user/$prog/$sel_bin as $asProgram from $url" +}else{ + echo "[#] downloading $user/$prog as $asProgram from $url" +} + +Invoke-WebRequest -Uri $url -OutFile $zipFilePath +# Extracting zip +echo "[#] extracting file" +Expand-Archive -Path $zipFilePath -DestinationPath $extPath +# Moving To out_dir +Get-ChildItem -Path $extPath -Filter *.exe -Recurse | Move-Item -Destination $out_dir -Force +# Clean up the downloaded ZIP and temporary extracted folder +Remove-Item -Path $zipFilePath -Force +Remove-Item -Path $extPath -Recurse -Force + +echo "[#] downloaded successfully to path $out_dir" +if ($move -eq "false"){ + return +} + +echo "[#] setting $out_dir to path" +# Get the current user's PATH environment variable +$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::User) + +# Split the PATH variable into an array of individual paths +$pathArray = $currentPath -split ";" + +$hasPath = "false" +# Iterate over each path in the PATH variable +foreach ($path in $pathArray) { + # Check if the current path contains the specific directory + if ($path -eq $out_dir) { + $hasPath = "true" + } +} + +if ($hasPath -eq "false") { + # Update the PATH environment variable + if (-not [string]::IsNullOrWhiteSpace($currentPath)) { + $updatedPath = $currentPath + ";" + $out_dir + } else { + $updatedPath = $out_dir + } + + # Set the updated PATH + [System.Environment]::SetEnvironmentVariable("PATH", $updatedPath, [System.EnvironmentVariableTarget]::User) + $env:Path = $out_dir +} + +echo "[#] installation complete" diff --git a/scripts/scripts.go b/scripts/scripts.go index 1701816..6493539 100644 --- a/scripts/scripts.go +++ b/scripts/scripts.go @@ -10,3 +10,6 @@ var Shell []byte //go:embed install.rb.tmpl var Homebrew []byte + +//go:embed install.ps1.tmpl +var Powershell []byte From 0153f4873b5ce75078aa426d82b61e0a7cf65d76 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Fri, 1 Mar 2024 11:54:53 +0530 Subject: [PATCH 09/10] Fix/ci (#2) * :bug: Fix bugs --- .github/workflows/ci.yml | 6 ++++++ Dockerfile | 2 +- README.md | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21601c2..6c3a6cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,15 @@ name: Build & Release + on: pull_request: {} push: {} workflow_dispatch: inputs: {} + +permissions: + contents: write + packages: write + jobs: build-binary: name: build-binary diff --git a/Dockerfile b/Dockerfile index 0444507..e750014 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.4 -FROM golang:1.18.3-alpine3.16 AS base +FROM golang:1.22.0-alpine3.18 AS base USER 1001 ENV GOPATH=/tmp/go ENV GOCACHE=/tmp/go-cache diff --git a/README.md b/README.md index 4f2eb5e..565879b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ curl https://i.jpillora.com/! | bash ``` *Or you can use* `wget -qO- | bash` + *For windows use* `iwr | iex` **Path API** From 49e0887ffc3912602eaf6ea816ccbc3e89a4f473 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Fri, 1 Mar 2024 12:48:36 +0530 Subject: [PATCH 10/10] :bug: Fixed issue with parsing path while parsing release, user and program, was not working properly in case of no user and program provided and release is provided. --- handler/handler.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/handler/handler.go b/handler/handler.go index 61defda..6982cb0 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -128,15 +128,17 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { q.MoveToPath = true path = strings.TrimRight(path, "!") } - var rest string - q.User, rest = splitHalf(path, "/") - q.Program, q.Release = splitHalf(rest, "@") - // no program? treat first part as program, use default user + var initial string + initial, q.Release = splitHalf(path, "@") + q.User, q.Program = splitHalf(initial, "/") + + // change binary name to selected-binary if q.AsProgram == "" && q.Selected != "" { q.AsProgram = q.Selected } + // no program? treat first part as program, use default user if q.Program == "" { q.Program = q.User q.User = h.Config.User @@ -156,6 +158,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if h.Config.ForceRepo != "" { q.Program = h.Config.ForceRepo } + // validate query valid := q.Program != "" if !valid && path == "" {