diff --git a/Dockerfile b/Dockerfile index 4c24986..541bae4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Dockerfile -FROM golang:1.24.4 AS builder +FROM golang:1.24.5 AS builder WORKDIR /app # Define build arguments for version, commit, and date. @@ -15,7 +15,7 @@ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.buildDate=${DATE}" -v -o ./bin/gcx ./cmd/gcx -FROM golang:1.24.4 +FROM golang:1.24.5 ENV GOTOOLCHAIN=auto ENV GOROOT=/usr/local/go diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 5a63be4..55bb567 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -27,6 +27,7 @@ import ( "github.com/minio/minio-go/v7/pkg/credentials" "github.com/sxwebdev/gcx/internal/helpers" "github.com/urfave/cli/v3" + "golang.org/x/sync/errgroup" "gopkg.in/yaml.v3" ) @@ -407,6 +408,24 @@ func getGitCommitHash() string { return strings.TrimSpace(string(out)) } +// getOutputFilename returns the output filename based on the configuration and platform. +func getOutputFilename( + usePlatformSuffix bool, + outDir, binaryBase, version, goos, goarch, goarm string, +) string { + var outputName string + if usePlatformSuffix { + if goarch == "arm" && goarm != "" { + outputName = fmt.Sprintf("%s/%s_%s_%s_%s_%s/%s", outDir, binaryBase, version, goos, goarch, goarm, binaryBase) + } else { + outputName = fmt.Sprintf("%s/%s_%s_%s_%s/%s", outDir, binaryBase, version, goos, goarch, binaryBase) + } + } else { + outputName = fmt.Sprintf("%s/%s_%s/%s", outDir, binaryBase, version, binaryBase) + } + return outputName +} + // buildBinaries performs cross-compilation of binaries according to the configuration. func buildBinaries(cfg *Config) error { // Execute hooks (e.g., "go mod tidy") @@ -504,32 +523,57 @@ func buildBinaries(cfg *Config) error { processedLdflags = append(processedLdflags, buf.String()) } + eg := errgroup.Group{} + eg.SetLimit(runtime.NumCPU()) + + log.Printf("Use %d CPU cores for building...\n", runtime.NumCPU()) + // Iterate over all combinations of GOOS and GOARCH for _, goos := range buildCfg.Goos { - for _, goarch := range buildCfg.Goarch { - // If the architecture is arm and OS is not linux, skip build - if goarch == "arm" && goos != "linux" { - continue - } - // If architecture is arm and goarm parameters are provided, iterate over them - if goarch == "arm" && len(buildCfg.Goarm) > 0 { - for _, goarm := range buildCfg.Goarm { + eg.Go(func() error { + for _, goarch := range buildCfg.Goarch { + // If the architecture is arm and OS is not linux, skip build + if goarch == "arm" && goos != "linux" { + continue + } + // If architecture is arm and goarm parameters are provided, iterate over them + if goarch == "arm" && len(buildCfg.Goarm) > 0 { + for _, goarm := range buildCfg.Goarm { + envs := os.Environ() + envs = append(envs, "GOOS="+goos, "GOARCH="+goarch, "GOARM="+goarm) + envs = append(envs, buildCfg.Env...) + outputName := getOutputFilename( + usePlatformSuffix, outDir, binaryBase, currentTag, goos, goarch, goarm, + ) + args := []string{"build"} + args = append(args, buildCfg.Flags...) + if len(processedLdflags) > 0 { + args = append(args, "-ldflags", strings.Join(processedLdflags, " ")) + } + args = append(args, "-o", outputName, buildCfg.Main) + log.Printf("Building %s for %s/%s arm%s...", binaryBase, goos, goarch, goarm) + cmd := exec.Command("go", args...) + cmd.Env = envs + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return fmt.Errorf("build error: %w", err) + } + } + } else { envs := os.Environ() - envs = append(envs, "GOOS="+goos, "GOARCH="+goarch, "GOARM="+goarm) + envs = append(envs, "GOOS="+goos, "GOARCH="+goarch) envs = append(envs, buildCfg.Env...) - var outputName string - if usePlatformSuffix { - outputName = fmt.Sprintf("%s/%s_%s_%s_%s", outDir, binaryBase, goos, goarch, goarm) - } else { - outputName = fmt.Sprintf("%s/%s", outDir, binaryBase) - } + outputName := getOutputFilename( + usePlatformSuffix, outDir, binaryBase, currentTag, goos, goarch, "", + ) args := []string{"build"} args = append(args, buildCfg.Flags...) if len(processedLdflags) > 0 { args = append(args, "-ldflags", strings.Join(processedLdflags, " ")) } args = append(args, "-o", outputName, buildCfg.Main) - log.Printf("Building %s for %s/%s arm%s...", binaryBase, goos, goarch, goarm) + log.Printf("Building %s for %s/%s...", binaryBase, goos, goarch) cmd := exec.Command("go", args...) cmd.Env = envs cmd.Stdout = os.Stdout @@ -538,32 +582,13 @@ func buildBinaries(cfg *Config) error { return fmt.Errorf("build error: %w", err) } } - } else { - envs := os.Environ() - envs = append(envs, "GOOS="+goos, "GOARCH="+goarch) - envs = append(envs, buildCfg.Env...) - var outputName string - if usePlatformSuffix { - outputName = fmt.Sprintf("%s/%s_%s_%s", outDir, binaryBase, goos, goarch) - } else { - outputName = fmt.Sprintf("%s/%s", outDir, binaryBase) - } - args := []string{"build"} - args = append(args, buildCfg.Flags...) - if len(processedLdflags) > 0 { - args = append(args, "-ldflags", strings.Join(processedLdflags, " ")) - } - args = append(args, "-o", outputName, buildCfg.Main) - log.Printf("Building %s for %s/%s...", binaryBase, goos, goarch) - cmd := exec.Command("go", args...) - cmd.Env = envs - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("build error: %w", err) - } } - } + return nil + }) + } + + if err := eg.Wait(); err != nil { + return fmt.Errorf("build error: %w", err) } } @@ -814,38 +839,37 @@ func createArchives(cfg *Config, artifactsDir string) error { return nil } - // Get current version - version := getGitTag() - // Read all files in artifacts directory files, err := os.ReadDir(artifactsDir) if err != nil { return fmt.Errorf("failed to read artifacts directory: %w", err) } + eg := errgroup.Group{} + eg.SetLimit(runtime.NumCPU()) + + log.Printf("Use %d CPU cores for creating archives...\n", runtime.NumCPU()) + // Track which files were archived archivedFiles := make(map[string]bool) - // Create archives for each file according to configuration + // Create archives for each file/directory according to configuration for _, file := range files { - if file.IsDir() { - continue - } - - // Parse filename to get platform information fileName := file.Name() + parts := strings.Split(fileName, "_") - if len(parts) < 3 { + if len(parts) < 4 { continue } - binary := parts[0] - os := parts[1] - arch := parts[2] + binaryName := parts[0] + version := parts[1] + os := parts[2] + arch := parts[3] // Template data tmplData := ArchiveTemplateData{ - Binary: binary, + Binary: binaryName, Version: version, Os: os, Arch: arch, @@ -854,29 +878,39 @@ func createArchives(cfg *Config, artifactsDir string) error { // For each archive configuration for _, archive := range cfg.Archives { // Create archive name from template - tmpl, err := template.New("archive").Parse(archive.NameTemplate) - if err != nil { - return fmt.Errorf("failed to parse archive name template: %w", err) - } + archiveName := fileName + if archive.NameTemplate != "" { + tmpl, err := template.New("archive").Parse(archive.NameTemplate) + if err != nil { + return fmt.Errorf("failed to parse archive name template: %w", err) + } + + var nameBuffer strings.Builder + if err := tmpl.Execute(&nameBuffer, tmplData); err != nil { + return fmt.Errorf("failed to execute archive name template: %w", err) + } - var nameBuffer strings.Builder - if err := tmpl.Execute(&nameBuffer, tmplData); err != nil { - return fmt.Errorf("failed to execute archive name template: %w", err) + archiveName = nameBuffer.String() } // For each archive format for _, format := range archive.Formats { - archiveName := nameBuffer.String() + "." + format - archivePath := filepath.Join(artifactsDir, archiveName) + archiveFileName := archiveName + "." + format + archivePath := filepath.Join(artifactsDir, archiveFileName) + sourcePath := filepath.Join(artifactsDir, fileName) switch format { case "tar.gz": - if err := createTarGz(filepath.Join(artifactsDir, fileName), archivePath); err != nil { - return fmt.Errorf("failed to create tar.gz archive: %w", err) - } - // Mark the source file as archived + // Mark the source file/directory as archived archivedFiles[fileName] = true - // Here you can add support for other archive formats + + eg.Go(func() error { + if err := createTarGz(sourcePath, archivePath); err != nil { + return fmt.Errorf("failed to create tar.gz archive: %w", err) + } + + return nil + }) default: log.Printf("Unsupported archive format: %s", format) } @@ -884,25 +918,34 @@ func createArchives(cfg *Config, artifactsDir string) error { } } - // Remove all source files that were archived + if err := eg.Wait(); err != nil { + return fmt.Errorf("error creating archives: %w", err) + } + + // Remove all source files/directories that were archived for _, file := range files { - if file.IsDir() { - continue - } fileName := file.Name() if archivedFiles[fileName] { filePath := filepath.Join(artifactsDir, fileName) - if err := os.Remove(filePath); err != nil { - log.Printf("Warning: failed to remove source file %s: %v", filePath, err) + if file.IsDir() { + if err := os.RemoveAll(filePath); err != nil { + log.Printf("Warning: failed to remove source directory %s: %v", filePath, err) + } + } else { + if err := os.Remove(filePath); err != nil { + log.Printf("Warning: failed to remove source file %s: %v", filePath, err) + } } } } + log.Printf("All archives created successfully.") + return nil } -// createTarGz creates a tar.gz archive from a file -func createTarGz(srcFile, destFile string) error { +// createTarGz creates a tar.gz archive from a file or directory +func createTarGz(srcPath, destFile string) error { // Create archive file archive, err := os.Create(destFile) if err != nil { @@ -918,8 +961,26 @@ func createTarGz(srcFile, destFile string) error { tw := tar.NewWriter(gw) defer tw.Close() + // Check if source is file or directory + srcInfo, err := os.Stat(srcPath) + if err != nil { + return fmt.Errorf("failed to get source info: %w", err) + } + + if srcInfo.IsDir() { + // Archive directory - use directory name as base + dirName := filepath.Base(srcPath) + return addDirToTar(tw, srcPath, dirName) + } else { + // Archive single file + return addFileToTar(tw, srcPath, filepath.Base(srcPath)) + } +} + +// addFileToTar adds a single file to tar archive +func addFileToTar(tw *tar.Writer, filePath, nameInTar string) error { // Open source file - file, err := os.Open(srcFile) + file, err := os.Open(filePath) if err != nil { return fmt.Errorf("failed to open source file: %w", err) } @@ -933,7 +994,7 @@ func createTarGz(srcFile, destFile string) error { // Create tar header header := &tar.Header{ - Name: filepath.Base(srcFile), + Name: nameInTar, Size: stat.Size(), Mode: int64(stat.Mode()), ModTime: stat.ModTime(), @@ -952,6 +1013,44 @@ func createTarGz(srcFile, destFile string) error { return nil } +// addDirToTar recursively adds directory contents to tar archive +func addDirToTar(tw *tar.Writer, dirPath, baseInTar string) error { + return filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Calculate relative path for tar + relPath, err := filepath.Rel(dirPath, path) + if err != nil { + return fmt.Errorf("failed to get relative path: %w", err) + } + + var nameInTar string + if relPath == "." { + // This is the root directory itself + nameInTar = baseInTar + } else { + // Combine with base path in tar + nameInTar = filepath.Join(baseInTar, relPath) + } + + // Handle directories + if info.IsDir() { + header := &tar.Header{ + Name: nameInTar + "/", + Mode: int64(info.Mode()), + ModTime: info.ModTime(), + Typeflag: tar.TypeDir, + } + return tw.WriteHeader(header) + } + + // Handle regular files + return addFileToTar(tw, path, nameInTar) + }) +} + // deployArtifacts executes deployment according to the configuration func deployArtifacts(cfg *Config, deployName string) error { if len(cfg.Deploys) == 0 { diff --git a/go.mod b/go.mod index fd069ec..fa083ba 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,14 @@ module github.com/sxwebdev/gcx -go 1.23.0 +go 1.24.5 require ( github.com/containrrr/shoutrrr v0.8.0 github.com/joho/godotenv v1.5.1 github.com/melbahja/goph v1.4.0 - github.com/minio/minio-go/v7 v7.0.92 - github.com/urfave/cli/v3 v3.3.3 + github.com/minio/minio-go/v7 v7.0.95 + github.com/urfave/cli/v3 v3.3.8 + golang.org/x/sync v0.16.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -18,19 +19,19 @@ require ( github.com/goccy/go-json v0.10.5 // indirect github.com/google/uuid v1.6.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/crc64nvme v1.0.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect + github.com/philhofer/fwd v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.9 // indirect github.com/rs/xid v1.6.0 // indirect github.com/tinylib/msgp v1.3.0 // indirect - golang.org/x/crypto v0.39.0 // indirect - golang.org/x/net v0.41.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect ) diff --git a/go.sum b/go.sum index 5306216..1514b0e 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -44,14 +44,14 @@ github.com/minio/crc64nvme v1.0.2 h1:6uO1UxGAD+kwqWWp7mBFsi5gAse66C4NXO8cmcVculg github.com/minio/crc64nvme v1.0.2/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.92 h1:jpBFWyRS3p8P/9tsRc+NuvqoFi7qAmTCFPoRFmobbVw= -github.com/minio/minio-go/v7 v7.0.92/go.mod h1:vTIc8DNcnAZIhyFsk8EB90AbPjj3j68aWIEQCiPj7d0= +github.com/minio/minio-go/v7 v7.0.95 h1:ywOUPg+PebTMTzn9VDsoFJy32ZuARN9zhB+K3IYEvYU= +github.com/minio/minio-go/v7 v7.0.95/go.mod h1:wOOX3uxS334vImCNRVyIDdXX9OsXDm89ToynKgqUKlo= github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= @@ -70,8 +70,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww= github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= -github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= -github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= +github.com/urfave/cli/v3 v3.3.8 h1:BzolUExliMdet9NlJ/u4m5vHSotJ3PzEqSAZ1oPMa/E= +github.com/urfave/cli/v3 v3.3.8/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -81,8 +81,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -97,8 +97,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -106,6 +106,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -120,8 +122,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -131,8 +133,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -143,16 +145,16 @@ golang.org/x/text v0.13.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.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/scripts/install.sh b/scripts/install.sh index d732093..8ee53d0 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -79,8 +79,8 @@ tar -xzf "$ASSET_NAME" || { echo "Removing archive $ASSET_NAME..." rm "$ASSET_NAME" -# Find the extracted binary file recursively, excluding the archive -EXTRACTED_BINARY=$(find . -type f -name "${TARGET_BINARY}*" ! -name "*.tar.gz" | head -n 1) +# Find the extracted binary file recursively in subdirectories +EXTRACTED_BINARY=$(find . -type f -name "${TARGET_BINARY}" ! -name "*.tar.gz" | head -n 1) if [ -z "$EXTRACTED_BINARY" ]; then echo "Error: No binary file found after extraction." @@ -89,12 +89,6 @@ fi echo "Extracted binary: $EXTRACTED_BINARY" -# If the binary is in a subdirectory, move it to the current directory -if [ "$(dirname "$EXTRACTED_BINARY")" != "." ]; then - mv "$EXTRACTED_BINARY" . - EXTRACTED_BINARY=$(basename "$EXTRACTED_BINARY") -fi - # Ensure the extracted file is executable if [ ! -x "$EXTRACTED_BINARY" ]; then echo "Error: Extracted file is not executable." @@ -107,8 +101,8 @@ if [ ! -d "$INSTALL_DIR" ]; then exit 1 fi -echo "Renaming $EXTRACTED_BINARY to $TARGET_BINARY..." -mv "$EXTRACTED_BINARY" "$TARGET_BINARY" +# Copy the binary to a temporary location for installation +cp "$EXTRACTED_BINARY" "$TARGET_BINARY" if [ -f "$INSTALL_DIR/$TARGET_BINARY" ]; then echo "Removing existing binary from $INSTALL_DIR..." @@ -121,4 +115,11 @@ sudo mv "$TARGET_BINARY" "$INSTALL_DIR/$TARGET_BINARY" echo "Making the binary executable..." sudo chmod +x "$INSTALL_DIR/$TARGET_BINARY" +# Clean up extracted files +echo "Cleaning up extracted files..." +EXTRACTED_DIR=$(dirname "$EXTRACTED_BINARY") +if [ "$EXTRACTED_DIR" != "." ]; then + rm -rf "$EXTRACTED_DIR" +fi + echo "Installation complete. You can now run $TARGET_BINARY from the terminal."