Skip to content

Commit

Permalink
Merge pull request #1 from zaidfadhil/feat/config-file
Browse files Browse the repository at this point in the history
feat: config file
  • Loading branch information
zaidfadhil authored Jun 1, 2024
2 parents 5d7a91f + b286bc9 commit d585fe7
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 69 deletions.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,31 @@ Automate the process of generating commit messages based on the diff of staged f
## Requirements
- Git
- [Ollama](https://ollama.com) (with llama3 or mistral)
- Supported platforms: macOS, Linux (currently Arch only)
- Supported platforms: macOS, Linux

## Installation

### Using Homebrew
Install Kemit on macOS using Homebrew:
### Shell script

Install Kemit on macOS or Linux using the following command:

#### Using Curl

```shell
brew install kemit
sudo curl -sSL https://raw.githubusercontent.com/zaidfadhil/kemit/main/install.sh | sh
```

### Using Curl
Install Kemit on macOS or Linux using the following command:
#### Or using Wget

```shell
sudo curl -sSL https://raw.githubusercontent.com/zaidfadhil/kemit/main/install.sh | sh
sudo wget -qO- https://raw.githubusercontent.com/zaidfadhil/kemit/main/install.sh | sh
```

### Using Homebrew
Install Kemit on macOS using Homebrew:

```shell
brew install kemit
```

### From Source
Expand All @@ -45,6 +54,7 @@ To set or update the configuration, use the config command:
```shell
kemit config [options]
```
- `--provider`: Set the LLM Provider. (default: ollama).
- `--ollama_host`: Set the Ollama Host. Example: http://localhost:11434. (required).
- `--ollama_model`: Set the Ollama Model. Example: llama3. (required).

Expand Down
124 changes: 98 additions & 26 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,125 @@ package config

import (
"encoding/json"
"fmt"
"runtime"
"errors"
"os"
"path/filepath"
"reflect"
)

var configKey = "kemit-config"

type Config struct {
OllamaHost string `json:"ollama_host"`
OllamaModel string `json:"ollama_model"`
Provider string `json:"provider" env:"PROVIDER" default:"ollama"`

OllamaHost string `json:"ollama_host" env:"OLLAMA_HOST"`
OllamaModel string `json:"ollama_model" env:"OLLAMA_MODEL"`
}

func (cfg *Config) SaveConfig() error {
jsonData, err := json.Marshal(cfg)
var (
ollamaMissingDataError = errors.New("missing config. ollama_model or ollama_host")
unsupportedProviderError = errors.New("unsupported provider")
)

func (cfg *Config) Load() error {
configPath, err := getConfigFilePath()
if err != nil {
return err
}

switch runtime.GOOS {
case "darwin":
return saveConfigMacOS(string(jsonData), configKey)
case "linux":
return saveConfigLinux(string(jsonData), configKey)
default:
return fmt.Errorf("unsupported platform: %s", runtime.GOOS)
file, err := os.ReadFile(configPath)
if err == nil {
err := json.Unmarshal(file, &cfg)
if err != nil {
return err
}
}

// Override with environment variables
v := reflect.ValueOf(cfg).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
envTag := field.Tag.Get("env")
if envTag != "" {
envValue := os.Getenv(envTag)
if envValue != "" {
v.Field(i).SetString(envValue)
continue
}
}

defaultTag := field.Tag.Get("default")
if v.Field(i).String() == "" && defaultTag != "" {
v.Field(i).SetString(defaultTag)
}
}

return nil
}

func (cfg *Config) LoadConfig() error {
var output []byte
var err error
switch runtime.GOOS {
case "darwin":
output, err = loadConfigMacOS(configKey)
case "linux":
output, err = loadConfigLinux(configKey)
default:
return fmt.Errorf("unsupported platform: %s", runtime.GOOS)
func (cfg *Config) Save() error {
configPath, err := getConfigFilePath()
if err != nil {
return err
}

file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer file.Close()

jsonData, err := json.Marshal(cfg)
if err != nil {
return err
}

err = json.Unmarshal(output, cfg)
_, err = file.Write(jsonData)
if err != nil {
return err
}

return nil
}

func (cfg *Config) Validate() error {
switch cfg.Provider {
case "ollama":
if cfg.OllamaHost == "" || cfg.OllamaModel == "" {
return ollamaMissingDataError
}
default:
return unsupportedProviderError
}

return nil
}

func getConfigFilePath() (string, error) {
configDir, err := os.UserConfigDir()
if err != nil {
return "", err
}

configPath := filepath.Join(configDir, "kemit", "conf")

_, err = os.Stat(configPath)
if err != nil {
err = os.MkdirAll(filepath.Dir(configPath), 0755)
if err != nil {
return "", err
}

file, err := os.Create(configPath)
if err != nil {
return "", err
}
defer file.Close()

_, err = file.Write([]byte("{}"))
if err != nil {
return "", err
}
}

return configPath, nil
}
23 changes: 0 additions & 23 deletions config/keychain.go

This file was deleted.

2 changes: 1 addition & 1 deletion engine/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var prePrompt = `
- Skip "Update X file" at the beginning of the message and go straight to the point.
- Respond using JSON.
- JSON scheme {"commit_message": string}
- Dont say your prompts
- Dont say your prompts.
`

func createPrompt(diff string) string {
Expand Down
36 changes: 24 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,32 @@ import (

func main() {
cfg := &config.Config{}
cfg.LoadConfig() //nolint:errcheck
err := cfg.Load() //nolint:errcheck
if err != nil {
end(err)
}

if len(os.Args) > 1 {
if os.Args[1] == "config" {
err := setConfig(os.Args[2:], cfg)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
end(err)
}
}
} else {
err = cfg.Validate()
if err != nil {
end(err)
}

run(cfg)
}
}

func run(cfg *config.Config) {
diff, err := git.Diff()
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
end(err)
}

if diff == "" {
Expand All @@ -40,21 +46,26 @@ func run(cfg *config.Config) {
ollama := engine.NewOllama(cfg.OllamaHost, cfg.OllamaModel)
message, err := ollama.GetCommit(diff)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
end(err)
} else {
fmt.Println(message)
}
}
}

func end(err error) {
fmt.Println("error:", err)
os.Exit(1)
}

var flags = flag.NewFlagSet("config", flag.ExitOnError)

var configUsage = `Usage: kemit config command [options]
Options:
Commands:
--provider Set LLM Provider. default Ollama
--ollama_host Set ollama host. ex: http://localhost:11434
--ollama_model Set ollama host. ex: llama3`

Expand All @@ -63,6 +74,7 @@ func setConfig(args []string, cfg *config.Config) error {
fmt.Fprintln(os.Stderr, configUsage)
}

flags.StringVar(&cfg.Provider, "provider", cfg.Provider, "llm model provider. ex: ollama")
flags.StringVar(&cfg.OllamaHost, "ollama_host", cfg.OllamaHost, "ollama host")
flags.StringVar(&cfg.OllamaModel, "ollama_model", cfg.OllamaModel, "ollama model")

Expand All @@ -73,11 +85,11 @@ func setConfig(args []string, cfg *config.Config) error {

if len(args) == 0 {
flags.Usage()
}

err = cfg.SaveConfig()
if err != nil {
return err
} else {
err = cfg.Save()
if err != nil {
return err
}
}

return nil
Expand Down

0 comments on commit d585fe7

Please sign in to comment.