Compare commits
	
		
			13 Commits
		
	
	
		
			v0.1.1
			...
			renovate/c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3382351a9c | |||
| 48fe4ba396 | |||
| 535d13222d | |||
| 
						 | 
					a008e20cc7 | ||
| 
						 | 
					0f80b14869 | ||
| 
						 | 
					c594257c4f | ||
| 
						 | 
					bd6c0a0bc6 | ||
| 
						 | 
					04c79984c0 | ||
| 
						 | 
					534834680b | ||
| 
						 | 
					a6737c1871 | ||
| 
						 | 
					07e156dd3f | ||
| 
						 | 
					6459152833 | ||
| 
						 | 
					86f00a4c9c | 
							
								
								
									
										46
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								.drone.yml
									
									
									
									
									
								
							@@ -1,46 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
kind: pipeline
 | 
					 | 
				
			||||||
type: kubernetes
 | 
					 | 
				
			||||||
name: Containeraztion latest
 | 
					 | 
				
			||||||
steps:
 | 
					 | 
				
			||||||
- name: Docker build
 | 
					 | 
				
			||||||
  resources:
 | 
					 | 
				
			||||||
    limits:
 | 
					 | 
				
			||||||
      cpu: 100
 | 
					 | 
				
			||||||
      memory: 2048MiB
 | 
					 | 
				
			||||||
  when:
 | 
					 | 
				
			||||||
   branch:
 | 
					 | 
				
			||||||
     - main
 | 
					 | 
				
			||||||
  privileged: true
 | 
					 | 
				
			||||||
  settings:
 | 
					 | 
				
			||||||
    registry: git.badhouseplants.net
 | 
					 | 
				
			||||||
    username: allanger
 | 
					 | 
				
			||||||
    password: 
 | 
					 | 
				
			||||||
      from_secret: GITEA_TOKEN
 | 
					 | 
				
			||||||
    repo: git.badhouseplants.net/badhouseplants/clever-install
 | 
					 | 
				
			||||||
    tags: latest
 | 
					 | 
				
			||||||
    platforms: 
 | 
					 | 
				
			||||||
      - linux/arm64
 | 
					 | 
				
			||||||
      - linux/amd64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
steps:
 | 
					 | 
				
			||||||
- name: Docker build
 | 
					 | 
				
			||||||
  image: thegeeklab/drone-docker-buildx
 | 
					 | 
				
			||||||
  trigger:
 | 
					 | 
				
			||||||
    event:
 | 
					 | 
				
			||||||
      - tag
 | 
					 | 
				
			||||||
  resources:
 | 
					 | 
				
			||||||
    limits:
 | 
					 | 
				
			||||||
      cpu: 100
 | 
					 | 
				
			||||||
      memory: 2048MiB
 | 
					 | 
				
			||||||
  privileged: true
 | 
					 | 
				
			||||||
  settings:
 | 
					 | 
				
			||||||
    registry: git.badhouseplants.net
 | 
					 | 
				
			||||||
    username: allanger
 | 
					 | 
				
			||||||
    password: 
 | 
					 | 
				
			||||||
      from_secret: GITEA_TOKEN
 | 
					 | 
				
			||||||
    repo: git.badhouseplants.net/badhouseplants/clever-install
 | 
					 | 
				
			||||||
    tags: latest
 | 
					 | 
				
			||||||
    platforms: 
 | 
					 | 
				
			||||||
      - linux/arm64
 | 
					 | 
				
			||||||
      - linux/amd64
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								.github/workflows/build-version.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-version.yaml
									
									
									
									
										vendored
									
									
								
							@@ -50,7 +50,7 @@ jobs:
 | 
				
			|||||||
        uses: actions/download-artifact@v3
 | 
					        uses: actions/download-artifact@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Set version variable
 | 
					      - name: Set version variable
 | 
				
			||||||
        run: echo "CLIN_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
 | 
					        run: echo "VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Rename release to avoid name conflict
 | 
					      - name: Rename release to avoid name conflict
 | 
				
			||||||
        run: ./scripts/rename_releases.sh
 | 
					        run: ./scripts/rename_releases.sh
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
name: "Stable container"
 | 
					name: "Latest container"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
on:
 | 
					on:
 | 
				
			||||||
  push:
 | 
					  push:
 | 
				
			||||||
@@ -43,7 +43,6 @@ jobs:
 | 
				
			|||||||
          platforms: linux/amd64,linux/arm64
 | 
					          platforms: linux/amd64,linux/arm64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: |
 | 
					          tags: |
 | 
				
			||||||
            ghcr.io/${{ github.repository }}:stable
 | 
					 | 
				
			||||||
            ghcr.io/${{ github.repository }}:latest
 | 
					            ghcr.io/${{ github.repository }}:latest
 | 
				
			||||||
          labels: |
 | 
					          labels: |
 | 
				
			||||||
            action_id=${{ github.action }}
 | 
					            action_id=${{ github.action }}
 | 
				
			||||||
							
								
								
									
										1
									
								
								.github/workflows/container-version.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/container-version.yaml
									
									
									
									
										vendored
									
									
								
							@@ -47,6 +47,7 @@ jobs:
 | 
				
			|||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: |
 | 
					          tags: |
 | 
				
			||||||
            ghcr.io/${{ github.repository }}:${{ env.TAG }}
 | 
					            ghcr.io/${{ github.repository }}:${{ env.TAG }}
 | 
				
			||||||
 | 
					            ghcr.io/${{ github.repository }}:stable
 | 
				
			||||||
          labels: |
 | 
					          labels: |
 | 
				
			||||||
            action_id=${{ github.action }}
 | 
					            action_id=${{ github.action }}
 | 
				
			||||||
            action_link=${{ env.LINK }}
 | 
					            action_link=${{ env.LINK }}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1009
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1009
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							@@ -1,13 +1,17 @@
 | 
				
			|||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "dudo"
 | 
					name = "dudo"
 | 
				
			||||||
version = "0.1.1"
 | 
					version = "0.2.2"
 | 
				
			||||||
edition = "2021"
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
clap = { version = "4.1.1", features = ["derive", "env"] }
 | 
					clap = { version = "4.1.1", features = ["derive", "env"] }
 | 
				
			||||||
handlebars = "4.3.1"
 | 
					handlebars = "5.1.0"
 | 
				
			||||||
env_logger = "0.10.0"
 | 
					env_logger = "0.11.2"
 | 
				
			||||||
log = "0.4.17"
 | 
					log = "0.4.17"
 | 
				
			||||||
http = "0.2.8"
 | 
					 | 
				
			||||||
serde = { version = "1.0.126", features = ["derive"] }
 | 
					serde = { version = "1.0.126", features = ["derive"] }
 | 
				
			||||||
reqwest = { version = "0.11", features = ["json", "blocking"] }
 | 
					reqwest = { version = "0.11", features = ["json", "blocking", "rustls"] }
 | 
				
			||||||
 | 
					serde_yaml = "0.9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dev-dependencies]
 | 
				
			||||||
 | 
					tempfile = "3.4.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,13 +1,17 @@
 | 
				
			|||||||
FROM rust:1.66.1-alpine3.17 as builder
 | 
					FROM rust:1.76.0-slim-bookworm as builder
 | 
				
			||||||
WORKDIR /src
 | 
					WORKDIR /src
 | 
				
			||||||
RUN apk update && apk add --no-cache libressl-dev musl-dev gcc
 | 
					RUN apt-get update &&\
 | 
				
			||||||
 | 
							apt-get install -y libssl-dev gcc musl pkg-config
 | 
				
			||||||
COPY ./ .
 | 
					COPY ./ .
 | 
				
			||||||
RUN cargo build --release
 | 
					RUN rustup default nightly && rustup update
 | 
				
			||||||
 | 
					RUN cargo build --release --jobs 2 -Z sparse-registry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM alpine:3.17.1
 | 
					FROM debian:stable
 | 
				
			||||||
COPY --from=builder /src/target/release/dudo /bin/dudo
 | 
					COPY --from=builder /src/target/release/dudo /bin/dudo
 | 
				
			||||||
RUN apk update && apk add --no-cache libressl-dev libc6-compat
 | 
					RUN apt-get update &&\
 | 
				
			||||||
 | 
							apt-get install -y openssl ca-certificates &&\
 | 
				
			||||||
 | 
							apt-get clean -y
 | 
				
			||||||
RUN chmod +x /bin/dudo
 | 
					RUN chmod +x /bin/dudo
 | 
				
			||||||
WORKDIR /workdir
 | 
					WORKDIR /workdir
 | 
				
			||||||
ENTRYPOINT ["/bin/dudo"]
 | 
					ENTRYPOINT ["/bin/dudo"]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										73
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								README.md
									
									
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# What's it about?
 | 
					# What's it about?
 | 
				
			||||||
It's just a tool to make downloading binaries for different platforms easier. 
 | 
					It's just a tool to make downloading binaries for different platforms easier. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## For example
 | 
					## For example
 | 
				
			||||||
If you want to build a docker image, but you want to make it available on different platforms. But your tool needs other tools as dependencies, e.g. `helm`.
 | 
					If you want to build a docker image, but you want to make it available on different platforms. But your tool needs other tools as dependencies, e.g. `helm`.
 | 
				
			||||||
To install helm on Alpine you need to use curl, wget, or something. You need to choose a version, an operating system, and an architecture. For me, it was obvious that you must be able to use `uname -m`...
 | 
					To install helm on Alpine you need to use curl, wget, or something. You need to choose a version, an operating system, and an architecture. For me, it was obvious that you must be able to use `uname -m`...
 | 
				
			||||||
@@ -32,15 +33,15 @@ Prebuilt binaries exist for **Linux x86_64** and **MacOS arm64** and **x86_64**
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Don't forget to add the binary to $PATH
 | 
					Don't forget to add the binary to $PATH
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
$ curl https://raw.githubusercontent.com/allanger/clever-install/main/scripts/download_dudo.sh | bash
 | 
					$ curl https://raw.githubusercontent.com/allanger/dumb-downloader/main/scripts/download_dudo.sh | bash
 | 
				
			||||||
$ dudo -h
 | 
					$ dudo --help
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
### Docker
 | 
					### Docker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can use the `latest` or a `tagged` docker image
 | 
					You can use the `latest` or a `tagged` docker image
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
$ docker pull ghcr.io/allanger/clever-install:latest
 | 
					$ docker pull ghcr.io/allanger/dumb-downloader:latest
 | 
				
			||||||
$ docker run ghcr.io/allanger/clever-install:latest dudo -h
 | 
					$ docker run ghcr.io/allanger/dumb-downloader:latest dudo -h
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Build from source
 | 
					### Build from source
 | 
				
			||||||
@@ -48,7 +49,67 @@ $ docker run ghcr.io/allanger/clever-install:latest dudo -h
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
$ cargo build --release
 | 
					$ cargo build --release
 | 
				
			||||||
``` 
 | 
					``` 
 | 
				
			||||||
2. Run `gum help`
 | 
					2. Run `dudo --help`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# How to use?
 | 
					# How to use?
 | 
				
			||||||
To be done
 | 
					## Custom configurations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In case the default config is not doing the trick for you, you can pass a custom configuration, for example, you need to download a package "package-linux-amd64_x86_64_intel_v1.0.3" and this kind of name for an architecture is not supported by the `dudo`, then you can create a config file like 
 | 
				
			||||||
 | 
					```yaml
 | 
				
			||||||
 | 
					# config-example.yaml
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					os:
 | 
				
			||||||
 | 
					  macos:
 | 
				
			||||||
 | 
					    - macos
 | 
				
			||||||
 | 
					    - darwin
 | 
				
			||||||
 | 
					    - mac
 | 
				
			||||||
 | 
					    - apple
 | 
				
			||||||
 | 
					  linux:
 | 
				
			||||||
 | 
					    - linux
 | 
				
			||||||
 | 
					  windows:
 | 
				
			||||||
 | 
					    - windows
 | 
				
			||||||
 | 
					  freebsd:
 | 
				
			||||||
 | 
					    - freebsd
 | 
				
			||||||
 | 
					arch:
 | 
				
			||||||
 | 
					  x86_64:
 | 
				
			||||||
 | 
					    - x86_64
 | 
				
			||||||
 | 
					    - amd64
 | 
				
			||||||
 | 
					    - amd
 | 
				
			||||||
 | 
					    - intel
 | 
				
			||||||
 | 
					    - amd64_x86_64_intel
 | 
				
			||||||
 | 
					  aarch64:
 | 
				
			||||||
 | 
					    - aarch64
 | 
				
			||||||
 | 
					    - arm64
 | 
				
			||||||
 | 
					    - m1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And execute `dudo -l "package-{{ os }}-{{ arch }}-{{ version}}" -p v1.0.3 -d /tmp/package` and dudo will download the package to the `/tmp/package` then, 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Dockerfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The initial intetion for developing this was to use it for writing multi-architecture Dockerfiles for my another projects. I needed to download `helm` and `helmfile` for `arm64` and `amd64`. And I couldn't come up with good simple script for settings environment variables that would point to the the correct url, because `uname -m` wasn't giving me results that I would need. I was thinkg about writing a script to create some kind of map for different architectures, but then I thought that is was already not the first time I was having that problem and I decided to come up with a tool. And here is example, how one could use it in a `Dockerfile`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```DOCKERFILE
 | 
				
			||||||
 | 
					ARG BASE_VERSION=latest
 | 
				
			||||||
 | 
					FROM ghcr.io/allanger/dumb-downloader as builder
 | 
				
			||||||
 | 
					RUN apt-get update -y && apt-get install tar -y
 | 
				
			||||||
 | 
					ARG HELM_VERSION=v3.10.3
 | 
				
			||||||
 | 
					ARG HELMFILE_VERSION=0.151.0
 | 
				
			||||||
 | 
					ENV RUST_LOG=info
 | 
				
			||||||
 | 
					RUN dudo -l "https://github.com/helmfile/helmfile/releases/download/v{{ version }}/helmfile_{{ version }}_{{ os }}_{{ arch }}.tar.gz" -i /tmp/helmfile.tar.gz -p $HELMFILE_VERSION
 | 
				
			||||||
 | 
					RUN dudo -l "https://get.helm.sh/helm-{{ version }}-{{ os }}-{{ arch }}.tar.gz" -i /tmp/helm.tar.gz -p $HELM_VERSION
 | 
				
			||||||
 | 
					RUN tar -xf /tmp/helm.tar.gz  -C /tmp && rm -f /tmp/helm.tar.gz 
 | 
				
			||||||
 | 
					RUN tar -xf /tmp/helmfile.tar.gz  -C /tmp && rm -f /tmp/helmfile.tar.gz 
 | 
				
			||||||
 | 
					RUN mkdir /out && for bin in `find /tmp | grep helm`; do cp $bin /out/; done
 | 
				
			||||||
 | 
					RUN chmod +x /out/helm
 | 
				
			||||||
 | 
					RUN chmod +x /out/helmfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/allanger/check-da-helm-base:${BASE_VERSION} 
 | 
				
			||||||
 | 
					COPY --from=builder /out/ /usr/bin
 | 
				
			||||||
 | 
					RUN apk update --no-cache && apk add --no-cache jq bash
 | 
				
			||||||
 | 
					ENTRYPOINT ["cdh"]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the builder it is downloading dependencies that are needed in my final docker image.
 | 
				
			||||||
							
								
								
									
										23
									
								
								example/config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								example/config.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					os:
 | 
				
			||||||
 | 
					  macos:
 | 
				
			||||||
 | 
					    - macos
 | 
				
			||||||
 | 
					    - darwin
 | 
				
			||||||
 | 
					    - mac
 | 
				
			||||||
 | 
					    - apple
 | 
				
			||||||
 | 
					  linux:
 | 
				
			||||||
 | 
					    - linux
 | 
				
			||||||
 | 
					  windows:
 | 
				
			||||||
 | 
					    - windows
 | 
				
			||||||
 | 
					  freebsd:
 | 
				
			||||||
 | 
					    - freebsd
 | 
				
			||||||
 | 
					arch:
 | 
				
			||||||
 | 
					  x86_64:
 | 
				
			||||||
 | 
					    - x86_64
 | 
				
			||||||
 | 
					    - amd64
 | 
				
			||||||
 | 
					    - amd
 | 
				
			||||||
 | 
					    - intel
 | 
				
			||||||
 | 
					  aarch64:
 | 
				
			||||||
 | 
					    - aarch64
 | 
				
			||||||
 | 
					    - arm64
 | 
				
			||||||
 | 
					    - m1
 | 
				
			||||||
							
								
								
									
										3
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "$schema": "https://docs.renovatebot.com/renovate-schema.json"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
echo 'renaming dudo to dudo-$VERSION-$SYSTEM format'
 | 
					echo 'renaming dudo to dudo-$VERSION-$SYSTEM format'
 | 
				
			||||||
mkdir -p release
 | 
					mkdir -p release
 | 
				
			||||||
echo "version - $CLIN_VERSION"
 | 
					echo "version - $VERSION"
 | 
				
			||||||
for BUILD in build*; do
 | 
					for BUILD in build*; do
 | 
				
			||||||
  SYSTEM=$(echo $BUILD | sed -e 's/build-//g')
 | 
					  SYSTEM=$(echo $BUILD | sed -e 's/build-//g')
 | 
				
			||||||
  echo "system - $SYSTEM"
 | 
					  echo "system - $SYSTEM"
 | 
				
			||||||
  cp $BUILD/dudo release/dudo-$CLIN_VERSION-$SYSTEM
 | 
					  cp $BUILD/dudo release/dudo-$VERSION-$SYSTEM
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
ls release
 | 
					ls release
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										244
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										244
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,68 +1,254 @@
 | 
				
			|||||||
use clap::Parser;
 | 
					use clap::Parser;
 | 
				
			||||||
use handlebars::Handlebars;
 | 
					use handlebars::Handlebars;
 | 
				
			||||||
use http::{StatusCode};
 | 
					 | 
				
			||||||
use log::{error, info};
 | 
					use log::{error, info};
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
 | 
					    collections::HashMap,
 | 
				
			||||||
    env::consts::{ARCH, OS},
 | 
					    env::consts::{ARCH, OS},
 | 
				
			||||||
    fs::File,
 | 
					    fmt::Display,
 | 
				
			||||||
    io,
 | 
					    fs::{File, OpenOptions},
 | 
				
			||||||
 | 
					    io::{self},
 | 
				
			||||||
    process::exit,
 | 
					    process::exit,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Result<T> = std::result::Result<T, DudoError>;
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					enum DudoError {
 | 
				
			||||||
 | 
					    IoError(io::Error),
 | 
				
			||||||
 | 
					    SerdeYamlError(serde_yaml::Error),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl From<io::Error> for DudoError {
 | 
				
			||||||
 | 
					    fn from(error: io::Error) -> Self {
 | 
				
			||||||
 | 
					        DudoError::IoError(error)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<serde_yaml::Error> for DudoError {
 | 
				
			||||||
 | 
					    fn from(error: serde_yaml::Error) -> Self {
 | 
				
			||||||
 | 
					        DudoError::SerdeYamlError(error)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Display for DudoError {
 | 
				
			||||||
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
 | 
					        match self {
 | 
				
			||||||
 | 
					            DudoError::SerdeYamlError(err) => write!(f, "{}", err),
 | 
				
			||||||
 | 
					            DudoError::IoError(err) => write!(f, "{}", err),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CONFIG: &str = "
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					os:
 | 
				
			||||||
 | 
					  macos:
 | 
				
			||||||
 | 
					    - macos
 | 
				
			||||||
 | 
					    - darwin
 | 
				
			||||||
 | 
					    - mac
 | 
				
			||||||
 | 
					    - apple
 | 
				
			||||||
 | 
					  linux:
 | 
				
			||||||
 | 
					    - linux
 | 
				
			||||||
 | 
					  windows:
 | 
				
			||||||
 | 
					    - windows
 | 
				
			||||||
 | 
					  freebsd:
 | 
				
			||||||
 | 
					    - freebsd
 | 
				
			||||||
 | 
					arch:
 | 
				
			||||||
 | 
					  x86_64:
 | 
				
			||||||
 | 
					    - x86_64
 | 
				
			||||||
 | 
					    - amd64
 | 
				
			||||||
 | 
					    - amd
 | 
				
			||||||
 | 
					    - intel
 | 
				
			||||||
 | 
					  aarch64:
 | 
				
			||||||
 | 
					    - aarch64
 | 
				
			||||||
 | 
					    - arm64
 | 
				
			||||||
 | 
					    - m1
 | 
				
			||||||
 | 
					";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Maybe not that clever, but at least not dumb. Download binaries for defferent architectures easier
 | 
					/// Maybe not that clever, but at least not dumb. Download binaries for defferent architectures easier
 | 
				
			||||||
#[derive(Parser)]
 | 
					#[derive(Parser)]
 | 
				
			||||||
#[clap(author = "allanger <allanger@zohomail.com>", version, about, long_about = None, arg_required_else_help(true))]
 | 
					#[clap(author = "allanger <allanger@zohomail.com>", version, about, long_about = None, arg_required_else_help(true))]
 | 
				
			||||||
struct Args {
 | 
					struct Args {
 | 
				
			||||||
    /// A templated link for downloading
 | 
					    /// A templated link for downloading
 | 
				
			||||||
    #[clap(short, long, env = "CLIN_LINK")]
 | 
					    #[clap(short, long, env = "DUDO_LINK_TEMPLATE")]
 | 
				
			||||||
    link_template: String,
 | 
					    link_template: String,
 | 
				
			||||||
    /// Version that you want to download
 | 
					    /// Version that you want to download
 | 
				
			||||||
    #[clap(short, long, env = "CLIN_VERSION")]
 | 
					    #[clap(short, long, env = "DUDO_PACKAGE_VERSION")]
 | 
				
			||||||
    package_version: String,
 | 
					    package_version: String,
 | 
				
			||||||
    /// Path to download
 | 
					    /// Path to download
 | 
				
			||||||
    #[clap(short, long, env = "CLIN_PATH")]
 | 
					    #[clap(short, long, env = "DUDO_DOWNLOADPATH")]
 | 
				
			||||||
    install_path: String,
 | 
					    download_path: String,
 | 
				
			||||||
 | 
					    /// Path to dudo config file
 | 
				
			||||||
 | 
					    #[clap(short, long, default_value = "", env = "DUDO_CONFIG")]
 | 
				
			||||||
 | 
					    config: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Serialize, Deserialize)]
 | 
					#[derive(Clone, Serialize, Deserialize)]
 | 
				
			||||||
struct Values {
 | 
					struct SystemValues {
 | 
				
			||||||
    version: String,
 | 
					    version: String,
 | 
				
			||||||
    os: String,
 | 
					    os: String,
 | 
				
			||||||
    arch: String,
 | 
					    arch: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Serialize, Deserialize, Debug)]
 | 
				
			||||||
 | 
					struct Config {
 | 
				
			||||||
 | 
					    os: HashMap<String, Vec<String>>,
 | 
				
			||||||
 | 
					    arch: HashMap<String, Vec<String>>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
 | 
					    // Initial steps
 | 
				
			||||||
    env_logger::init();
 | 
					    env_logger::init();
 | 
				
			||||||
    let args = Args::parse();
 | 
					    let args = Args::parse();
 | 
				
			||||||
    let mut reg = Handlebars::new();
 | 
					 | 
				
			||||||
    reg.register_template_string("download_link", args.link_template)
 | 
					 | 
				
			||||||
        .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let archs: Vec<String> = match ARCH {
 | 
					    // Register download url template
 | 
				
			||||||
        "x86_64" => vec!["x86_64".to_string(), "amd64".to_string()],
 | 
					    let mut reg = Handlebars::new();
 | 
				
			||||||
        "aarch64" => vec!["aarch64".to_string(), "arm64".to_string()],
 | 
					    match reg.register_template_string("download_link", args.link_template) {
 | 
				
			||||||
        _ => {
 | 
					        Ok(_) => info!("Your template is successfully registered"),
 | 
				
			||||||
            error!("Unknown architecture");
 | 
					        Err(err) => error!("{}", err),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set system aliases
 | 
				
			||||||
 | 
					    let config = match parse_config(args.config) {
 | 
				
			||||||
 | 
					        Ok(config) => config,
 | 
				
			||||||
 | 
					        Err(err) => {
 | 
				
			||||||
 | 
					            error!("{}", err);
 | 
				
			||||||
            exit(1);
 | 
					            exit(1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for arch in archs {
 | 
					    info!("Running on {} {}", OS, ARCH);
 | 
				
			||||||
        let version = args.package_version.clone();
 | 
					    let oss = config.os.get(&OS.to_string()).unwrap();
 | 
				
			||||||
        let os = OS.to_string();
 | 
					    let archs = config.arch.get(&ARCH.to_string()).unwrap();
 | 
				
			||||||
        let values = Values { arch, os, version };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let link = reg.render("download_link", &values).unwrap();
 | 
					    for arch in archs {
 | 
				
			||||||
        info!("Trying to download from {}", link.clone());
 | 
					        for os in oss {
 | 
				
			||||||
        let mut resp = reqwest::blocking::get(link).unwrap();
 | 
					            let version = args.package_version.clone();
 | 
				
			||||||
        if resp.status() == StatusCode::OK {
 | 
					            let values = SystemValues {
 | 
				
			||||||
            info!("Response is 200, I'll try to download");
 | 
					                arch: arch.clone(),
 | 
				
			||||||
            let mut out = File::create(args.install_path).expect("failed to create file");
 | 
					                os: os.clone(),
 | 
				
			||||||
            io::copy(&mut resp, &mut out).expect("failed to copy content");
 | 
					                version,
 | 
				
			||||||
            break;
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let link = reg.render("download_link", &values).unwrap();
 | 
				
			||||||
 | 
					            info!("Trying to download from {}", link.clone());
 | 
				
			||||||
 | 
					            let mut resp = reqwest::blocking::get(link).unwrap();
 | 
				
			||||||
 | 
					            if resp.status().is_success() {
 | 
				
			||||||
 | 
					                info!("Response is 200, I'll try to download");
 | 
				
			||||||
 | 
					                let mut out =
 | 
				
			||||||
 | 
					                    File::create(args.download_path.clone()).expect("failed to create file");
 | 
				
			||||||
 | 
					                io::copy(&mut resp, &mut out).expect("failed to copy content");
 | 
				
			||||||
 | 
					                exit(0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            info!("Will try another name for arch, because response is not 200");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        info!("Will try another name for arch, because response is not 200");
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn parse_config(config_path: String) -> Result<Config> {
 | 
				
			||||||
 | 
					    let config_res: std::result::Result<Config, _>;
 | 
				
			||||||
 | 
					    if config_path.is_empty() {
 | 
				
			||||||
 | 
					        config_res = serde_yaml::from_str(CONFIG);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        let f = OpenOptions::new().write(false).read(true).open(config_path);
 | 
				
			||||||
 | 
					        let f = match f {
 | 
				
			||||||
 | 
					            Ok(file) => file,
 | 
				
			||||||
 | 
					            Err(err) => {
 | 
				
			||||||
 | 
					                return Err(err.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        config_res = serde_yaml::from_reader(f);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    match config_res {
 | 
				
			||||||
 | 
					        Ok(config) => Ok(config),
 | 
				
			||||||
 | 
					        Err(err) => Err(err.into()),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use crate::parse_config;
 | 
				
			||||||
 | 
					    use std::io::Write;
 | 
				
			||||||
 | 
					    use tempfile::NamedTempFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn parse_config_default() {
 | 
				
			||||||
 | 
					        let config = parse_config("".to_owned()).unwrap();
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("linux").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["linux".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("windows").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["windows".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("macos").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec![
 | 
				
			||||||
 | 
					                "macos".to_string(),
 | 
				
			||||||
 | 
					                "darwin".to_string(),
 | 
				
			||||||
 | 
					                "mac".to_string(),
 | 
				
			||||||
 | 
					                "apple".to_string(),
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.arch.get("x86_64").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec![
 | 
				
			||||||
 | 
					                "x86_64".to_string(),
 | 
				
			||||||
 | 
					                "amd64".to_string(),
 | 
				
			||||||
 | 
					                "amd".to_string(),
 | 
				
			||||||
 | 
					                "intel".to_string(),
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.arch.get("aarch64").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["aarch64".to_string(), "arm64".to_string(), "m1".to_string(),]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn parse_config_custom() {
 | 
				
			||||||
 | 
					        let config = "
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					os:
 | 
				
			||||||
 | 
					  macos:
 | 
				
			||||||
 | 
					    - macos
 | 
				
			||||||
 | 
					  linux:
 | 
				
			||||||
 | 
					    - linux
 | 
				
			||||||
 | 
					  windows:
 | 
				
			||||||
 | 
					    - windows
 | 
				
			||||||
 | 
					  freebsd:
 | 
				
			||||||
 | 
					    - freebsd
 | 
				
			||||||
 | 
					arch:
 | 
				
			||||||
 | 
					  x86_64:
 | 
				
			||||||
 | 
					    - x86_64
 | 
				
			||||||
 | 
					  aarch64:
 | 
				
			||||||
 | 
					    - aarch64
 | 
				
			||||||
 | 
					        ";
 | 
				
			||||||
 | 
					        let mut file = NamedTempFile::new().unwrap();
 | 
				
			||||||
 | 
					        writeln!(file, "{}", config).unwrap();
 | 
				
			||||||
 | 
					        let path = file.into_temp_path();
 | 
				
			||||||
 | 
					        // It's looking damn not right
 | 
				
			||||||
 | 
					        let config = parse_config(path.to_str().unwrap().clone().to_string()).unwrap();
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("linux").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["linux".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("windows").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["windows".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.os.get("macos").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["macos".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.arch.get("x86_64").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["x86_64".to_string()]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            config.arch.get("aarch64").unwrap().clone(),
 | 
				
			||||||
 | 
					            vec!["aarch64".to_string()]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user