diff --git a/.github/workflows/bin.yml b/.github/workflows/bin.yml deleted file mode 100644 index ba9233f..0000000 --- a/.github/workflows/bin.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Check bin/auto-commit - -on: - pull_request: - branches: [main] - -jobs: - validate-binary: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Check that bin/auto-commit exists - run: | - if [ ! -f "bin/auto-commit" ]; then - echo "[-] bin/auto-commit not found." - exit 1 - fi - echo "[+] bin/auto-commit exists." - - - name: (Optional) Run binary with --help or version - run: | - ./bin/auto-commit --help || echo "Help output not available (optional check)." diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 47cde8a..d2a4182 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,14 @@ jobs: fetch-depth: 0 tags: true + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.23.0' + + - name: Build auto-commit binary + run: go build -o ./bin/auto-commit . + - name: Set up Git run: | git config user.name "github-actions" diff --git a/.gitignore b/.gitignore index 4054b74..a117e26 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ Debug/ Release/ *.exe bindir/ +bin/ diff --git a/.husky/pre-push b/.husky/pre-push index fa42ab4..6a35828 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -9,9 +9,8 @@ cd "$REPO_ROOT" make fmt make lint make check -make buildrelease git add . -git commit -m "build 'binary file' for release/push bin/auto-commit" +# git commit -m "build 'binary file' for release/push bin/auto-commit" echo "[+] Success pre-push!" diff --git a/README.md b/README.md index 8d04036..8f083e3 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,10 @@ git auto git push ``` -- 2 Option +- 2 Commands ```bash -git auto -w OR git auto --watch - Comit observer, you don't have to think and write more `git auto` -w (--watch) will figure it out when to make a comit and commit it yourself! +git auto -w - Comit observer, you dont have to think and write more `git auto` -w (--watch) will figure it out when to make a comit and commit it yourself! +git auto -v - Viewing the current version of auto-commit +git auto -u - Upgrade to the new auto-commit version ``` diff --git a/bin/auto-commit b/bin/auto-commit deleted file mode 100644 index 5227bf1..0000000 Binary files a/bin/auto-commit and /dev/null differ diff --git a/define.go b/define.go index 023e1f1..d19c224 100644 --- a/define.go +++ b/define.go @@ -5,6 +5,11 @@ import "time" const ( MAX_LINE_LENGTH uint16 = 1024 MAX_COMMIT_LENGTH uint16 = 300 - MAX_COMMIT_LENGTH_WATCHER uint16 = 60 - COMMIT_TIME time.Duration = 17 * time.Second + MAX_COMMIT_LENGTH_WATCHER uint16 = 45 + COMMIT_TIME time.Duration = 15 * time.Second + + GITHUB_API_REPO_URL string = "https://api.github.com/repos/thefuture-industries/git-auto-commit" + VERSION_FILE string = "auto-commit.version.txt" + BINARY_AUTO_COMMIT string = "auto-commit" + GITHUB_REPO_URL string = "https://github.com/thefuture-industries/git-auto-commit" ) diff --git a/files.go b/files.go index 06ab7d0..d7bfe2a 100644 --- a/files.go +++ b/files.go @@ -1 +1,75 @@ package main + +import ( + "fmt" + "io" + "net/http" + "os" + "strings" +) + +func DownloadBinAutoCommit(url, destPath string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + out, err := os.Create(destPath) + if err != nil { + return err + } + defer out.Close() + + if errProgress := DownloadProgress(resp, out); errProgress != nil { + return errProgress + } + + _, err = io.Copy(out, resp.Body) + return err +} + +func DownloadProgress(resp *http.Response, file *os.File) error { + size := resp.ContentLength + if size <= 0 { + _, err := io.Copy(file, resp.Body) + return err + } + + const progressBarWidth = 70 + var downloaded int64 = 0 + buffer := make([]byte, 32*1024) + + for { + n, errRead := resp.Body.Read(buffer) + if n > 0 { + nw, ew := file.Write(buffer[0:n]) + if nw > 0 { + downloaded += int64(nw) + progress := float64(downloaded) * 100 / float64(size) + hashes := int(progress * progressBarWidth) + + fmt.Printf("\r[%-*s] %3.0f%%", progressBarWidth, strings.Repeat("#", hashes), progress*100) + } + + if ew != nil { + return ew + } + + if n != nw { + return io.ErrShortWrite + } + } + + if errRead != nil { + if errRead == io.EOF { + break + } + + return errRead + } + } + + fmt.Println() + return nil +} diff --git a/main.go b/main.go index 827e6ce..228cfbf 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,10 @@ func main() { } WatchCommit(path) + } else if len(os.Args) > 1 && (os.Args[1] == "-v" || os.Args[1] == "--version") { + GetVersion() + } else if len(os.Args) > 1 && (os.Args[1] == "-u" || os.Args[1] == "--update") { + AutoCommitUpdate() } else { AutoCommit() } diff --git a/scripts/install-linux-auto-commit.sh b/scripts/install-linux-auto-commit.sh index df0debf..6fe53d4 100644 --- a/scripts/install-linux-auto-commit.sh +++ b/scripts/install-linux-auto-commit.sh @@ -22,7 +22,11 @@ BINARY_NAME="auto-commit" HOOKS_DIR=".git/hooks" HOOK_PATH="$HOOKS_DIR/$BINARY_NAME" -URL="https://github.com/thefuture-industries/git-auto-commit/blob/main/bin/auto-commit?raw=true" +VERSION_URL="https://api.github.com/repos/thefuture-industries/git-auto-commit/releases/latest" +TAG=$(curl -s "$VERSION_URL" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + +URL="https://github.com/thefuture-industries/git-auto-commit/releases/download/$TAG/auto-commit" +VERSION_FILE="$HOOKS_DIR/auto-commit.version.txt" if [ ! -d .git ]; then echo "[!] There is no .git. Run it in the root of the Git repository." @@ -39,7 +43,9 @@ if [[ "$answer" == "Y" || "$answer" == "y" ]]; then git config --local alias.auto '!./.git/hooks/auto-commit' - echo -e "\e[32mSuccessful installation and settings alias for auto-commit.\e[0m" + echo "$TAG" > "$VERSION_FILE" + + echo -e "\e[32mSuccessful installation version $TAG and settings alias for auto-commit.\e[0m" echo "" echo -e "\e[33mMore detailed: https://github.com/thefuture-industries/git-auto-commit\e[0m" echo -e "\e[33mNow you can run: git auto\e[0m" diff --git a/scripts/install-windows-auto-commit.ps1 b/scripts/install-windows-auto-commit.ps1 index 8b6ab46..66886e3 100644 --- a/scripts/install-windows-auto-commit.ps1 +++ b/scripts/install-windows-auto-commit.ps1 @@ -19,7 +19,9 @@ Set-Location $gitRoot $HookName = "auto-commit" -$Url = "https://github.com/thefuture-industries/git-auto-commit/blob/main/bin/auto-commit?raw=true" +$versionUrl = "https://api.github.com/repos/thefuture-industries/git-auto-commit/releases/latest" +$tag = (Invoke-RestMethod -Uri $versionUrl -UseBasicParsing).tag_name +$Url = "https://github.com/thefuture-industries/git-auto-commit/releases/download/$tag/auto-commit" if (-not (Test-Path ".git/hooks")) { Write-Error "The current directory is not a Git repository." @@ -39,7 +41,10 @@ try { git config --local alias.auto '!./.git/hooks/auto-commit' - Write-Host "Successful installation and settings alias for auto-commit." -ForegroundColor Green + $versionFile = Join-Path -Path ".git/hooks" -ChildPath "auto-commit.version.txt" + Set-Content -Path $versionFile -Value $tag + + Write-Host "Successful installation version $tag and settings alias for auto-commit." -ForegroundColor Green Write-Host "" Write-Host "More detailed: https://github.com/thefuture-industries/git-auto-commit" diff --git a/update.go b/update.go new file mode 100644 index 0000000..384f15a --- /dev/null +++ b/update.go @@ -0,0 +1,69 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "path/filepath" + "strings" +) + +func AutoCommitUpdate() { + root, err := GetGitRoot() + if err != nil { + ErrorLogger(err) + return + } + + versionFile := filepath.Join(root, ".git", "hooks", VERSION_FILE) + + version, err := os.ReadFile(versionFile) + if err != nil { + ErrorLogger(fmt.Errorf("unknown version for auto-commit, please re-install: %w", err)) + return + } + + resp, err := http.Get(GITHUB_REPO_URL + "/releases/latest") + if err != nil { + ErrorLogger(fmt.Errorf("could not check latest version: %w", err)) + return + } + defer resp.Body.Close() + + var data struct { + TagName string `json:"tag_name"` + } + if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { + ErrorLogger(fmt.Errorf("could not parse version info: %w", err)) + return + } + + if strings.TrimSpace(string(version)) == strings.TrimSpace(data.TagName) { + fmt.Printf("\033[92myou have the latest version installed %s\033[0m\n", strings.TrimSpace(data.TagName)) + return + } + + fmt.Printf("updating to version %s...\n", strings.TrimSpace(data.TagName)) + + binaryURL := GITHUB_REPO_URL + "/releases/download/" + strings.TrimSpace(data.TagName) + "/" + BINARY_AUTO_COMMIT + destPath := filepath.Join(root, ".git", "hooks", "auto-commit") + + if err := DownloadBinAutoCommit(binaryURL, destPath); err != nil { + ErrorLogger(fmt.Errorf("failed to download new binary: %w", err)) + return + } + + err = os.Chmod(destPath, 0755) + if err != nil { + ErrorLogger(fmt.Errorf("failed to set executable permission: %w", err)) + return + } + + err = os.WriteFile(versionFile, []byte(strings.TrimSpace(data.TagName)), 0644) + if err != nil { + ErrorLogger(fmt.Errorf("failed to update version file: %w", err)) + return + } + + fmt.Println("successful upgrade to version ", strings.TrimSpace(data.TagName)) +} diff --git a/version.go b/version.go new file mode 100644 index 0000000..9342f4d --- /dev/null +++ b/version.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "path/filepath" + "strings" +) + +func GetVersion() { + root, err := GetGitRoot() + if err != nil { + ErrorLogger(fmt.Errorf("could not get git root: %w", err)) + return + } + + versionFile := filepath.Join(root, ".git", "hooks", VERSION_FILE) + + version, err := os.ReadFile(versionFile) + if err != nil { + ErrorLogger(fmt.Errorf("unknown version for auto-commit, please re-install: %w", err)) + return + } + + fmt.Println("[git auto-commit] current version:", string(version)) + + resp, err := http.Get(GITHUB_API_REPO_URL + "/releases/latest") + if err != nil { + ErrorLogger(fmt.Errorf("could not check latest version: %w", err)) + return + } + defer resp.Body.Close() + + var data struct { + TagName string `json:"tag_name"` + } + if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { + ErrorLogger(fmt.Errorf("could not parse version info: %w", err)) + return + } + + if strings.TrimSpace(string(version)) != strings.TrimSpace(data.TagName) { + fmt.Printf("\033[94ma new version is available: %s\033[0m\n", strings.TrimSpace(data.TagName)) + fmt.Printf("\033[92mplease update! 'git auto -u'\033[0m\n") + } +}