diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..49b34aa --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true + +[*.go] +indent_style = tab +insert_final_newline = false + +[Makefile] +indent_style = tab diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..28fa3a8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,24 @@ +name: Build + +on: + push: + branches: + - main +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up env + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.22 + - name: Build + run: make builds diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..7799943 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,35 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + pull-requests: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up env + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.22 + - name: Set up golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.58 + cache: true + - name: Lint + run: make lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..52fd537 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up env + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.22 + cache: true + - name: Build + run: make builds + - name: Release + run: make release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f5a5a68 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: Test + +on: + push: + branches: + - main +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up env + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.22 + - name: Test + run: make test-coverage + - name: Upload to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + files: ./coverage.out + name: codecov-umbrella diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..839f065 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Go workspace file +go.work + +/configurations +/shazam.yml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dc19184 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 mistweaver.co + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fd07d31 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +BIN_NAME=kulala-fmt + +build-windows-64: + GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w -X 'github.com/mistweaverco/kulala-fmt/cmd/kulalafmt.VERSION=$(VERSION)'" -o dist/windows/$(BIN_NAME).exe main.go +build-linux-64: + GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w -X 'github.com/mistweaverco/kulala-fmt/cmd/kulalafmt.VERSION=$(VERSION)'" -o dist/linux/$(BIN_NAME)-linux main.go +build-macos-arm64: + GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "-s -w -X 'github.com/mistweaverco/kulala-fmt/cmd/kulalafmt.VERSION=$(VERSION)'" -o dist/macos/$(BIN_NAME)-macos main.go + +builds: build-linux-64 build-macos-arm64 build-windows-64 + +lint: + golangci-lint run + +test: + if [ -n $(COLORS_ENABLED) ]; then gotest ./... ; else go test ./...; fi + +test-coverage: + go test -race -covermode=atomic -coverprofile=coverage.out ./... + +release: + gh release create --generate-notes v$(VERSION) dist/linux/$(BIN_NAME)-linux dist/macos/$(BIN_NAME)-macos dist/windows/$(BIN_NAME).exe + +build-and-install-local-debug: + go build -ldflags "-X 'github.com/mistweaverco/kulala-fmt/cmd/kulalafmt.VERSION=development'" -o dist/$(BIN_NAME) main.go + sudo mv dist/$(BIN_NAME) /usr/bin/$(BIN_NAME) + +run: + go run -ldflags "-X 'github.com/mistweaverco/kulala-fmt/cmd/kulalafmt.VERSION=development'" main.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..9094de1 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +
+ +![Kulala-fmt Logo](logo.svg) + +# kulala-fmt + +[![Go](https://img.shields.io/badge/Made%20with%20Go-00ADD8.svg?style=for-the-badge&logo=go&logoColor=ffffff)](https://golang.org) +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/mistweaverco/kulala-fmt?style=for-the-badge)](/~https://github.com/mistweaverco/kulala-fmt/releases/latest) +[![Discord](https://img.shields.io/badge/discord-join-7289da?style=for-the-badge&logo=discord)](https://discord.gg/QyVQmfY4Rt) + +[Install](#install) • [Usage](#usage) + +

+ +An opinionated 🦄 .http and .rest 🐼 files linter 💄 and formatter ⚡. + +

+ +
+ +## Install + +Just grab the latest release: + + - [Linux](/~https://github.com/mistweaverco/kulala-fmt/releases/download/latest/kulala-fmt-linux) + - [Mac](/~https://github.com/mistweaverco/kulala-fmt/releases/download/latest/kulala-fmt-macos) + - [Windows](/~https://github.com/mistweaverco/kulala-fmt/releases/download/latest/kulala-fmt.exe) + +## Usage + +Format all `.http` and `.rest` files in the current directory and its subdirectories: + +```sh +kulala-fmt +``` + +Check if all `.http` and `.rest` files in the current directory and its subdirectories are formatted: + +```sh +kulala-fmt --check +``` diff --git a/cmd/kulalafmt/about.go b/cmd/kulalafmt/about.go new file mode 100644 index 0000000..db7fae8 --- /dev/null +++ b/cmd/kulalafmt/about.go @@ -0,0 +1,19 @@ +package kulalafmt + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var aboutCmd = &cobra.Command{ + Use: "about", + Short: "Shows information about kulala-fmt", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Made with ❤️ by Marco Kellershoff - https://gorilla.moe") + }, +} + +func init() { + rootCmd.AddCommand(aboutCmd) +} \ No newline at end of file diff --git a/cmd/kulalafmt/root.go b/cmd/kulalafmt/root.go new file mode 100644 index 0000000..19d0624 --- /dev/null +++ b/cmd/kulalafmt/root.go @@ -0,0 +1,36 @@ +package kulalafmt + +import ( + "os" + + "github.com/charmbracelet/log" + "github.com/mistweaverco/kulala-fmt/internal/config" + "github.com/mistweaverco/kulala-fmt/internal/parser" + "github.com/spf13/cobra" +) + +var cfg = config.NewConfig(config.Config{}) + +var rootCmd = &cobra.Command{ + Use: "kulala-fmt", + Short: "An opinionated 🦄 .http and .rest 🐼 files linter 💄 and formatter ⚡.", + Long: "Formats and lints .http and .rest files in the current directory and subdirectories.", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + log.Info("Starting kulala-fmt 🦄", "version", VERSION) + parser.Start(cfg.GetConfigFlags()) + } + }, +} + +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.PersistentFlags().BoolVar(&cfg.Flags.DryRun, "dry-run", false, "dry run") + rootCmd.PersistentFlags().BoolVar(&cfg.Flags.Check, "check", false, "check") +} \ No newline at end of file diff --git a/cmd/kulalafmt/version.go b/cmd/kulalafmt/version.go new file mode 100644 index 0000000..053d523 --- /dev/null +++ b/cmd/kulalafmt/version.go @@ -0,0 +1,22 @@ +package kulalafmt + +import ( + "runtime" + + "github.com/charmbracelet/log" + "github.com/spf13/cobra" +) + +var VERSION string + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version number of kulala-fmt", + Run: func(cmd *cobra.Command, args []string) { + log.Info("Version", runtime.GOOS, VERSION) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} \ No newline at end of file diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b2a20e3 --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module github.com/mistweaverco/kulala-fmt + +go 1.22 + +require ( + github.com/charmbracelet/log v0.4.0 + github.com/spf13/cobra v1.8.0 +) + +require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/lipgloss v0.10.0 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/sys v0.20.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..be8f88d --- /dev/null +++ b/go.sum @@ -0,0 +1,45 @@ +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= +github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= +github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM= +github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..0086e37 Binary files /dev/null and b/icon.png differ diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..3b1eae8 --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..8a8bea8 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,18 @@ +package config + +type ConfigFlags struct { + DryRun bool + Check bool +} + +type Config struct { + Flags ConfigFlags +} + +func (c Config) GetConfigFlags() ConfigFlags { + return c.Flags +} + +func NewConfig(cfg Config) Config { + return cfg +} \ No newline at end of file diff --git a/internal/parser/parser.go b/internal/parser/parser.go new file mode 100644 index 0000000..247193f --- /dev/null +++ b/internal/parser/parser.go @@ -0,0 +1,21 @@ +package parser + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/mistweaverco/kulala-fmt/internal/config" +) + +func Start(flags config.ConfigFlags) { + // get all files in the current directory and subdirectories that match the file extension .http or .rest + files := []string{} + _ = filepath.Walk(".", func(path string, info os.FileInfo, err error) error { + if filepath.Ext(path) == ".http" || filepath.Ext(path) == ".rest" { + files = append(files, path) + } + return nil + }) + fmt.Println(files) +} \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..675eaf9 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/mistweaverco/kulala-fmt/cmd/kulalafmt" + +func main() { + kulalafmt.Execute() +} \ No newline at end of file