3 Commits

Author SHA1 Message Date
07c3e935ef wip 2025-02-23 17:51:29 +01:00
e6224d9486 wip 2025-01-14 19:03:11 +01:00
e142814326 wip 2025-01-14 19:03:11 +01:00
14 changed files with 405 additions and 14 deletions

View File

@ -12,3 +12,7 @@ insert_final_newline = true
[*.go]
indent_style = tab
indent_size = 4
[Makefile]
indent_size = 4
indent_style = tab

View File

@ -3,7 +3,9 @@ appdata
arkanum
aurocrlf
certresolver
cli
codesetting
ctx
dotnet
Fira
FOSS

7
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}

View File

@ -69,5 +69,8 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[go]": {
"editor.defaultFormatter": "golang.go"
}
}

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
# Define Go command and flags
GO = go
GOFLAGS = -ldflags="-s -w"
build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GOFLAGS) -o dist/arkanum-cli ./cmd/cli/

78
cmd/cli/config.go Normal file
View File

@ -0,0 +1,78 @@
package main
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"github.com/urfave/cli/v3"
)
func disableMotd(ctx context.Context, cmd *cli.Command) error {
say("Disabling 'arkanum' motd...")
homeDir := os.Getenv("HOME")
motdFile := filepath.Join(homeDir, "enable_motd")
if _, err := os.Stat(motdFile); err != nil {
sayWarning("Arkanum Motd already disabled")
return nil
}
err := os.Remove(motdFile)
if err != nil {
return err
}
return nil
}
func installDefaultExtensions(ctx context.Context, cmd *cli.Command) error {
say("Installing default extensions...")
// Gitlens
if err := installSingleExtension(ctx, "eamodio.gitlens"); err != nil {
return err
}
if err := installSingleExtension(ctx, "zhuangtongfa.material-theme"); err != nil {
return err
}
if err := installSingleExtension(ctx, "vscode-icons-team.vscode-icons"); err != nil {
return err
}
say("done.")
return nil
}
func getDefaultSettings() string {
tmp := `{
"window.menuBarVisibility": "compact",
"workbench.colorTheme": "One Dark Pro Darker",
"workbench.iconTheme": "vscode-icons",
"editor.fontFamily": "'FiraCode', 'FiraCode Nerd Font', 'FiraCode NF', Consolas, 'Courier New', monospace",
"terminal.integrated.fontFamily": "'FiraCode Mono', 'FiraCode Nerd Font Mono', 'FiraCode NFM', Consolas, monospace",
"editor.fontLigatures": true,
"editor.formatOnSave": true,
"extensions.autoUpdate": false,
"git.confirmSync": false,
"telemetry.telemetryLevel": "off"
}`
return tmp
}
func setCodeSettings(ctx context.Context, cmd *cli.Command) error {
home := os.Getenv("HOME")
userSettings := path.Join(home, "data/User/settings.json")
defaults := getDefaultSettings()
if _, err := os.Stat(userSettings); err == nil {
sayWarning("Settings file found. Resetting content...")
// No need to remove file WriteFile dumps content
//if err := os.Remove(userSettings); err != nil {
// return err
//}
}
say(fmt.Sprintf("Writing Arkanum base settings.(%v)", userSettings))
if err := os.WriteFile(userSettings, []byte(defaults), 0644); err != nil {
return err
}
say("done.")
return nil
}

31
cmd/cli/git.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"context"
"fmt"
"github.com/urfave/cli/v3"
)
func SetGitConfig(ctx context.Context, cmd *cli.Command) error {
say("Setting global git config...")
if cmd.Args().Len() != 2 {
err := sayError(fmt.Sprintf("Unknown arguments count (%v)", cmd.Args().Len()))
return err
}
var err error
gitUser := cmd.Args().Get(0)
say(fmt.Sprintf("Setting global git user.name to '%v'...", gitUser))
err = execCommand(ctx, "git", "config", "--global", "user.name", gitUser)
if err != nil {
return err
}
gitEmail := cmd.Args().Get(1)
say(fmt.Sprintf("Setting global git user.email to '%v'...", gitEmail))
err = execCommand(ctx, "git", "config", "--global", "user.email", cmd.Args().Get(1))
if err != nil {
return err
}
return nil
}

116
cmd/cli/helper.go Normal file
View File

@ -0,0 +1,116 @@
package main
import (
"errors"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"runtime"
"context"
)
var (
Reset = "\033[0m"
Red = "\033[31m"
Green = "\033[32m"
Yellow = "\033[33m"
Blue = "\033[34m"
Magenta = "\033[35m"
Cyan = "\033[36m"
Gray = "\033[37m"
White = "\033[97m"
)
// Returns the current function block for use in log output.
func getCaller() string {
// remove getCaller and say*** from stack
pc, _, _, ok := runtime.Caller(2)
if !ok {
return ""
}
f := runtime.FuncForPC(pc)
if f == nil {
return ""
} else {
return f.Name()
}
}
func installSingleExtension(ctx context.Context, name string) error {
say(fmt.Sprintf("Installing '%v'...", name))
cmd := exec.CommandContext(ctx, "install-extension", name, "--force")
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func execCommand(ctx context.Context, name string, arg ...string) error {
cmd := exec.CommandContext(ctx, name, arg...)
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func execSudoCommand(ctx context.Context, hideStdout bool, name string, arg ...string) error {
args := append([]string{"-E", name}, arg...)
cmd := exec.CommandContext(ctx, "sudo", args...)
if hideStdout {
cmd.Stdout = nil
} else {
cmd.Stdout = os.Stdout
}
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func say(m string) {
section := getCaller()
fmt.Println(Green + "🧙 arkanum " + Reset + Blue + "[⚒️ " + section + "]" + Reset + ": " + m)
}
func sayWarning(m string) {
section := getCaller()
fmt.Println(Yellow + "🧙 arkanum " + Reset + Blue + "[⚒️ " + section + "]" + Reset + ": " + m)
}
func sayError(m string) error {
section := getCaller()
msg := (Red + "🧙 arkanum " + Reset + Blue + "[⚒️ " + section + "]" + Reset + ": " + m)
fmt.Println(msg)
return errors.New(msg)
}
func downloadFile(url string, filepath string) error {
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}

58
cmd/cli/install.go Normal file
View File

@ -0,0 +1,58 @@
package main
import (
"context"
"fmt"
"os"
"runtime"
"github.com/urfave/cli/v3"
)
func installDockerCli(ctx context.Context, cmd *cli.Command) error {
say("Installing docker-cli...")
var err error
say("Updating apt-get package cache...")
err = execSudoCommand(ctx, true, "apt-get", "update")
if err != nil {
return err
}
say("Getting required packages...")
err = execSudoCommand(ctx, false, "apt-get", "install", "ca-certificates", "curl", "gnupg")
if err != nil {
return err
}
say("Setting up docker repository...")
err = execSudoCommand(ctx, false, "install", "-m", "0755", "-d", "/etc/apt/keyrings")
if err != nil {
return err
}
err = downloadFile("https://download.docker.com/linux/ubuntu/gpg", "/tmp/docker-gpg")
if err != nil {
return err
}
err = execSudoCommand(ctx, false, "gpg","--dearmor", "-o", "/etc/apt/keyrings/docker.gpg", "/tmp/docker-gpg" )
if err != nil {
return err
}
err = execSudoCommand(ctx, false, "chmod", "0644", "/etc/apt/keyrings/docker.gpg")
if err != nil {
return err
}
arch := runtime.GOARCH
dockerList := fmt.Sprintf(`deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu %v stable`, arch)
listFile := "/etc/apt/sources.list.d/docker.list"
if err = os.WriteFile(listFile, []byte(dockerList), 0644); err != nil {
return err
}
err = execSudoCommand(ctx, true, "apt-get", "update")
if err != nil {
return err
}
err = execSudoCommand(ctx, true, "apt-get", "install", "--no-install-recommends", "-y", "docker-ce-cli")
if err != nil {
return err
}
return nil
}

66
cmd/cli/main.go Normal file
View File

@ -0,0 +1,66 @@
package main
import (
"context"
"os"
"github.com/urfave/cli/v3"
)
func main() {
cmd := &cli.Command{
Commands: []*cli.Command{
{
Name: "config",
Aliases: []string{"c"},
Usage: "Config arkanum itself",
EnableShellCompletion: true,
Commands: []*cli.Command{
{
Name: "disable-motd",
Usage: "Disables hint in new bash terminal",
Action: disableMotd,
},
{
Name: "install-extensions",
Usage: "Installs predefined recommended extensions",
Action: installDefaultExtensions,
},
{
Name: "reset-codesettings",
Usage: "Sets VS Code user setting with basic (Fira Code)",
Action: setCodeSettings,
},
},
},
{
Name: "git",
Aliases: []string{"g"},
Usage: "The git command is a wrapper for git helpers",
Commands: []*cli.Command{
{
Name: "setup",
Usage: "Takes user name and email address to setup the git client",
Action: SetGitConfig,
},
},
},
{
Name: "install",
Aliases: []string{"i"},
Usage: "The install command is used to add different tools",
Commands: []*cli.Command{
{
Name: "docker-cli",
Usage: "",
Action: installDockerCli,
},
},
},
},
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
panic(err)
}
}

5
cmd/cli/settings.go Normal file
View File

@ -0,0 +1,5 @@
package main
type Settings struct {
}

BIN
dist/arkanum-cli vendored Executable file

Binary file not shown.

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module gitea.ocram85.com/arkanum/arkanum
go 1.23.2
require github.com/urfave/cli/v3 v3.0.0-beta1

10
go.sum Normal file
View File

@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg=
github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=