Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite PowerShell with Go for better Windows scripting #282

Merged
merged 4 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .github/workflows/ci-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
os:
- ubuntu-latest
- macos-13
- windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand All @@ -35,14 +36,8 @@ jobs:
with:
go-version-file: 'go.mod'
cache-dependency-path: 'go.sum'
# https://github.com/davidB/rust-cargo-make/pull/178 is the blocker, even if this action is recommended in cargo-make official docs
- uses: asdf-vm/actions/install@v2
with:
# Keep same version as used in *.nix
tool_versions: |
cargo-make 0.36.12
# - run: go test
- run: makers test-go-race
- run: go build -v -race ./...
lint:
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"nil": {
"formatting": { "command": ["nixpkgs-fmt"] }
}
},
"gopls": {
"build.buildFlags": ["-tags=linux,windows,darwin"]
}
}
2 changes: 2 additions & 0 deletions cmd/add_nix_channels/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux || darwin

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/deps/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux || darwin

package main

import (
Expand Down
25 changes: 25 additions & 0 deletions cmd/disable_windows_beeps/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build windows

package main

import (
"log"

"golang.org/x/sys/windows/registry"
)

// # https://github.com/kachick/times_kachick/issues/214
func main() {
key, err := registry.OpenKey(registry.CURRENT_USER, `Control Panel\Sound`, registry.SET_VALUE)
if err != nil {
log.Fatalf("Failed to open registry key: %+v", err)
}
defer key.Close()

err = key.SetStringValue("Beep", "no")
if err != nil {
log.Fatalf("Failed to update registry: %+v", err)
}

log.Println("Completed to disable beeps, you need to restart Windows to activate settings")
}
2 changes: 2 additions & 0 deletions cmd/enable_nix_login_shells/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux || darwin

package main

import (
Expand Down
34 changes: 34 additions & 0 deletions cmd/enable_windows_verbose_context_menu/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//go:build windows

package main

import (
"log"

"golang.org/x/sys/windows/registry"
)

func main() {
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Classes\CLSID`, registry.CREATE_SUB_KEY)
if err != nil {
log.Fatalf("Failed to open registry key: %+v", err)
}
defer key.Close()

newKey, isExists, err := registry.CreateKey(key, `{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32`, registry.SET_VALUE)
if err != nil {
log.Fatalf("Failed to update registry: %+v", err)
}
defer newKey.Close()
if isExists {
log.Println("Skipped to create registry key, because it is already exists")
return
}

err = newKey.SetStringValue("", "")
if err != nil {
log.Fatalf("Failed to set empty default value, may need to fallback manually: %+v", err)
}

log.Println("Completed to enable classic style of context menu, you need to restart all explorer.exe processes to activate settings")
}
2 changes: 2 additions & 0 deletions cmd/fmt/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux || darwin

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions cmd/lint/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build linux || darwin

package main

import (
Expand Down
65 changes: 65 additions & 0 deletions cmd/setup_windows_terminals/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//go:build windows

package main

import (
"flag"
"log"
"os"
"path"
"path/filepath"

"github.com/kachick/dotfiles"
)

func main() {
dotsPathFlag := flag.String("dotfiles_path", "", "Specify dotfiles repository path in your local")
pwshProfilePathFlag := flag.String("pwsh_profile_path", "", "Specify PowerShell profile path")
flag.Parse()
dotsPath := filepath.Clean(*dotsPathFlag)
pwshProfilePath := filepath.Clean(*pwshProfilePathFlag)

if dotsPath == "" || pwshProfilePath == "" || len(os.Args) < 2 {
flag.Usage()
log.Fatalf("called with wrong arguments")
}

homePath, err := os.UserHomeDir()
if err != nil {
log.Fatalf("Failed to get home directory: %+v", err)
}

appdataPath, ok := os.LookupEnv("APPDATA")
if !ok {
log.Fatalln("ENV APPDATA is not found")
}

// As I understand it, unix like permission masks will work even in windows...
err = os.MkdirAll(filepath.Join(homePath, ".config", "alacritty"), 0750)
if err != nil {
log.Fatalf("Failed to create dotfiles directory: %+v", err)
}
err = os.MkdirAll(path.Join(appdataPath, "alacritty"), 0750)
if err != nil {
log.Fatalf("Failed to create path that will have alacritty.yml: %+v", err)
}

copies := []dotfiles.Copy{
{Src: filepath.Join(dotsPath, "home", ".config", "starship.toml"), Dst: filepath.Join(homePath, ".config", "starship.toml")},
{Src: filepath.Join(dotsPath, "home", ".config", "alacritty", "alacritty-common.yml"), Dst: filepath.Join(homePath, ".config", "alacritty", "alacritty-common.yml")},
{Src: filepath.Join(dotsPath, "home", ".config", "alacritty", "alacritty-windows.yml"), Dst: filepath.Join(homePath, ".config", "alacritty", "alacritty.yml")},
{Src: filepath.Join(dotsPath, "windows", "config", "Profile.ps1"), Dst: pwshProfilePath},
}

for _, copy := range copies {
err := copy.Run()
if err != nil {
log.Fatalf("Failed to copy file: %+v %+v", copy, err)
}
}

log.Printf(`Completed, you need to restart terminals

If you faced slow execution of PowerShell after this script, exclude %s from Anti Virus as Microsoft Defender
`, pwshProfilePath)
}
15 changes: 2 additions & 13 deletions cmd/setup_wsl/main.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//go:build linux
// +build linux

package main

import (
"fmt"
"io"
"log"
"os"
"os/exec"
"strings"

"github.com/kachick/dotfiles"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -75,17 +74,7 @@ func mustPersistDockerZshCompletions() {
}
// Can't make immutable symlink, so copy and make immutable here
// https://unix.stackexchange.com/questions/586430/how-to-make-a-symlink-read-only-chattr-i-location-symlink
target, err := os.Create(completionLoadablePath)
if err != nil {
log.Panicf("%+v\n", err)
}
defer target.Close()
integration, err := os.Open("dependencies/docker/zsh-vendor-completions.zsh")
if err != nil {
log.Panicf("%+v\n", err)
}
defer integration.Close()
_, err = io.Copy(target, integration)
err = dotfiles.Copy{Src: "dependencies/docker/zsh-vendor-completions.zsh", Dst: completionLoadablePath}.Run()
if err != nil {
log.Panicf("%+v\n", err)
}
Expand Down
27 changes: 27 additions & 0 deletions copy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dotfiles

import (
"io"
"os"
)

type Copy struct {
Src string
Dst string
}

func (c Copy) Run() error {
src, err := os.Open(c.Src)
if err != nil {
return err
}
defer src.Close()
dst, err := os.Create(c.Dst)
if err != nil {
return err
}
defer dst.Close()

_, err = io.Copy(dst, src)
return err
}
32 changes: 24 additions & 8 deletions windows/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
# FAQ

## Configuration steps after installation packages
## Installation

1. ```powershell
winget import --import-file "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles\windows\config\winget-pkgs-basic.json"
winget import --import-file "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles\windows\config\winget-pkgs-dev.json"
```
1. New session of pwsh
```powershell
go run github.com/kachick/dotfiles/cmd/setup_windows_terminals -dotfiles_path "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles" -pwsh_profile_path "$PROFILE"
go run github.com/kachick/dotfiles/cmd/disable_windows_beeps
go run github.com/kachick/dotfiles/cmd/enable_windows_verbose_context_menu
```
1. Change Dropbox storage path from `C:\Users`, default path made problems in System Restore.
\
See https://zmzlz.blogspot.com/2014/10/windows-dropbox.html for detail
1. On powershell
```powershell
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles\windows\scripts\bootstrap.ps1 -DotfilesPath "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles"
```
1. Exclude the `$PROFILE\Profile.ps1` from Anti Virus detection as Microsoft Defender
1. Enable Bitlocker and backup the restore key

## How to run go scripts in this repo?

After installed golang with winget, you can run github hosting files

```console
Administrator in ~ psh
> go run github.com/kachick/dotfiles/cmd/disable_windows_beeps@39ac6dc
2023/08/22 15:34:18 Completed to disable beeps, you need to restart Windows to activate settings
```

Specifying with branch name with the @ref may use cache, then specify commit ref

## How to install WSL2?

winget does not support it, run as follows
Expand All @@ -35,7 +51,7 @@ One more noting, if you cannot find ngen.exe, dig under "C:\Windows\Microsoft.NE
## How to export winget list?

```powershell
winget export --output "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles\windows\config\winget-list-$(Get-Date -UFormat '%F')-raw.json"
winget export --output "\\wsl.localhost\Ubuntu\home\kachick\repos\dotfiles\windows\config\winget-pkgs-$(Get-Date -UFormat '%F')-raw.json"
```

It may be better to remove some packages such as `Mozilla.Firefox.DeveloperEdition`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@
{
"PackageIdentifier" : "7zip.7zip"
},
{
"PackageIdentifier" : "BurntSushi.ripgrep.MSVC"
},
{
"PackageIdentifier" : "Canonical.Ubuntu.2204"
},
{
"PackageIdentifier" : "Docker.DockerDesktop"
},
{
"PackageIdentifier" : "Dropbox.Dropbox"
},
Expand All @@ -27,9 +18,6 @@
{
"PackageIdentifier" : "Microsoft.EdgeWebView2Runtime"
},
{
"PackageIdentifier" : "Microsoft.WindowsTerminal"
},
{
"PackageIdentifier" : "Microsoft.OneDrive"
},
Expand All @@ -48,24 +36,9 @@
{
"PackageIdentifier" : "Microsoft.VCRedist.2015+.x64"
},
{
"PackageIdentifier" : "Lapce.Lapce"
},
{
"PackageIdentifier" : "Microsoft.PowerShell"
},
{
"PackageIdentifier" : "Alacritty.Alacritty"
},
{
"PackageIdentifier" : "Google.GoogleDrive"
},
{
"PackageIdentifier" : "Starship.Starship"
},
{
"PackageIdentifier" : "Microsoft.VisualStudioCode"
},
{
"PackageIdentifier" : "Google.Chrome"
},
Expand Down
Loading