diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..c299a0e
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,34 @@
+name: goreleaser
+
+on:
+ push:
+ tags:
+ - '*'
+
+permissions:
+ contents: write
+
+jobs:
+ goreleaser:
+ runs-on: ubuntu-latest
+ steps:
+ -
+ name: Checkout
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ -
+ name: Set up Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.17
+ -
+ name: Run GoReleaser
+ uses: goreleaser/goreleaser-action@v2
+ with:
+ distribution: goreleaser
+ version: latest
+ args: release --rm-dist
+ env:
+ GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
+ HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..36482ef
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,14 @@
+on: [push, pull_request]
+name: Test
+jobs:
+ test:
+ runs-on: macos-latest
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.17.x
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Test
+ run: go test ./...
diff --git a/.goreleaser.yml b/.goreleaser.yml
index b684174..020fc09 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -73,3 +73,4 @@ brews:
install: |
bin.install "heptapod"
+ bin.install Dir["rules/*"]
diff --git a/README.md b/README.md
index 0ae6d96..4c11f38 100644
--- a/README.md
+++ b/README.md
@@ -3,41 +3,68 @@
This is a command line application to manage and fine-tune
[Time Machine](https://support.apple.com/en-us/HT201250) exclude paths.
-## This repository is a WIP! The advertised functionality is nonexistent yet :(
+
+ Why it is named after creatures from Arrival?
+Heptapods are extraterrestrial species from the movie Arrival.
+They are special because they have non-linear time perspective.
+Their written language (Heptapod B) is basically describes
+the future and the past in the same time. Hence the name of the tool.
+
-### Repo state
-done:
- - architecture the protocol/configs
- - most of asimovs features are ported
- - example rules added
- - command line interface
- - option to dryrun, show inner states, write to file
- - purge option
- - we should write down what paths excluded by us, and include them back
+### Install
-todos:
- - handle global deps (m2, ivy, nvm, npm)
- - support tmignore functionality
- - support tmignore like funcionality with dockerignore
- - regexp pattern
- - brew package
- - ghactions
- - hook to rerun periodically/before tmbackups
- - port asimov's issues (spotify, spotlight)
- - docker support (at least tell if docker vm is persisted or not)
- - this is kinda easy with tmutil.GetExcludeList()
- - android vms?
- - this should be also easy
- - preemptive search that tells you how many files with which size will be excluded/included
- - nice to have, we can tell the sizes, but counting files need to actually count the files which could be slow AH
- - speedtest it
- - modify the backup intervals and frequencies
- - not sure it can be done with tmutil, but there are applications for this
- - probably adding `.` and `..` will break the execution shortcuts and need to fix them
- - wildcards like `*.sh` not working right now, do we want to make them work?
+```sh
+brew tap tg44/heptapod
+```
+```sh
+brew install heptapod
+```
+
+### Usage
+
+```
+heptapod -h
+heptapod -h
+```
+Will print help!
+
+```
+heptapod initRules
+```
+This will move the currently added ruleset to `~/.heptapod/rules` (or the set `--rules dir` directory) they are added as enabled rules!
+
+```
+heptapod ls -a
+```
+Lists all the rules (you get 4 tables, enabled, disabled, parseable but unrunable and unparsable).
+
+```
+heptapod lse
+```
+Could list all the currently excluded TM paths.
+
+```
+heptapod -v run -d
+```
+Will dryrun the current rules, will log speed informations. (Potentially list nonexistent directories and files!)
+
+```
+heptapod run
+```
+Will run the current rules, and add them to the TM exclude list. Also writes exclude logs to `~/.heptapod/logs` (or the given `--logDir dir`) for easier revert.
+
+```
+heptapod prune -a
+```
+Will revert all the previously added paths from the run-exclude-logs. (`prune -h` could tell you the other useful revert options).
-### Notes for migrating to a new machine
-`xcode-select --install` may be needed after a migration
+
+
+
+### Notes for TM migrating to a new machine
+When you try to migrate your TM state to a new machine
+`xcode-select --install` may be needed. Somehow this is
+sometimes not migrating as you thought it will.
### Rules
Every rule has a searchPaths, ignorePaths.
@@ -73,3 +100,38 @@ Ignores files/dirs based on other files existence, made for easy language dep ig
- [tmignore](https://github.com/samuelmeuli/tmignore)
- [various stack exchange responses](https://superuser.com/questions/1161038/exclude-folders-by-regex-from-time-machine-backup)
- [tmutil](https://ss64.com/osx/tmutil.html)
+
+### Contribution
+If you are interested in this repo, star it, and write an issue, and we can talk about future ideas there!
+
+
+### Repo/developement state
+done:
+- architecture the protocol/configs
+- most of asimov's features are ported
+- example rules added
+- command line interface
+- option to dryrun, show inner states, write to file
+- purge option
+ - we should write down what paths excluded by us, and include them back
+- brew package
+- ghactions
+
+todos:
+- handle global deps (m2, ivy, nvm, npm)
+- support tmignore functionality
+- support tmignore like funcionality with dockerignore
+- regexp pattern
+- hook to rerun periodically/before tmbackups
+- port asimov's issues (spotify, spotlight)
+- docker support (at least tell if docker vm is persisted or not)
+ - this is kinda easy with tmutil.GetExcludeList()
+- android vms?
+ - this should be also easy
+- preemptive search that tells you how many files with which size will be excluded/included
+ - nice to have, we can tell the sizes, but counting files need to actually count the files which could be slow AH
+- speedtest it
+- modify the backup intervals and frequencies
+ - not sure it can be done with tmutil, but there are applications for this
+- probably adding `.` and `..` will break the execution shortcuts and need to fix them
+- wildcards like `*.sh` not working right now, do we want to make them work?
diff --git a/go.mod b/go.mod
index 5cc54d6..3333cca 100644
--- a/go.mod
+++ b/go.mod
@@ -1,9 +1,16 @@
module github.com/tg44/heptapod
-go 1.13
+go 1.17
require (
github.com/olekukonko/tablewriter v0.0.5
github.com/urfave/cli/v2 v2.3.0
gopkg.in/yaml.v2 v2.4.0
)
+
+require (
+ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
+ github.com/mattn/go-runewidth v0.0.9 // indirect
+ github.com/russross/blackfriday/v2 v2.0.1 // indirect
+ github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
+)
diff --git a/main.go b/main.go
index 5995b9b..a5c951d 100644
--- a/main.go
+++ b/main.go
@@ -1,24 +1,27 @@
package main
import (
+ "fmt"
"github.com/olekukonko/tablewriter"
"github.com/tg44/heptapod/pkg"
"github.com/tg44/heptapod/pkg/parser"
"github.com/tg44/heptapod/pkg/tmutil"
+ "github.com/tg44/heptapod/pkg/utils"
"github.com/urfave/cli/v2"
+ "io"
+ "io/ioutil"
"log"
"os"
+ "path/filepath"
"sort"
"strings"
)
-func main() {
- //res := pkg.GetExcludedPaths([]string{"test-rules/scala.yaml", "test-rules/node.yaml"}, 4, 2048)
- //tmutil.AddPathsToTM(res, 2048)
- //fmt.Println(len(res))
-
- //fmt.Println(tmutil.GetExcludeList())
+var version string = "local-build"
+var commit string = ""
+var date string = ""
+func main() {
var rulePath string
var logDir string
var file string
@@ -43,7 +46,7 @@ func main() {
&cli.StringFlag{
Name: "logDir",
Aliases: []string{"ld"},
- Value: "./.logs",
+ Value: "~/.heptapod/logs",
Usage: "the directory where excluded dirs logged for reliable prune/uninstall",
Destination: &logDir,
},
@@ -70,6 +73,30 @@ func main() {
},
},
Commands: []*cli.Command{
+ {
+ Name: "version",
+ Aliases: []string{"v"},
+ Usage: "version info",
+ Flags: []cli.Flag{
+ &cli.BoolFlag{
+ Name: "verbose",
+ Aliases: []string{"v"},
+ Value: false,
+ Usage: "more detaild version info",
+ Destination: &verbose,
+ },
+ },
+ Action: func(c *cli.Context) error {
+ if verbose {
+ fmt.Println(version)
+ fmt.Println(commit)
+ fmt.Println(date)
+ } else {
+ fmt.Println(version)
+ }
+ return nil
+ },
+ },
{
Name: "list",
Aliases: []string{"ls"},
@@ -108,7 +135,7 @@ func main() {
res := pkg.GetExcludedPaths(rulePath, par, buffer, verbose)
tmutil.AddPathsToTM(res, logDir, buffer, verbose)
if verbose {
- log.Printf("total %d paths found", len(res))
+ log.Printf("total %d paths found\n", len(res))
}
}
return nil
@@ -166,6 +193,50 @@ func main() {
return nil
},
},
+ {
+ Name: "initRules",
+ Aliases: []string{},
+ Usage: "copy the example rules to the given rule dir",
+ Flags: []cli.Flag{},
+ Action: func(c *cli.Context) error {
+ dest, err := utils.FixupPathsToHandleHome(rulePath)
+ if err != nil {
+ return err
+ }
+ srcDir := "./rules"
+ entries, err := ioutil.ReadDir(srcDir)
+ if err != nil {
+ return err
+ }
+ for _, entry := range entries {
+ sourcePath := filepath.Join(srcDir, entry.Name())
+ destPath := filepath.Join(dest, entry.Name())
+
+ out, err := os.Create(destPath)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = out.Close()
+ }()
+
+ in, err := os.Open(sourcePath)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = in.Close()
+ }()
+
+ _, err = io.Copy(out, in)
+ if err != nil {
+ return err
+ }
+ }
+ fmt.Printf("All the rules are copied to %s, please check them with heptapod ls -a, and optionally edit them for better include/exclude rules!\n", rulePath)
+ return nil
+ },
+ },
},
}
diff --git a/pkg/parser/file-trigger_test.go b/pkg/parser/file-trigger_test.go
index ef25cd5..3f6dfc5 100644
--- a/pkg/parser/file-trigger_test.go
+++ b/pkg/parser/file-trigger_test.go
@@ -3,7 +3,7 @@ package parser
import "testing"
func TestFileTriggerSettingsParse(t *testing.T) {
- rule, err := ruleParse("../test-rules/git.yaml")
+ rule, err := ruleParse("../../test-rules/git.yaml")
if err != nil {
t.Errorf("Rule parser can't parse testRule!")
}
diff --git a/pkg/parser/rule_test.go b/pkg/parser/rule_test.go
index 6224b8f..ff0f63d 100644
--- a/pkg/parser/rule_test.go
+++ b/pkg/parser/rule_test.go
@@ -5,7 +5,7 @@ import (
)
func TestRuleParse(t *testing.T) {
- res, err := ruleParse("../test-rules/git.yaml")
+ res, err := ruleParse("../../test-rules/git.yaml")
//t.Log(res)
if err != nil {
t.Errorf("Rule parser can't parse testRule!")
diff --git a/pkg/tmutil/tmutil.go b/pkg/tmutil/tmutil.go
index 8b18813..26199e3 100644
--- a/pkg/tmutil/tmutil.go
+++ b/pkg/tmutil/tmutil.go
@@ -13,8 +13,12 @@ import (
"time"
)
-func AddPathsToTM(paths []string, logPath string, bufferSize int, verbose bool) {
- err := os.MkdirAll(logPath, os.ModePerm)
+func AddPathsToTM(paths []string, logDir string, bufferSize int, verbose bool) {
+ logPath, err := utils.FixupPathsToHandleHome(logDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+ err = os.MkdirAll(logPath, os.ModePerm)
if err != nil {
log.Fatal(err)
}