diff --git a/.golangci.yml b/.golangci.yml index 4371728..e1f39f5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -136,6 +136,11 @@ linters: disabled: true - name: unused-parameter - name: unused-receiver + staticcheck: + checks: + - "all" + - "-SA9003" + exclusions: presets: diff --git a/.idx/dev.nix b/.idx/dev.nix index 7389577..9b796d3 100644 --- a/.idx/dev.nix +++ b/.idx/dev.nix @@ -14,6 +14,7 @@ fzf util-linux go + golangci-lint uv dos2unix ]; diff --git a/cmd/ai/pytorch.go b/cmd/ai/pytorch.go index f7bea5f..66ae22c 100644 --- a/cmd/ai/pytorch.go +++ b/cmd/ai/pytorch.go @@ -22,10 +22,8 @@ func pytorch(cmd *cobra.Command, _ []string) { utils.RunCmd(command) } if utils.GetBoolFlag(cmd, "config") { - // nothing to configure } if utils.GetBoolFlag(cmd, "uninstall") { - // TODO } } diff --git a/cmd/bigdata/arrowdb.go b/cmd/bigdata/arrowdb.go index 1654eb1..942f98a 100644 --- a/cmd/bigdata/arrowdb.go +++ b/cmd/bigdata/arrowdb.go @@ -13,10 +13,7 @@ func linkArrowDbProfileFromHost() { dstProfile := filepath.Join(utils.UserHomeDir(), ".arrowdb_profile") if utils.ExistsFile(srcProfile) { // inside a Docker container, link profile from host - if utils.ExistsFile(dstProfile) { - utils.RemoveAll(dstProfile) - } - utils.Symlink(srcProfile, dstProfile) + utils.Symlink(srcProfile, dstProfile, false) } } diff --git a/cmd/data.go b/cmd/data.go index a1f349d..663d5d2 100644 --- a/cmd/data.go +++ b/cmd/data.go @@ -8,14 +8,14 @@ import ( ) // Pull data for icon from GitHub into ~/.config/icon-data. -func data(cmd *cobra.Command, args []string) { +func data(cmd *cobra.Command, _ []string) { dir := "~/.config/icon-data" if !utils.GetBoolFlag(cmd, "force") && utils.ExistsDir(dir+"/.git") { fmt.Println("Using existing data in ~/.config/icon-data.") return } - utils.BackupDir(dir, "") + utils.Backup(dir, "") utils.MkdirAll(dir, 0o700) command := utils.Format(`git clone {gitUrl} {dir} \ diff --git a/cmd/dev/git.go b/cmd/dev/git.go index 6c18e6c..d542195 100644 --- a/cmd/dev/git.go +++ b/cmd/dev/git.go @@ -36,7 +36,7 @@ func installGitUi(cmd *cobra.Command) { } func linkGitUiFiles(baseDir string) { - utils.SymlinkIntoDir("~/.config/icon-data/git/gitui/key_bindings.ron", filepath.Join(baseDir, "gitui")) + utils.SymlinkIntoDir("~/.config/icon-data/git/gitui/key_bindings.ron", filepath.Join(baseDir, "gitui"), true) } func configGitUi(cmd *cobra.Command) { @@ -124,7 +124,7 @@ func git(cmd *cobra.Command, args []string) { } if utils.GetBoolFlag(cmd, "config") { network.SshClient(cmd, args) - utils.Symlink("~/.config/icon-data/git/gitconfig", "~/.gitconfig") + utils.Symlink("~/.config/icon-data/git/gitconfig", "~/.gitconfig", true) configGitProxy(cmd) configGitUi(cmd) } diff --git a/cmd/dev/golang.go b/cmd/dev/golang.go index e34e7cb..4f5e34c 100644 --- a/cmd/dev/golang.go +++ b/cmd/dev/golang.go @@ -60,7 +60,7 @@ func installGoPls(prefix string) { } // Install and configure Golang. -func golang(cmd *cobra.Command, args []string) { +func golang(cmd *cobra.Command, _ []string) { prefix := utils.GetCommandPrefix(false, map[string]uint32{ "/usr/local/go": unix.W_OK | unix.R_OK, "/usr/local": unix.W_OK | unix.R_OK, diff --git a/cmd/dev/pytype.go b/cmd/dev/pytype.go index 8ce9af2..f657256 100644 --- a/cmd/dev/pytype.go +++ b/cmd/dev/pytype.go @@ -11,7 +11,7 @@ import ( ) // Install and configure pytype. -func pytype(cmd *cobra.Command, args []string) { +func pytype(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { command := utils.Format("{pip_install} pytype", map[string]string{ "pip_install": utils.BuildPipInstall(cmd), diff --git a/cmd/dev/rust.go b/cmd/dev/rust.go index d471760..c0ab50e 100644 --- a/cmd/dev/rust.go +++ b/cmd/dev/rust.go @@ -104,7 +104,7 @@ func installCargoBinstall() { } // Install and configure Rust. -func rust(cmd *cobra.Command, args []string) { +func rust(cmd *cobra.Command, _ []string) { rustupHome := utils.GetStringFlag(cmd, "rustup-home") if rustupHome == "" { rustupHome = filepath.Join(utils.UserHomeDir(), ".rustup") diff --git a/cmd/ide/neovim.go b/cmd/ide/neovim.go index b8d3820..9d8150f 100644 --- a/cmd/ide/neovim.go +++ b/cmd/ide/neovim.go @@ -8,7 +8,7 @@ import ( ) // Install and configure neovim. -func neovim(cmd *cobra.Command, args []string) { +func neovim(cmd *cobra.Command, _ []string) { Neovim( utils.GetBoolFlag(cmd, "install"), utils.GetBoolFlag(cmd, "config"), @@ -58,8 +58,7 @@ func Neovim(install bool, config bool, uninstall bool, yes_s string) { } if config { dir := "~/.config/nvim" - utils.BackupDir(dir, "") - utils.Symlink("~/.config/icon-data/nvim", dir) + utils.Symlink("~/.config/icon-data/nvim", dir, true) } if uninstall { switch runtime.GOOS { diff --git a/cmd/ide/vscode.go b/cmd/ide/vscode.go index c723550..01798b2 100644 --- a/cmd/ide/vscode.go +++ b/cmd/ide/vscode.go @@ -9,7 +9,7 @@ import ( ) // Install and configure Visual Studio Code. -func vscode(cmd *cobra.Command, args []string) { +func vscode(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { switch runtime.GOOS { case "linux": @@ -52,7 +52,7 @@ func vscode(cmd *cobra.Command, args []string) { if utils.GetBoolFlag(cmd, "copy") { utils.CopyFileToDir("~/.config/icon-data/vscode/settings.json", userDir) } else { - utils.SymlinkIntoDir("~/.config/icon-data/vscode/settings.json", userDir) + utils.SymlinkIntoDir("~/.config/icon-data/vscode/settings.json", userDir, true) } } if utils.GetBoolFlag(cmd, "uninstall") { diff --git a/cmd/jupyter/ganymede.go b/cmd/jupyter/ganymede.go index c831f2e..71e0bb2 100644 --- a/cmd/jupyter/ganymede.go +++ b/cmd/jupyter/ganymede.go @@ -11,7 +11,7 @@ import ( ) // Install and configure Ganymede. -func ganymede(cmd *cobra.Command, args []string) { +func ganymede(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { tmpdir := utils.CreateTempDir("") defer os.RemoveAll(tmpdir) diff --git a/cmd/jupyter/ipython.go b/cmd/jupyter/ipython.go index e49e8c3..c417daa 100644 --- a/cmd/jupyter/ipython.go +++ b/cmd/jupyter/ipython.go @@ -8,7 +8,7 @@ import ( ) // Install and configure IPython. -func ipython(cmd *cobra.Command, args []string) { +func ipython(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { command := utils.Format("{prefix} {pip_install} ipython", map[string]string{ "prefix": utils.GetCommandPrefix( @@ -24,10 +24,10 @@ func ipython(cmd *cobra.Command, args []string) { profile_default := filepath.Join(profile_dir, "profile_default") utils.Symlink( "~/.config/icon-data/ipython/startup.ipy", - filepath.Join(profile_default, "startup/startup.ipy")) + filepath.Join(profile_default, "startup/startup.ipy"), true) utils.SymlinkIntoDir( "~/.config/icon-data/ipython/ipython_config.py", - profile_default) + profile_default, true) } if utils.GetBoolFlag(cmd, "uninstall") { command := utils.Format("{prefix} {pip_uninstall} ipython", map[string]string{ diff --git a/cmd/jupyter/jupyter_book.go b/cmd/jupyter/jupyter_book.go index f664724..bf7d95f 100644 --- a/cmd/jupyter/jupyter_book.go +++ b/cmd/jupyter/jupyter_book.go @@ -8,7 +8,7 @@ import ( ) // Install and configure jupyter_book. -func jupyter_book(cmd *cobra.Command, args []string) { +func jupyter_book(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { command := utils.Format("{pip_install} jupyter-book", map[string]string{ "pip_install": utils.BuildPipInstall(cmd), diff --git a/cmd/jupyter/jupyterlab_vim.go b/cmd/jupyter/jupyterlab_vim.go index 7fe615f..9e02446 100644 --- a/cmd/jupyter/jupyterlab_vim.go +++ b/cmd/jupyter/jupyterlab_vim.go @@ -6,7 +6,7 @@ import ( ) // Install and configure the jupyterlab_vim extension for JupyterLab. -func jupyterlab_vim(cmd *cobra.Command, args []string) { +func jupyterlab_vim(cmd *cobra.Command, _ []string) { prefix := utils.GetCommandPrefix( utils.GetBoolFlag(cmd, "sudo"), map[string]uint32{}, diff --git a/cmd/network/github.go b/cmd/network/github.go index b8a6c5d..04c608c 100644 --- a/cmd/network/github.go +++ b/cmd/network/github.go @@ -83,7 +83,7 @@ func GetLatestRelease(releaseUrl string) ReleaseInfo { // Download a release from GitHub. // @param args: The arguments to parse. // If None, the arguments from command-line are parsed. -func DownloadGitHubReleaseArgs(cmd *cobra.Command, args []string) { +func DownloadGitHubReleaseArgs(cmd *cobra.Command, _ []string) { DownloadGitHubRelease( utils.GetStringFlag(cmd, "repo"), utils.GetStringFlag(cmd, "version"), diff --git a/cmd/network/ssh_client.go b/cmd/network/ssh_client.go index be3d947..8d09aa6 100644 --- a/cmd/network/ssh_client.go +++ b/cmd/network/ssh_client.go @@ -34,11 +34,11 @@ func adjustPathInConfig() { } // Install and configure SSH client. -func SshClient(cmd *cobra.Command, args []string) { +func SshClient(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { } if utils.GetBoolFlag(cmd, "config") { - utils.SymlinkIntoDir("~/.config/icon-data/ssh/client/config", sshHome) + utils.SymlinkIntoDir("~/.config/icon-data/ssh/client/config", sshHome, true) copySshcSettingsFromHost() utils.MkdirAll(filepath.Join(sshHome, "control"), 0o700) /* diff --git a/cmd/network/ssh_server.go b/cmd/network/ssh_server.go index 5267b30..0e2969f 100644 --- a/cmd/network/ssh_server.go +++ b/cmd/network/ssh_server.go @@ -6,7 +6,7 @@ import ( ) // Install and configure SSH server. -func SshServer(cmd *cobra.Command, args []string) { +func SshServer(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { if utils.IsDebianUbuntuSeries() { command := utils.Format("{prefix} apt-get update && {prefix} apt-get install {yes_s} openssh-server fail2ban", map[string]string{ diff --git a/cmd/shell/alacritty.go b/cmd/shell/alacritty.go index b4a48ff..3858733 100644 --- a/cmd/shell/alacritty.go +++ b/cmd/shell/alacritty.go @@ -8,7 +8,7 @@ import ( ) // Install and configure the Alacritty terminal. -func alacritty(cmd *cobra.Command, args []string) { +func alacritty(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { switch runtime.GOOS { case "linux": diff --git a/cmd/shell/atuin.go b/cmd/shell/atuin.go index 5902649..1c24280 100644 --- a/cmd/shell/atuin.go +++ b/cmd/shell/atuin.go @@ -9,7 +9,7 @@ import ( ) // Install atuin. -func atuin(cmd *cobra.Command, args []string) { +func atuin(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { command := "bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh)" utils.RunCmd(command) diff --git a/cmd/shell/bash_it.go b/cmd/shell/bash_it.go index c0b2199..343223c 100644 --- a/cmd/shell/bash_it.go +++ b/cmd/shell/bash_it.go @@ -9,7 +9,7 @@ import ( // Install bash-it, a community Bash framework. // For more details, please refer to https://github.com/Bash-it/bash-it#installation. -func bashIt(cmd *cobra.Command, args []string) { +func bashIt(cmd *cobra.Command, _ []string) { home := utils.UserHomeDir() if utils.GetBoolFlag(cmd, "install") { dir := filepath.Join(home, ".bash_it") @@ -23,7 +23,7 @@ func bashIt(cmd *cobra.Command, args []string) { } if utils.GetBoolFlag(cmd, "config") { utils.ConfigBash() - utils.Symlink("~/.config/icon-data/bash-it", "~/.bash_it") + utils.Symlink("~/.config/icon-data/bash-it", "~/.bash_it", true) } if utils.GetBoolFlag(cmd, "uninstall") { utils.RunCmd("~/.bash_it/uninstall.sh && rm -rf ~/.bash_it/") diff --git a/cmd/shell/fish.go b/cmd/shell/fish.go index 7dfdf1a..78b2602 100644 --- a/cmd/shell/fish.go +++ b/cmd/shell/fish.go @@ -75,7 +75,7 @@ func generateCrazyCompletions() { } // Install and config the fish shell. -func fish(cmd *cobra.Command, args []string) { +func fish(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { switch runtime.GOOS { case "linux": @@ -92,8 +92,7 @@ func fish(cmd *cobra.Command, args []string) { } if utils.GetBoolFlag(cmd, "config") { dir := "~/.config/fish" - utils.BackupDir(dir, "") - utils.Symlink("~/.config/icon-data/fish", dir) + utils.Symlink("~/.config/icon-data/fish", dir, true) generateCompletions() generateCrazyCompletions() diff --git a/cmd/shell/hyper.go b/cmd/shell/hyper.go index 3451366..85150fb 100644 --- a/cmd/shell/hyper.go +++ b/cmd/shell/hyper.go @@ -56,7 +56,7 @@ func hyper(cmd *cobra.Command, _ []string) { log.Printf("Hyper plugins hypercwd, hyper-search, hyper-pane and hyperpower are installed.\n") utils.Symlink( "~/.config/icon-data/hyper/hyper.js", - "~/.hyper.js") + "~/.hyper.js", true) } if utils.GetBoolFlag(cmd, "uninstall") { switch runtime.GOOS { diff --git a/cmd/shell/zellij.go b/cmd/shell/zellij.go index 1d951e9..0792ae6 100644 --- a/cmd/shell/zellij.go +++ b/cmd/shell/zellij.go @@ -11,7 +11,7 @@ import ( ) // Install and configure Ganymede. -func zellij(cmd *cobra.Command, args []string) { +func zellij(cmd *cobra.Command, _ []string) { if utils.GetBoolFlag(cmd, "install") { tmpdir := utils.CreateTempDir("") defer os.RemoveAll(tmpdir) @@ -34,7 +34,7 @@ func zellij(cmd *cobra.Command, args []string) { utils.RunCmd(command) } if utils.GetBoolFlag(cmd, "config") { - utils.Symlink("~/.config/icon-data/zellij/config.kdl", "~/.config/zellij/config.kdl") + utils.Symlink("~/.config/icon-data/zellij/config.kdl", "~/.config/zellij/config.kdl", true) } if utils.GetBoolFlag(cmd, "uninstall") { } diff --git a/cmd/update.go b/cmd/update.go index f28b031..6f2b30e 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -7,7 +7,7 @@ import ( ) // Update icon. -func update(cmd *cobra.Command, args []string) { +func update(cmd *cobra.Command, _ []string) { dir := utils.GetStringFlag(cmd, "install-dir") command := utils.Format(`curl -sSL https://raw.githubusercontent.com/legendu-net/icon/main/install_icon.sh \ | {prefix} bash -s -- -d {dir}`, map[string]string{ diff --git a/cmd/version.go b/cmd/version.go index cacfea9..1b93055 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -7,8 +7,8 @@ import ( ) // Show the version of icon. -func version(_ *cobra.Command, args []string) { - fmt.Println("0.31.2") +func version(_ *cobra.Command, _ []string) { + fmt.Println("0.32.0") } var versionCmd = &cobra.Command{ diff --git a/utils/utils.go b/utils/utils.go index 952729e..9596358 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -967,7 +967,7 @@ fi // @param paths: Absolute paths to add into PATH. // @param config_file: The path of a shell's configuration file. func ConfigShellPath(config_file string) { - if GetLinuxDistId() == "idx" { + if GetLinuxDistID() == "idx" { return } text := ReadFileAsString(config_file) @@ -1234,11 +1234,11 @@ func IsLinux() bool { // if distId == "ubuntu" { // fmt.Println("Running on Ubuntu") // } -func GetLinuxDistId() string { +func GetLinuxDistID() string { m := distro.OSRelease() - distId, found := m["ID"] + distID, found := m["ID"] if found { - return distId + return distID } return "" } @@ -1259,7 +1259,7 @@ func GetLinuxDistId() string { // fmt.Println("Not running on Ubuntu") // } func IsUbuntu() bool { - return GetLinuxDistId() == "ubuntu" + return GetLinuxDistID() == "ubuntu" } // IsDebian checks if the current Linux distribution is Debian. @@ -1278,7 +1278,7 @@ func IsUbuntu() bool { // fmt.Println("Not running on Debian") // } func IsDebian() bool { - return GetLinuxDistId() == "debian" + return GetLinuxDistID() == "debian" } // IsDebianSeries checks if the current Linux distribution belongs to the Debian series. @@ -1303,9 +1303,9 @@ func IsDebianSeries() bool { "antix", "lmde", } - distId := GetLinuxDistId() + distID := GetLinuxDistID() for _, id := range ids { - if distId == id { + if distID == id { return true } } @@ -1339,9 +1339,9 @@ func IsDebianUbuntuSeries() bool { "lmde", "ubuntu", "linuxmint", "pop", } - distId := GetLinuxDistId() + distID := GetLinuxDistID() for _, id := range ids { - if distId == id { + if distID == id { return true } } @@ -1372,7 +1372,7 @@ func IsUbuntuSeries() bool { ids := []string{ "ubuntu", "linuxmint", "pop", } - distId := GetLinuxDistId() + distId := GetLinuxDistID() for _, id := range ids { if distId == id { return true @@ -1405,7 +1405,7 @@ func IsFedoraSeries() bool { ids := []string{ "fedora", "centos", "rhel", } - distId := GetLinuxDistId() + distId := GetLinuxDistID() for _, id := range ids { if distId == id { return true @@ -1501,9 +1501,15 @@ func IsSocket(path string) bool { // @example // // Symlink("/path/to/source/file.txt", "/path/to/link/file.txt") -func Symlink(path string, dstLink string) { +func Symlink(path string, dstLink string, backup bool) { path = NormalizePath(path) dstLink = NormalizePath(dstLink) + if backup { + Backup(dstLink, "") + } else { + RemoveAll(dstLink) + } + MkdirAll(filepath.Dir(dstLink), 0o700) err := os.Symlink(path, dstLink) if err != nil { @@ -1511,8 +1517,8 @@ func Symlink(path string, dstLink string) { } } -func SymlinkIntoDir(path string, dstDir string) { - Symlink(path, filepath.Join(dstDir, filepath.Base(path))) +func SymlinkIntoDir(path string, dstDir string, backup bool) { + Symlink(path, filepath.Join(dstDir, filepath.Base(path)), backup) } // Update map1 using map2. @@ -1555,11 +1561,11 @@ func UpdateMap(map1 orderedmap.OrderedMap[string, any], map2 orderedmap.OrderedM map1.Set(key2, val2) continue } - switch val2.(type) { + switch t2 := val2.(type) { case orderedmap.OrderedMap[string, any]: - switch val1.(type) { + switch t1 := val1.(type) { case orderedmap.OrderedMap[string, any]: - UpdateMap(val1.(orderedmap.OrderedMap[string, any]), val2.(orderedmap.OrderedMap[string, any])) + UpdateMap(t1, t2) default: map1.Set(key2, val2) } @@ -1665,21 +1671,21 @@ func ParseInt(str string) int64 { return i } -func RenameDir(originalDir string, newDir string) { - err := os.Rename(originalDir, newDir) +func Rename(original string, new string) { + err := os.Rename(original, new) if err != nil { log.Fatal(err) } } -func BackupDir(originalDir string, backupDir string) { - originalDir = NormalizePath(originalDir) - backupDir = NormalizePath(backupDir) - if ExistsDir(originalDir) { - if backupDir == "" { - backupDir = filepath.Clean(originalDir) + "_" + time.Now().Format(time.RFC3339) +func Backup(original string, backup string) { + original = NormalizePath(original) + backup = NormalizePath(backup) + if ExistsDir(original) { + if backup == "" { + backup = filepath.Clean(original) + "_" + time.Now().Format(time.RFC3339) } - RenameDir(originalDir, backupDir) - fmt.Printf("%s has been backed up to %s.\n", originalDir, backupDir) + Rename(original, backup) + fmt.Printf("%s has been backed up to %s.\n", original, backup) } }