diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100755 index 0000000..09782e9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + + - name: CI + run: go build diff --git a/.gitignore b/.gitignore index 66fd13c..f6bc83b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,14 @@ -# 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 -# Dependency directories (remove the comment below to include it) -# vendor/ +vendor/ +.idea/ +.vscode/ +.tools/ +build/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100755 index 0000000..f1c0901 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,53 @@ + +run: + concurrency: 1 + deadline: 2m + issues-exit-code: 1 + tests: true + skip-files: + - easyjson + +issues: + exclude-use-default: false + +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0.8 + gofmt: + simplify: true + errcheck: + check-type-assertions: true + check-blank: true + gocyclo: + min-complexity: 30 + misspell: + locale: US + gosimple: + go: "1.16" + checks: ["all"] + prealloc: + simple: true + range-loops: true + for-loops: false + +linters: + disable-all: true + enable: + - govet + - gofmt + - errcheck + - misspell + - gocyclo + - ineffassign + - goimports + - gosimple + - prealloc + fast: false + diff --git a/README.md b/README.md index 69b6a71..53ecab3 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# devtool \ No newline at end of file +# devtool + +[![Release](https://img.shields.io/github/release/dewep-online/devtool.svg?style=flat-square)](https://github.com/dewep-online/devtool/releases/latest) +[![Go Report Card](https://goreportcard.com/badge/github.com/dewep-online/devtool)](https://goreportcard.com/report/github.com/dewep-online/devtool) +[![CI](https://github.com/dewep-online/devtool/actions/workflows/ci.yml/badge.svg)](https://github.com/dewep-online/devtool/actions/workflows/ci.yml) \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dce1a42 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module github.com/dewep-online/devtool + +go 1.17 + +require github.com/deweppro/go-app v1.6.1 + +require github.com/deweppro/go-errors v0.0.4 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..10e83fe --- /dev/null +++ b/go.sum @@ -0,0 +1,22 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deweppro/go-algorithms v1.2.0/go.mod h1:zYdfRdlpaXgdT36OgvdjH1qtTZFWEeBi3KUQmWltMPI= +github.com/deweppro/go-app v1.6.1 h1:NH7W/NDQmHLrFgXl9Zy3nGM91+w9q4vo9wfSfWHmAgg= +github.com/deweppro/go-app v1.6.1/go.mod h1:1oMjMJH9hxas3/Nl73O2E+E5mJoMheqrZ1fmQ6M46EE= +github.com/deweppro/go-chan-pool v1.1.2/go.mod h1:6meJsORhraeyvJNPy4hx8xgBNjp2xx3KGB/d5Q5a/I4= +github.com/deweppro/go-errors v0.0.4 h1:TW91LRqHAkUauDJ5lzz73LziANH7mjli1tyvtwzXRCM= +github.com/deweppro/go-errors v0.0.4/go.mod h1:BLsNcxaHh1fjNl/o1TB69JwA8XueSk/Nszkvw4ZwI/I= +github.com/deweppro/go-logger v1.3.0/go.mod h1:jxBBLyHmIvJ4erGUj5qeE6ir36ztyAL1pI+9GymOHVI= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/init/devtool.service b/init/devtool.service new file mode 100755 index 0000000..fb3a6a4 --- /dev/null +++ b/init/devtool.service @@ -0,0 +1,15 @@ +[Unit] +After=network.target + +[Service] +User=root +Group=root +Restart=on-failure +RestartSec=30s +Type=simple +ExecStart=/usr/bin/devtool --config=/etc/devtool/config.yaml +KillMode=process +KillSignal=SIGTERM + +[Install] +WantedBy=default.target diff --git a/internal/build/build.go b/internal/build/build.go new file mode 100644 index 0000000..718e7fd --- /dev/null +++ b/internal/build/build.go @@ -0,0 +1,53 @@ +package build + +import ( + "strings" + + "github.com/dewep-online/devtool/internal/global" + "github.com/dewep-online/devtool/pkg/exec" + "github.com/dewep-online/devtool/pkg/files" + "github.com/deweppro/go-app/console" +) + +func Cmd() console.CommandGetter { + return console.NewCommand(func(setter console.CommandSetter) { + setter.Setup("build", "") + setter.Flag(func(flagsSetter console.FlagsSetter) { + flagsSetter.StringVar("arch", "amd64,arm64", "") + }) + setter.ExecFunc(func(_ []string, arch string) { + console.Infof("setup tools") + buildDir := global.GetBuildDir() + global.SetupEnv() + + cmds := []string{ + "go mod tidy", + "go mod download", + "go generate ./...", + } + + mainFiles, err := files.Detect("main.go") + console.FatalIfErr(err, "detect main.go") + + for _, main := range mainFiles { + appName := files.Folder(main) + archList := strings.Split(arch, ",") + + for _, arch = range archList { + cmds = append(cmds, "rm -rf "+buildDir+"/"+appName+"_"+arch) + + switch arch { + case "arm64": + cmds = append(cmds, "GODEBUG=netdns=9 GO111MODULE=on CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=aarch64-linux-gnu-gcc go build -a -o "+buildDir+"/"+appName+"_"+arch+" "+main) + case "amd64": + cmds = append(cmds, "GODEBUG=netdns=9 GO111MODULE=on CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o "+buildDir+"/"+appName+"_"+arch+" "+main) + default: + console.Fatalf("use only arch=[amd64,arm64]") + } + } + } + + exec.CommandPack("bash", cmds...) + }) + }) +} diff --git a/internal/global/global.go b/internal/global/global.go new file mode 100644 index 0000000..49a269c --- /dev/null +++ b/internal/global/global.go @@ -0,0 +1,49 @@ +package global + +import ( + "os" + exec2 "os/exec" + "regexp" + + "github.com/dewep-online/devtool/pkg/files" + "github.com/deweppro/go-app/console" +) + +const ( + ToolsDir = ".tools" + BuildDir = "build" + InitDir = "init" + ScriptsDir = "scripts" +) + +func GetToolsDir() string { + return files.CurrentDir() + "/" + ToolsDir +} + +func GetBuildDir() string { + return files.CurrentDir() + "/" + BuildDir +} + +func GetInitDir() string { + return files.CurrentDir() + "/" + InitDir +} + +func GetScriptsDir() string { + return files.CurrentDir() + "/" + ScriptsDir +} + +func SetupEnv() { + console.FatalIfErr(os.Setenv("GOBIN", GetToolsDir()), "setup env") +} + +var rex = regexp.MustCompile(`go(\d+)\.(\d+)`) + +func GoVersion() string { + b, err := exec2.Command("bash", "-c", "go version").CombinedOutput() + console.FatalIfErr(err, "detect go version") + result := rex.FindAllString(string(b), 1) + for _, s := range result { + return s + } + return "unknown" +} diff --git a/internal/lint/lint.go b/internal/lint/lint.go new file mode 100644 index 0000000..611807d --- /dev/null +++ b/internal/lint/lint.go @@ -0,0 +1,34 @@ +package lint + +import ( + "github.com/dewep-online/devtool/internal/global" + "github.com/dewep-online/devtool/pkg/exec" + "github.com/dewep-online/devtool/pkg/files" + "github.com/deweppro/go-app/console" +) + +func Cmd() console.CommandGetter { + return console.NewCommand(func(setter console.CommandSetter) { + setter.Setup("lint", "") + setter.ExecFunc(func(_ []string) { + console.Infof("setup tools") + toolsDir := global.GetToolsDir() + global.SetupEnv() + + exec.CommandPack("bash", + "go mod tidy", + "go mod download", + "go generate ./...", + toolsDir+"/golangci-lint --version", + toolsDir+"/golangci-lint -v run ./...", + ) + + mainFiles, err := files.Detect("main.go") + console.FatalIfErr(err, "detect main.go") + + for _, main := range mainFiles { + exec.CommandPack("bash", "go build -race -v -o /tmp/bin.test "+main) + } + }) + }) +} diff --git a/internal/setup/setup.go b/internal/setup/setup.go new file mode 100644 index 0000000..68a26b6 --- /dev/null +++ b/internal/setup/setup.go @@ -0,0 +1,216 @@ +package setup + +import ( + "os" + "strings" + + "github.com/dewep-online/devtool/internal/global" + "github.com/dewep-online/devtool/pkg/exec" + "github.com/dewep-online/devtool/pkg/files" + "github.com/deweppro/go-app/console" +) + +func Cmd() console.CommandGetter { + return console.NewCommand(func(setter console.CommandSetter) { + setter.Setup("setup", "") + setter.ExecFunc(func(_ []string) { + global.SetupEnv() + + toolDir, initDir, scriptsDir := global.GetToolsDir(), global.GetInitDir(), global.GetScriptsDir() + + console.FatalIfErr(os.MkdirAll(initDir, 0755), "create init dir") + console.FatalIfErr(os.MkdirAll(toolDir, 0755), "create tools dir") + console.FatalIfErr(os.MkdirAll(scriptsDir, 0755), "create scripts dir") + + console.Infof("update .gitignore") + console.FatalIfErr(files.Rewrite(files.CurrentDir()+"/.gitignore", func(s string) string { + if !strings.Contains(s, global.ToolsDir) { + s += global.ToolsDir + "/\n" + } + if !strings.Contains(s, global.BuildDir) { + s += global.BuildDir + "/\n" + } + return s + }), "create tools dir") + + console.Infof("install tools") + for name, install := range tools1 { + if !files.Exist(toolDir + "/" + name) { + console.FatalIfErr(exec.Command("bash", install), "install tool [%s]", name) + } + } + + gover := global.GoVersion() + tools, ok := tools2[gover] + if ok { + for name, install := range tools { + if !files.Exist(toolDir + "/" + name) { + console.FatalIfErr(exec.Command("bash", install), "install tool [%s]", name) + } + } + } + + console.Infof("create configs") + for name, config := range configs { + if !files.Exist(files.CurrentDir() + "/" + name) { + console.FatalIfErr(os.WriteFile(files.CurrentDir()+"/"+name, []byte(config), 0755), "create config [%s]", name) + } + } + + console.Infof("create services and deb scripts") + postinstData, postrmData, preinstData, prermData := bashPrefix, bashPrefix, bashPrefix, bashPrefix + + mainFiles, err := files.Detect("main.go") + console.FatalIfErr(err, "detect main.go") + for _, main := range mainFiles { + appName := files.Folder(main) + if !files.Exist(initDir + "/" + appName + ".service") { + tmpl := strings.ReplaceAll(systemctlConfig, "{%app_name%}", appName) + console.FatalIfErr(os.WriteFile(initDir+"/"+appName+".service", []byte(tmpl), 0755), "create init config [%s]", appName) + } + + postinstData += strings.ReplaceAll(postinst, "{%app_name%}", appName) + preinstData += strings.ReplaceAll(preinstDir, "{%app_name%}", appName) + preinstData += strings.ReplaceAll(preinst, "{%app_name%}", appName) + prermData += strings.ReplaceAll(prerm, "{%app_name%}", appName) + } + + if !files.Exist(scriptsDir + "/postinst.sh") { + console.FatalIfErr(os.WriteFile(scriptsDir+"/postinst.sh", []byte(postinstData), 0755), "create postinst") + } + if !files.Exist(scriptsDir + "/postrm.sh") { + console.FatalIfErr(os.WriteFile(scriptsDir+"/postrm.sh", []byte(postrmData), 0755), "create postrm") + } + if !files.Exist(scriptsDir + "/preinst.sh") { + console.FatalIfErr(os.WriteFile(scriptsDir+"/preinst.sh", []byte(preinstData), 0755), "create preinst") + } + if !files.Exist(scriptsDir + "/prerm.sh") { + console.FatalIfErr(os.WriteFile(scriptsDir+"/prerm.sh", []byte(prermData), 0755), "create prerm") + } + + }) + }) +} + +var tools1 = map[string]string{ + "goveralls": "go install github.com/mattn/goveralls@latest", + "static": "go install github.com/deweppro/go-static/cmd/static@latest", + "easyjson": "go install github.com/mailru/easyjson/...@latest", +} + +var tools2 = map[string]map[string]string{ + "go1.19": { + "golangci-lint": "go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.0", + }, + "go1.18": { + "golangci-lint": "go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.38.0", + }, + "go1.17": { + "golangci-lint": "go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.38.0", + }, +} + +var configs = map[string]string{ + ".golangci.yml": golangciLintConfig, +} + +var golangciLintConfig = ` +run: + concurrency: 1 + deadline: 2m + issues-exit-code: 1 + tests: true + skip-files: + - easyjson + +issues: + exclude-use-default: false + +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0.8 + gofmt: + simplify: true + errcheck: + check-type-assertions: true + check-blank: true + gocyclo: + min-complexity: 30 + misspell: + locale: US + gosimple: + go: "1.16" + checks: ["all"] + prealloc: + simple: true + range-loops: true + for-loops: false + +linters: + disable-all: true + enable: + - govet + - gofmt + - errcheck + - misspell + - gocyclo + - ineffassign + - goimports + - gosimple + - prealloc + fast: false + +` +var systemctlConfig = `[Unit] +After=network.target + +[Service] +User=root +Group=root +Restart=on-failure +RestartSec=30s +Type=simple +ExecStart=/usr/bin/{%app_name%} --config=/etc/{%app_name%}/config.yaml +KillMode=process +KillSignal=SIGTERM + +[Install] +WantedBy=default.target +` + +var ( + bashPrefix = "#!/bin/bash\n\n" + postinst = ` +if [ -f "/etc/systemd/system/{%app_name%}.service" ]; then + systemctl start {%app_name%} + systemctl enable {%app_name%} + systemctl daemon-reload +fi +` + preinstDir = ` +if ! [ -d /var/lib/{%app_name%}/ ]; then + mkdir /var/lib/{%app_name%} +fi +` + preinst = ` +if [ -f "/etc/systemd/system/{%app_name%}.service" ]; then + systemctl stop {%app_name%} + systemctl disable {%app_name%} + systemctl daemon-reload +fi +` + prerm = ` +if [ -f "/etc/systemd/system/{%app_name%}.service" ]; then + systemctl stop {%app_name%} + systemctl disable {%app_name%} + systemctl daemon-reload +fi +` +) diff --git a/internal/tests/tests.go b/internal/tests/tests.go new file mode 100644 index 0000000..b87ee42 --- /dev/null +++ b/internal/tests/tests.go @@ -0,0 +1,40 @@ +package tests + +import ( + "os" + + "github.com/dewep-online/devtool/internal/global" + "github.com/dewep-online/devtool/pkg/exec" + "github.com/deweppro/go-app/console" +) + +func Cmd() console.CommandGetter { + return console.NewCommand(func(setter console.CommandSetter) { + setter.Setup("test", "") + setter.ExecFunc(func(_ []string) { + console.Infof("setup tools") + toolsDir := global.GetToolsDir() + global.SetupEnv() + + coverallsToken := os.Getenv("COVERALLS_TOKEN") + + cmds := []string{ + "go mod tidy", + "go mod download", + "go generate ./...", + "go clean -testcache", + } + + if len(coverallsToken) > 0 { + cmds = append(cmds, + "go test -v -race -run Unit -covermode=atomic -coverprofile=coverage.out ./...", + toolsDir+"/goveralls -coverprofile=coverage.out -repotoken "+coverallsToken, + ) + } else { + cmds = append(cmds, "go test -v -race -run Unit ./...") + } + + exec.CommandPack("bash", cmds...) + }) + }) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..13721b7 --- /dev/null +++ b/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "os" + + "github.com/dewep-online/devtool/internal/setup" + + "github.com/dewep-online/devtool/internal/build" + + "github.com/dewep-online/devtool/internal/lint" + "github.com/dewep-online/devtool/internal/tests" + "github.com/deweppro/go-app/console" +) + +func main() { + console.ShowDebug(true) + + app := console.New("devtool", "help devtool") + + app.RootCommand(console.NewCommand(func(setter console.CommandSetter) { + setter.ExecFunc(func(_ []string) { + console.Infof("os env:\n%s", func() string { + out := "" + for _, s := range os.Environ() { + out += s + "\n" + } + return out + }()) + }) + })) + + app.AddCommand( + setup.Cmd(), + lint.Cmd(), + tests.Cmd(), + build.Cmd(), + ) + + app.Exec() +} diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go new file mode 100644 index 0000000..700c0e9 --- /dev/null +++ b/pkg/exec/exec.go @@ -0,0 +1,78 @@ +package exec + +import ( + "bufio" + "context" + "fmt" + "os" + "os/exec" + "sync" + + "github.com/dewep-online/devtool/pkg/files" + "github.com/deweppro/go-app/application/sys" + "github.com/deweppro/go-app/console" +) + +func CommandPack(shell string, command ...string) { + for _, s := range command { + console.FatalIfErr(Command(shell, s), "run command") + } +} + +func Command(shell string, command string) (err error) { + wg := sync.WaitGroup{} + ctx, cncl := context.WithCancel(context.Background()) + go sys.OnSyscallStop(func() { + cncl() + }) + + wg.Add(1) + go func() { + err = runCmd(ctx, shell, command) + wg.Done() + }() + + wg.Wait() + return +} + +func runCmd(ctx context.Context, shell string, command string) error { + console.Infof(command) + cmd := exec.CommandContext(ctx, shell, "-c", command) + cmd.Env = os.Environ() + cmd.Dir = files.CurrentDir() + + stdout, err := cmd.StdoutPipe() + console.FatalIfErr(err, "stdout init") + defer stdout.Close() //nolint: errcheck + stderr, err := cmd.StderrPipe() + console.FatalIfErr(err, "stderr init") + defer stderr.Close() //nolint: errcheck + + console.FatalIfErr(cmd.Start(), "start command") + + go func() { + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + fmt.Println(scanner.Text()) + select { + case <-ctx.Done(): + break + default: + } + } + }() + go func() { + scanner := bufio.NewScanner(stderr) + for scanner.Scan() { + fmt.Println(scanner.Text()) + select { + case <-ctx.Done(): + break + default: + } + } + }() + + return cmd.Wait() +} diff --git a/pkg/files/files.go b/pkg/files/files.go new file mode 100644 index 0000000..27caa9c --- /dev/null +++ b/pkg/files/files.go @@ -0,0 +1,54 @@ +package files + +import ( + "io/fs" + "os" + "path/filepath" + "strings" + + "github.com/deweppro/go-app/console" +) + +func CurrentDir() string { + dir, err := os.Getwd() + console.FatalIfErr(err, "get current dir") + return dir +} + +func Detect(filename string) ([]string, error) { + curDir := CurrentDir() + files := make([]string, 0) + err := filepath.Walk(curDir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() || info.Name() != filename { + return nil + } + files = append(files, path) + return nil + }) + return files, err +} + +func Rewrite(filename string, cb func(string) string) error { + b, err := os.ReadFile(filename) + if err != nil { + return err + } + + b = []byte(cb(string(b))) + + return os.WriteFile(filename, b, 0755) +} + +func Exist(filename string) bool { + _, err := os.Stat(filename) + return err == nil +} + +func Folder(filename string) string { + dir := filepath.Dir(filename) + tree := strings.Split(dir, string(os.PathSeparator)) + return tree[len(tree)-1] +} diff --git a/scripts/postinst.sh b/scripts/postinst.sh new file mode 100755 index 0000000..71e5261 --- /dev/null +++ b/scripts/postinst.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + +if [ -f "/etc/systemd/system/devtool.service" ]; then + systemctl start devtool + systemctl enable devtool + systemctl daemon-reload +fi diff --git a/scripts/postrm.sh b/scripts/postrm.sh new file mode 100755 index 0000000..05a7907 --- /dev/null +++ b/scripts/postrm.sh @@ -0,0 +1,2 @@ +#!/bin/bash + diff --git a/scripts/preinst.sh b/scripts/preinst.sh new file mode 100755 index 0000000..d58735b --- /dev/null +++ b/scripts/preinst.sh @@ -0,0 +1,12 @@ +#!/bin/bash + + +if ! [ -d /var/lib/devtool/ ]; then + mkdir /var/lib/devtool +fi + +if [ -f "/etc/systemd/system/devtool.service" ]; then + systemctl stop devtool + systemctl disable devtool + systemctl daemon-reload +fi diff --git a/scripts/prerm.sh b/scripts/prerm.sh new file mode 100755 index 0000000..8651fc4 --- /dev/null +++ b/scripts/prerm.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + +if [ -f "/etc/systemd/system/devtool.service" ]; then + systemctl stop devtool + systemctl disable devtool + systemctl daemon-reload +fi