Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
iton0 committed Oct 28, 2024
0 parents commit fdc98ea
Show file tree
Hide file tree
Showing 32 changed files with 1,115 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG] "
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Version [e.g. 22]

**HkUp (please complete the following information).**
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEAT] "
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/

# Test binary, built with `go test -c`
*.test

# Go workspace file
go.work
15 changes: 15 additions & 0 deletions .hkup/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

# Check for changes in Go files
if git diff --cached --name-only | grep -q '\.go$'; then
echo "Formatting Go files..."
gofmt -w .
echo ""

# Add formatted files to the staging area
git add .
else
echo "No Go files changed. Skipping formatting."
echo ""
fi

25 changes: 25 additions & 0 deletions .hkup/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# Check for modified Go files in the staged changes
echo "Checking for modified Go files..."

# Store the output of the git command in a variable
modified_go_files=$(git diff --name-only HEAD^ HEAD)

# Check if there are any Go files in the modified files
if echo "$modified_go_files" | grep -q '\.go$'; then
echo "Go files detected. Running tests..."

# Run tests
if go test ./cmd; then
echo "Tests passed."
echo ""
else
echo "Tests failed. Push cancelled."
exit 1
fi
else
echo "No Go files changed. Skipping tests."
echo ""
fi

21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 iton0

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.
90 changes: 90 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# HkUp
Your CLI tool with benefits built by [iton0](https://github.com/iton0) in [Go](https://go.dev/)!

[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/iton0/hkup-cli)](https://github.com/iton0/hkup-cli/releases/latest)
[![godoc](https://godoc.org/github.com/iton0/hkup-cli?status.svg)](http://godoc.org/github.com/iton0/hkup-cli)
[![Go Report Card](https://goreportcard.com/badge/github.com/iton0/hkup-cli)](https://goreportcard.com/report/github.com/iton0/hkup-cli)

![GitHub watchers](https://img.shields.io/github/watchers/iton0/hkup-cli?style=social)
![GitHub stars](https://img.shields.io/github/stars/iton0/hkup-cli?style=social)

## Introduction
Git hooks automate and implement processes in your workflow, increasing code quality and consistency.

However, many developers avoid git hooks due to a lack of awareness and the perceived complexity of setup, discouraging them from using this feature.

**HkUp** simplifies the management of git hooks, allowing you to focus on the logic and usage of your hooks instead.

## Installation
External Dependencies:
- `git`
- `curl`
- `grep`

Run the script below (supports Linux and macOS):

```sh
curl -sSL https://raw.githubusercontent.com/iton0/hkup-cli/main/scripts/install | sh
```
> [!Tip]
> To update HkUp, rerun the above script.
> It will replace the current version.
#### Uninstalling hkup

```sh
# Locates and deletes the HkUp binary
sh -c 'rm "$(command -v 'hkup')"'
```

</details>

## Usage Quickstart
This section provides basic information about core usage. For detailed options run `hkup --help`.

#### Initializing hkup
Run the following command in your git repository to initialize HkUp:
```sh
hkup init
```

This command creates a **.hkup** folder and sets the local **core.hooksPath** variable. If the folder already exists, it will simply update the path variable. The path is relative, ensuring that moving your repository won’t affect hook sourcing.

#### Adding & Removing hooks
Add or remove hooks easily with:
```sh
hkup add <hook-name>
hkup remove <hook-name>
```

#### Info & Docs
There are two commands that will help you with both HkUp and git hooks:

**`hkup list {hook|lang}`**
Outputs list of either available hooks or supported languages.

**`hkup doc <hook-name>`**
Opens your browser with Git documentation for the specified git hook, helping you understand its usage.

## Future TODOs
- [ ] add either flags or subcommand for init to specify dir and worktree; also if you want the hkup folder to be hidden or not
- [ ] functionality to save custom setups (ie gitdir and workdir are not in same location)
- [ ] make an update subcommand
- [ ] store custom git hooks as templates for future use (via add template subcmd)
- Allow users to create, store, and share templates for common hooks. Users can fetch these templates over the network.
- [ ] branch-specific hooks
- [ ] logo maybe?

## Contributing
HkUp welcomes contributions to enhance this CLI application! Before submitting a pull request (PR) for a new feature, please follow these steps:

1. **Create an Issue**:
If you have an idea for a new feature, please create a new issue in the repository using the **feature_request** template. Provide a clear description of the feature and its potential benefits. Please note that issues submitted without using the template may be closed without warning.

2. **Wait for Approval**:
Once you submit your issue, I’ll review it and provide feedback. If I approve the feature request, I will let you know that you're free to proceed with your PR.

3. **Submit Your PR**:
After receiving approval, you can create your PR. Be sure to reference the issue in your PR description.

Please note that PRs submitted without prior approval through an issue may be closed without merging. This process helps us manage feature requests effectively and ensures that contributions align with the project’s goals.
23 changes: 23 additions & 0 deletions cmd/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"github.com/iton0/hkup-cli/internal/git"
"github.com/iton0/hkup-cli/internal/logic"
"github.com/iton0/hkup-cli/internal/util"
"github.com/spf13/cobra"
)

var (
addCmd = &cobra.Command{
Use: "add <hook-name>",
Short: "Add git hook",
ValidArgs: util.ConvertMapKeysToSlice(git.Hooks()),
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: logic.Add,
}
)

func init() {
addCmd.Flags().StringVar(&logic.Lang, "lang", "", "supported languages for git hooks")
rootCmd.AddCommand(addCmd)
}
55 changes: 55 additions & 0 deletions cmd/add_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"
)

func TestAddCmd(t *testing.T) {
var buf bytes.Buffer
rootCmd.SetOut(&buf)

// Change directory to the parent
originalDir, err := os.Getwd()
if err != nil {
t.Fatalf("could not get current working directory: %v", err)
}
defer os.Chdir(originalDir) // Restore original directory after test

if err := os.Chdir(filepath.Join(originalDir, "..")); err != nil {
t.Fatalf("could not change to parent directory: %v", err)
}

tests := []struct {
args []string
want string
err error
}{
{
args: []string{"add", "test"},
want: "Usage:\n hkup add <hook-name> [flags]\n\nFlags:\n -h, --help help for add\n --lang string supported languages for git hooks\n\n",
err: fmt.Errorf("invalid argument \"test\" for \"hkup add\""),
},
// Add more test cases here if necessary, e.g., for error conditions
}

for _, tt := range tests {
buf.Reset() // Reset the buffer before each command execution
rootCmd.SetArgs(tt.args)

err := rootCmd.Execute()

// Check for expected error
if (err != nil) != (tt.err != nil) || (err != nil && err.Error() != tt.err.Error()) {
t.Fatalf("Command failed for args %v: got error %v, want %v", tt.args, err, tt.err)
}

got := buf.String()
if got != tt.want {
t.Errorf("got output %q, want %q for args %v", got, tt.want, tt.args)
}
}
}
23 changes: 23 additions & 0 deletions cmd/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"github.com/iton0/hkup-cli/internal/git"
"github.com/iton0/hkup-cli/internal/logic"
"github.com/iton0/hkup-cli/internal/util"
"github.com/spf13/cobra"
)

var (
docCmd = &cobra.Command{
Use: "doc <hook-name>",
Aliases: []string{"docs"},
Short: "Documentation for git hook",
ValidArgs: util.ConvertMapKeysToSlice(git.Hooks()),
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: logic.Doc,
}
)

func init() {
rootCmd.AddCommand(docCmd)
}
55 changes: 55 additions & 0 deletions cmd/doc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"
)

func TestDocCmd(t *testing.T) {
var buf bytes.Buffer
rootCmd.SetOut(&buf)

// Change directory to the parent
originalDir, err := os.Getwd()
if err != nil {
t.Fatalf("could not get current working directory: %v", err)
}
defer os.Chdir(originalDir) // Restore original directory after test

if err := os.Chdir(filepath.Join(originalDir, "..")); err != nil {
t.Fatalf("could not change to parent directory: %v", err)
}

tests := []struct {
args []string
want string
err error
}{
{
args: []string{"doc", "test"},
want: "Usage:\n hkup doc <hook-name> [flags]\n\nAliases:\n doc, docs\n\nFlags:\n -h, --help help for doc\n\n",
err: fmt.Errorf("invalid argument \"test\" for \"hkup doc\""),
},
// Add more test cases here if necessary, e.g., for error conditions
}

for _, tt := range tests {
buf.Reset() // Reset the buffer before each command execution
rootCmd.SetArgs(tt.args)

err := rootCmd.Execute()

// Check for expected error
if (err != nil) != (tt.err != nil) || (err != nil && err.Error() != tt.err.Error()) {
t.Fatalf("Command failed for args %v: got error %v, want %v", tt.args, err, tt.err)
}

got := buf.String()
if got != tt.want {
t.Errorf("got %q, want %q for args %v", got, tt.want, tt.args)
}
}
}
Loading

0 comments on commit fdc98ea

Please sign in to comment.