From b71a04b7f502af2d56a22899f2874bf3117bb594 Mon Sep 17 00:00:00 2001 From: Dana Woodman Date: Sun, 25 Feb 2024 18:54:07 -0800 Subject: [PATCH] Reorg, add goreleaser, update readme --- .github/workflows/release.yml | 93 ++++--------------- .gitignore | 2 +- .goreleaser.yaml | 39 ++++++++ Makefile | 8 +- README.md | 24 +++-- cmd/cng/main.go | 12 +-- internal/{domain/skip.go => skipper.go} | 2 +- .../{domain/skip_test.go => skipper_test.go} | 8 +- internal/{watch.go => watcher.go} | 18 +--- test/e2e_test.go | 7 -- 10 files changed, 87 insertions(+), 126 deletions(-) create mode 100644 .goreleaser.yaml rename internal/{domain/skip.go => skipper.go} (98%) rename internal/{domain/skip_test.go => skipper_test.go} (93%) rename internal/{watch.go => watcher.go} (91%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b8de74..4e72806 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,91 +1,34 @@ -name: Build and Release +name: Build and Release Go Project on: push: tags: - "v*" +permissions: + contents: write + packages: write + jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - goos: [darwin, windows, linux] - goarch: [amd64, arm64] - exclude: - - goos: darwin - goarch: arm64 - steps: - - name: Check out code - uses: actions/checkout@v2 + - name: Checkout code + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 - with: - go-version: "^1.17" - - - name: Build Project - run: | - export GOOS=${{ matrix.goos }} - export GOARCH=${{ matrix.goarch }} - go build -o build/my_app_${{ matrix.goos }}_${{ matrix.goarch }} - - - name: Upload Artifacts - uses: actions/upload-artifact@v2 + uses: actions/setup-go@v5 with: - name: my_app_${{ matrix.goos }}_${{ matrix.goarch }} - path: build/my_app_${{ matrix.goos }}_${{ matrix.goarch }} + go-version-file: "go.mod" - release: - runs-on: ubuntu-latest - needs: build - steps: - - name: Check out code - uses: actions/checkout@v2 - - - name: Download Artifacts - uses: actions/download-artifact@v2 - with: - path: build/ - - - name: Create Release - id: create_release - uses: actions/create-release@v1 - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false - - - name: Upload Release Assets - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build/my_app_darwin_amd64 - asset_name: my_app_darwin_amd64 - asset_content_type: application/octet-stream - - - name: Upload Release Assets - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build/my_app_windows_amd64 - asset_name: my_app_windows_amd64 - asset_content_type: application/octet-stream - - - name: Upload Release Assets - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build/my_app_linux_amd64 - asset_name: my_app_linux_amd64 - asset_content_type: application/octet-stream + - name: Run tests + run: make test - - name: Upload Release Assets - uses: actions/upload-release-asset@v1 + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build/my_app_linux_arm64 - asset_name: my_app_linux_arm64 - asset_content_type: application/octet-stream + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index e27209c..1a07445 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ .DS_Store -bin/ \ No newline at end of file +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..210c8b9 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj + +version: 1 + +before: + hooks: + - go mod tidy + +builds: + - main: ./cmd/cng/ + env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" diff --git a/Makefile b/Makefile index 7c64396..6031ae4 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,11 @@ test: .PHONY: test-e2e test-e2e: - @go test -v ./test/... + @gtc -v ./test/... .PHONY: test-unit test-unit: - @go test -v ./internal/... + @gtc -v ./internal/... .PHONY: watch-test watch-test: @@ -32,8 +32,8 @@ watch-e2e-test: .PHONY: build build: - @CGO_ENABLED=0 go build -a -gcflags=all="-l -B" -ldflags="-s -w" -o bin/cng ./cmd/cng - @echo "🎉 cng built to bin/cng" + @CGO_ENABLED=0 go build -a -gcflags=all="-l -B" -ldflags="-s -w" -o dist/cng ./cmd/cng + @echo "🎉 cng built to dist/cng" .PHONY: install install: diff --git a/README.md b/README.md index 98c936c..656b13b 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,9 @@ ## Install -### Binary installs +Download a [release](https://github.com/danawoodman/cng/releases) for your platform and add it to your path. -**Coming soon(?):** Downloads for macOS, Linux, and Windows, homebrew, apt, etc... - -### Install with Golang +Or just install with Golang: ```shell go install github.com/danawoodman/cng @@ -18,10 +16,10 @@ go install github.com/danawoodman/cng ```shell # Run `go run ./cmd/myapp` when any .go or .html files change. -# `-i` runs the command once on load without any event +# `-i` runs the command once initially, without any event # `-k`` kills running processes between changes # The command you want to run is followed by the `--` separator: -cng -i -k '**/*.go' 'templates/**/*.html' -- go run ./cmd/myapp +cng -ik '**/*.go' 'templates/**/*.html' -- go run ./cmd/myapp # Run tests when your source or tests change: cng 'app/**/*.{ts,tsx}' '**/*.test.ts' -- npm test @@ -52,13 +50,13 @@ Usage: cng [flags] [paths] -- [command] Flags: - -a, --add Execute command for initially added paths - -d, --delay int Delay between process changes in milliseconds - -e, --exclude strings Exclude matching paths - -h, --help Help for cng - -i, --initial Execute command once on load without any event - -k, --kill Kill running processes between changes - -v, --verbose Enable verbose logging + -a, --add execute command for initially added paths + -d, --delay int delay between process changes in milliseconds + -e, --exclude strings exclude matching paths + -h, --help help for cng + -i, --initial execute command once on load without any event + -k, --kill kill running processes between changes + -v, --verbose enable verbose logging ``` ## Notes and Limitations diff --git a/cmd/cng/main.go b/cmd/cng/main.go index 4ceef15..b376d04 100644 --- a/cmd/cng/main.go +++ b/cmd/cng/main.go @@ -32,12 +32,12 @@ func init() { // Don't parse commands after the "--" separator rootCmd.Flags().SetInterspersed(false) - rootCmd.PersistentFlags().BoolVarP(&add, "add", "a", false, "Execute command for initially added paths") - rootCmd.PersistentFlags().BoolVarP(&initial, "initial", "i", false, "Execute command once on load without any event") - rootCmd.PersistentFlags().StringSliceVarP(&exclude, "exclude", "e", []string{}, "Exclude matching paths") - rootCmd.PersistentFlags().BoolVarP(&kill, "kill", "k", false, "Kill running processes between changes") - rootCmd.PersistentFlags().IntVarP(&delay, "delay", "d", 0, "Delay between process changes in milliseconds") - rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") + rootCmd.PersistentFlags().BoolVarP(&add, "add", "a", false, "execute command for initially added paths") + rootCmd.PersistentFlags().BoolVarP(&initial, "initial", "i", false, "execute command once on load without any event") + rootCmd.PersistentFlags().StringSliceVarP(&exclude, "exclude", "e", []string{}, "exclude matching paths") + rootCmd.PersistentFlags().BoolVarP(&kill, "kill", "k", false, "kill running processes between changes") + rootCmd.PersistentFlags().IntVarP(&delay, "delay", "d", 0, "delay between process changes in milliseconds") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "enable verbose logging") // TODO: implement more onchange features: // rootCmd.PersistentFlags().BoolVar(&noExclude, "no-exclude", false, "Disable default exclusion") // rootCmd.PersistentFlags().IntVarP(&jobs, "jobs", "j", 1, "Set max concurrent processes") diff --git a/internal/domain/skip.go b/internal/skipper.go similarity index 98% rename from internal/domain/skip.go rename to internal/skipper.go index dfad37a..378a402 100644 --- a/internal/domain/skip.go +++ b/internal/skipper.go @@ -1,4 +1,4 @@ -package domain +package internal import ( "fmt" diff --git a/internal/domain/skip_test.go b/internal/skipper_test.go similarity index 93% rename from internal/domain/skip_test.go rename to internal/skipper_test.go index 13e6302..f0f41a7 100644 --- a/internal/domain/skip_test.go +++ b/internal/skipper_test.go @@ -1,14 +1,14 @@ -package domain_test +package internal_test import ( "path/filepath" "testing" - "github.com/danawoodman/cng/internal/domain" + "github.com/danawoodman/cng/internal" "github.com/stretchr/testify/assert" ) -func Test(t *testing.T) { +func TestSkipper(t *testing.T) { tests := []struct { name string workDir string @@ -92,7 +92,7 @@ func Test(t *testing.T) { for _, e := range test.exclusions { exclusions = append(exclusions, filepath.Join(test.workDir, e)) } - s := domain.NewSkipper(test.workDir, exclusions) + s := internal.NewSkipper(test.workDir, exclusions) for path, val := range test.expected { p := filepath.Join(test.workDir, path) assert.Equal(t, val, s.ShouldExclude(p), "exclude patterns %v should skip path '%s' but didn't", test.exclusions, path) diff --git a/internal/watch.go b/internal/watcher.go similarity index 91% rename from internal/watch.go rename to internal/watcher.go index 059d555..86606c4 100644 --- a/internal/watch.go +++ b/internal/watcher.go @@ -10,16 +10,14 @@ import ( "github.com/bmatcuk/doublestar/v4" "github.com/charmbracelet/log" - "github.com/danawoodman/cng/internal/domain" "github.com/fsnotify/fsnotify" ) +// todo: inject logging using WithLogger var logger = log.NewWithOptions(os.Stderr, log.Options{ Prefix: "cng", }) -// todo: inject logging using WithLogger - type WatcherConfig struct { ExcludePaths []string Command []string @@ -35,7 +33,7 @@ type Watcher struct { cmd *exec.Cmd lastCmdStart time.Time log func(msg string, args ...interface{}) - skipper domain.Skipper + skipper Skipper workDir string } @@ -53,7 +51,7 @@ func NewWatcher(config WatcherConfig) Watcher { config: config, // todo: make this injectable workDir: workDir, - skipper: domain.NewSkipper(workDir, config.Exclude), + skipper: NewSkipper(workDir, config.Exclude), log: func(msg string, args ...interface{}) { if config.Verbose { logger.Info(msg, args...) @@ -63,8 +61,6 @@ func NewWatcher(config WatcherConfig) Watcher { } func (w Watcher) Start() { - // fmt.Println("WORKING DIRECTORY:", wd) - w.log("Command to run:", "cmd", w.config.Command) w.log("Watched paths:", "paths", w.config.ExcludePaths) @@ -77,10 +73,7 @@ func (w Watcher) Start() { w.log("Adding watched paths:", "paths", w.config.ExcludePaths) for _, pattern := range w.config.ExcludePaths { expandedPath := filepath.Join(w.workDir, pattern) - // fmt.Println("EXPANDED PATH:", expandedPath) - rootDir, _ := doublestar.SplitPattern(expandedPath) - // fmt.Println("ROOT DIR:", rootDir) if err := watcher.Add(rootDir); err != nil { w.exit("Could not watch root directory:", "dir", rootDir, " error:", err) @@ -170,11 +163,6 @@ func (w Watcher) Start() { w.kill() } - // if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Remove == fsnotify.Remove { - // watcher.Remove(event.Name) // Attempt to remove in case it's deleted - // addFiles() // Re-add files to catch any new/removed files - // } - w.runCmd() case <-sig: diff --git a/test/e2e_test.go b/test/e2e_test.go index 813d814..4598cc2 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -112,13 +112,6 @@ func TestCng(t *testing.T) { }) } - // List all files in dir: - // files, err := os.ReadDir(dir) - // assert.NoError(t, err) - // for _, file := range files { - // fmt.Println("FILE:", file.Name()) - // } - time.Sleep(300 * time.Millisecond) // Send SIGINT to the process