-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic ability to clone repo and run ledger command
- Loading branch information
Showing
13 changed files
with
461 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/usr/bin/env sh | ||
|
||
export TELEGRAM_TOKEN="YOUR_TELEGRAM_TOKEN" | ||
export URL="YOUR_URL" | ||
export GIT_URL="YOUR_GIT_URL" | ||
## Fine-grained personal access tokens for repo with RW Contents scope | ||
export GIT_ACCESS_TOKEN="YOUR_GIT" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
/dev/dev-env-setup.sh | ||
.env | ||
/tmp/ | ||
/.env.test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
run: | ||
timeout: 5m | ||
output: | ||
format: tab | ||
skip-dirs: | ||
- vendor | ||
|
||
linters-settings: | ||
govet: | ||
check-shadowing: true | ||
goconst: | ||
min-len: 2 | ||
min-occurrences: 2 | ||
misspell: | ||
locale: US | ||
lll: | ||
line-length: 140 | ||
gocritic: | ||
enabled-tags: | ||
- performance | ||
- style | ||
- experimental | ||
- opinionated | ||
- diagnostic | ||
- security | ||
|
||
linters: | ||
enable: | ||
- sloglint | ||
- bodyclose | ||
- megacheck | ||
- revive | ||
- govet | ||
- unconvert | ||
- gas | ||
- gocyclo | ||
- dupl | ||
- misspell | ||
- unparam | ||
- unused | ||
- typecheck | ||
- ineffassign | ||
- stylecheck | ||
- gochecknoinits | ||
- exportloopref | ||
- gocritic | ||
- nakedret | ||
- gosimple | ||
- prealloc | ||
- goconst | ||
fast: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package bot | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/go-git/go-git/v5" | ||
"github.com/go-git/go-git/v5/plumbing/transport/http" | ||
) | ||
|
||
func cloneRepo(url, token, workdir string) error { | ||
log.Printf("[INFO] cloning %s..\n", url) | ||
|
||
_, err := git.PlainClone(workdir, false, &git.CloneOptions{ | ||
URL: url, | ||
Auth: &http.BasicAuth{ | ||
Username: "username", | ||
Password: token, | ||
}, | ||
Depth: 2}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("unable to clone %s into %s: %v", url, workdir, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func FetchOrCloneRepo(url, token, workdir string) error { | ||
r, err := git.PlainOpen(workdir) | ||
|
||
if err == git.ErrRepositoryNotExists { | ||
return cloneRepo(url, token, workdir) | ||
} | ||
if err != nil { | ||
return fmt.Errorf("unable to ensure repo %s: %v", workdir, err) | ||
} | ||
|
||
log.Printf("[INFO] fetching repo %s..\n", url) | ||
err = r.Fetch(&git.FetchOptions{ | ||
Auth: &http.BasicAuth{ | ||
Username: "username", | ||
Password: token, | ||
}, | ||
Depth: 2}) | ||
|
||
if err == git.NoErrAlreadyUpToDate { | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("unable to fetch %s: %v", workdir, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
const ledgerBinary = "/opt/homebrew/bin/ledger" | ||
|
||
func ExecLedgerCmd(url, token, workdir, file string, arg ...string) (string, error) { | ||
log.Printf("[INFO] executing ledger command: %s on file: %s\n", arg, file) | ||
|
||
err := FetchOrCloneRepo(url, token, workdir) | ||
|
||
if err != nil { | ||
return "", fmt.Errorf("unable to ensure repo: %v", err) | ||
} | ||
|
||
arg = append([]string{"-f", file, "--pedantic"}, arg...) | ||
|
||
cmd := exec.Command(ledgerBinary, arg...) | ||
cmd.Dir = workdir | ||
var out strings.Builder | ||
var errOut strings.Builder | ||
cmd.Stdout = &out | ||
cmd.Stderr = &errOut | ||
|
||
err = cmd.Run() | ||
if err != nil { | ||
return "", fmt.Errorf("unable to run ledger command: %v", errOut.String()) | ||
} | ||
return out.String(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package bot | ||
|
||
import ( | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/joho/godotenv" | ||
) | ||
|
||
|
||
|
||
func TestCloneRepo(t *testing.T) { | ||
godotenv.Load("../../.env") | ||
tmpDir := t.TempDir() | ||
|
||
gitURL := os.Getenv("GIT_URL") | ||
if gitURL == "" { | ||
t.Errorf("GIT_URL is not set") | ||
return | ||
} | ||
|
||
gitAccessToken := os.Getenv("GIT_ACCESS_TOKEN") | ||
if gitAccessToken == "" { | ||
t.Errorf("GIT_ACCESS_TOKEN is not set") | ||
return | ||
} | ||
|
||
t.Run("happy path", func(t *testing.T) { | ||
err := cloneRepo(gitURL, gitAccessToken, tmpDir) | ||
if err != nil { | ||
t.Errorf("Error: %v", err) | ||
return | ||
} | ||
_, err = os.Stat(tmpDir + "/main.ledger") | ||
if err != nil { | ||
t.Errorf("Can't access main ledger file: %v", err) | ||
return | ||
} | ||
}) | ||
} | ||
|
||
func TestExecLedgerCmd(t *testing.T) { | ||
godotenv.Load("../../.env.test") | ||
tmpDir := t.TempDir() | ||
|
||
gitURL := os.Getenv("GIT_URL") | ||
if gitURL == "" { | ||
t.Errorf("GIT_URL is not set") | ||
return | ||
} | ||
|
||
gitAccessToken := os.Getenv("GIT_ACCESS_TOKEN") | ||
if gitAccessToken == "" { | ||
t.Errorf("GIT_ACCESS_TOKEN is not set") | ||
return | ||
} | ||
|
||
t.Run("happy path", func(t *testing.T) { | ||
|
||
res, err := ExecLedgerCmd(gitURL, gitAccessToken, tmpDir, "main.ledger", "bal") | ||
if err != nil { | ||
t.Errorf("Command execution error: %v", err) | ||
return | ||
} | ||
|
||
expected := ` | ||
1049,30 EUR Assets | ||
949,30 EUR Cards:Bank | ||
100,00 EUR Cash:Main | ||
-1100,00 EUR Equity:Opening-Balance | ||
50,70 EUR Expenses | ||
4,00 EUR Addictions:Cigarettes | ||
40,15 EUR Food | ||
11,80 EUR Coffee | ||
28,35 EUR Eat-Out | ||
6,55 EUR Personal:Subscriptions | ||
-------------------- | ||
0` | ||
|
||
if res == "" { | ||
t.Errorf("Command executed with empty result") | ||
return | ||
} | ||
|
||
if strings.TrimSpace(res) != strings.TrimSpace(expected) { | ||
t.Errorf("Command executed with unexpected result: %s", res) | ||
return | ||
} | ||
|
||
}) | ||
|
||
t.Run("wrong file", func(t *testing.T) { | ||
_, err := ExecLedgerCmd(gitURL, gitAccessToken, tmpDir, "not-exists.ledger", "bal") | ||
|
||
if err == nil { | ||
t.Errorf("Error excpected") | ||
return | ||
} | ||
|
||
if !strings.Contains(err.Error(), "Cannot read journal file") { | ||
t.Errorf("Unexpected error: %v", err) | ||
return | ||
} | ||
}) | ||
|
||
|
||
t.Run("wrong command", func(t *testing.T) { | ||
_, err := ExecLedgerCmd(gitURL, gitAccessToken, tmpDir, "main.ledger", "unknown-command") | ||
|
||
if err == nil { | ||
t.Errorf("Error excpected") | ||
return | ||
} | ||
|
||
if !strings.Contains(err.Error(), "Unrecognized command 'unknown-command'") { | ||
t.Errorf("Unexpected error: %v", err) | ||
return | ||
} | ||
}) | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.