Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
PWZER committed Sep 26, 2024
0 parents commit 13ad80a
Show file tree
Hide file tree
Showing 19 changed files with 1,156 additions and 0 deletions.
60 changes: 60 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Build
on:
workflow_dispatch:
push:
paths-ignore:
- "README.md"
# branches:
# - main
tags:
- "v*"
pull_request_target:
branches:
- main
- dev
jobs:
build:
permissions: write-all
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
fail-fast: false
defaults:
run:
shell: bash
working-directory: .
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: Set variables
if: ${{github.ref_name=='main'}}
run: echo "VERSION=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

- name: Set variables
if: ${{github.ref_name=='' || github.ref_type=='tag'}}
run: echo "VERSION=$(git describe --tags)" >> $GITHUB_ENV

- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: "1.23.0"
check-latest: true

- name: Install UPX
uses: crazy-max/ghaction-upx@v3
with:
install-only: true

- name: Build govm
run: make all

- name: Upload Release
if: ${{ success() && github.ref_type=='tag' }}
uses: softprops/action-gh-release@v1
with:
tag: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
files: bin/govm-*
generate_release_notes: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
Empty file added LICENSE
Empty file.
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
GO_BUILD_COMMAND := go build -a -ldflags '-s -w -extldflags "-static"'

all: darwin linux

compress:
upx --best bin/* || true

darwin-amd64:
GOOS=darwin GOARCH=amd64 $(GO_BUILD_COMMAND) -o bin/govm-darwin-amd64 .

darwin-arm64:
GOOS=darwin GOARCH=arm64 $(GO_BUILD_COMMAND) -o bin/govm-darwin-arm64 .

darwin: darwin-amd64 darwin-arm64

linux-amd64:
GOOS=linux GOARCH=amd64 $(GO_BUILD_COMMAND) -o bin/govm-linux-amd64 .

linux-arm64:
GOOS=linux GOARCH=arm64 $(GO_BUILD_COMMAND) -o bin/govm-linux-arm64 .

linux: linux-amd64 linux-arm64
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# GoVM

Golang multiple version manager

## Installation

```bash
go install github.com/PWZER/govm@latest
```

Or download the binary from [releases](https://github.com/PWZER/govm/releases/latest)

```bash
# example
wget https://github.com/PWZER/govm/releases/download/v0.1.0/govm-linux-amd64 -O govm

# make it executable
chmod +x govm
```

## Usage

```bash
# display info
govm

# list remote versions
govm ls --remote

# list local versions
govm ls

# install a version
govm install go1.23.0

# use a version
govm use go1.23.0
```
39 changes: 39 additions & 0 deletions cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright © 2024 PWZER <[email protected]>
*/
package cmd

import (
"fmt"

"github.com/PWZER/govm/internal"
"github.com/spf13/cobra"
)

var (
installMirror string
)

var installCmd = &cobra.Command{
Use: "install",
Short: "Install specified version of golang",
Long: "Install specified version of golang",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
for _, version := range args {
if err := internal.Install(version, installMirror); err != nil {
return err
}
}
return nil
}
return fmt.Errorf("please specify the version of golang you want to install")
},
}

func init() {
rootCmd.AddCommand(installCmd)
installCmd.Flags().StringVarP(&installMirror, "mirror", "m", internal.DefaultMirror,
"Specify the mirror you want to download the golang package.")
}
66 changes: 66 additions & 0 deletions cmd/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright © 2024 PWZER <[email protected]>
*/
package cmd

import (
"fmt"
"sort"
"strings"

"github.com/PWZER/govm/internal"
"github.com/spf13/cobra"
"golang.org/x/mod/semver"
)

var (
listRemoteVersions bool
includeAllVersions bool
)

var listCmd = &cobra.Command{
Use: "ls",
Short: "list versions for golang.",
Long: "list versions for golang.",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) (err error) {
var getVersionsFunc func(bool) ([]*internal.Version, error)
if listRemoteVersions {
getVersionsFunc = internal.GetRemoteVersions
} else {
getVersionsFunc = internal.GetLocalVersions
}

versions, err := getVersionsFunc(!includeAllVersions)
if err != nil {
return err
}

sort.Slice(versions, func(i, j int) bool {
return semver.Compare(strings.ReplaceAll(versions[i].Version, "go", "v"),
strings.ReplaceAll(versions[j].Version, "go", "v")) < 0
})

curBinaryFile, err := internal.GetCurrentUseVersionBinaryFile()
if err != nil {
return err
}

for _, v := range versions {
if (listRemoteVersions && v.Local != nil) ||
(!listRemoteVersions && v.Local.BinaryFile == curBinaryFile) {
fmt.Printf("[*] %s\n", v.Version)
} else {
fmt.Printf("[ ] %s\n", v.Version)
}
}
return nil
},
}

func init() {
rootCmd.AddCommand(listCmd)

listCmd.Flags().BoolVar(&listRemoteVersions, "remote", false, "list remote versions")
listCmd.Flags().BoolVar(&includeAllVersions, "all", false, "list all versions")
}
48 changes: 48 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright © 2024 PWZER <[email protected]>
*/
package cmd

import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"

"github.com/PWZER/govm/internal"
"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "govm",
Short: "A simple version manager for golang.",
Long: "A simple version manager for golang.",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) (err error) {
binaryFile, err := internal.GetCurrentUseVersionBinaryFile()
if err != nil {
return err
}

version := "Unknown"
names := strings.Split(filepath.ToSlash(binaryFile), "/")
for i := len(names) - 1; i >= 0; i-- {
if matched, _ := regexp.MatchString(`^go\d+(\.\d+(\.\d+)?)?$`, names[i]); matched {
version = names[i]
break
}
}

fmt.Println(" Working directory:", internal.Config.WorkingDir)
fmt.Println("Current use version:", version)
return nil
},
}

func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
31 changes: 31 additions & 0 deletions cmd/use.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright © 2024 PWZER <[email protected]>
*/
package cmd

import (
"fmt"

"github.com/PWZER/govm/internal"
"github.com/spf13/cobra"
)

var useCmd = &cobra.Command{
Use: "use",
Short: "Specify the version of golang to use",
Long: "Specify the version of golang to use",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("Please specify the version of golang to use, just like 'govm use 1.16.3'")
}
version := args[0]
if version == "" {
return fmt.Errorf("Please specify the version of golang to use")
}
return internal.UseGoVersion(version)
},
}

func init() {
rootCmd.AddCommand(useCmd)
}
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/PWZER/govm

go 1.23.0

toolchain go1.21.0

require (
github.com/spf13/cobra v1.8.1
golang.org/x/mod v0.21.0
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
43 changes: 43 additions & 0 deletions internal/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package internal

import (
"os"
"path/filepath"
)

type ConfigType struct {
WorkingDir string `json:"working_dir"`
}

var Config ConfigType

func init() {
defaultWorkingDir := filepath.Join(getUserHomeDir(), ".govm")

Config = ConfigType{
WorkingDir: defaultWorkingDir,
}
}

func getUserHomeDir() string {
homeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
return homeDir
}

func getWorkingDir() string {
if _, err := os.Stat(Config.WorkingDir); os.IsNotExist(err) {
os.MkdirAll(Config.WorkingDir, 0755)
}
return Config.WorkingDir
}

func getCacheDir() string {
cacheDir := filepath.Join(getWorkingDir(), "cache")
if _, err := os.Stat(cacheDir); os.IsNotExist(err) {
os.MkdirAll(cacheDir, 0755)
}
return cacheDir
}
Loading

0 comments on commit 13ad80a

Please sign in to comment.