Last active
June 8, 2024 10:08
-
-
Save TaQuanMinhLong/a893cce49a865b40d30eaf244587aed0 to your computer and use it in GitHub Desktop.
Update golang version using Nushell script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Config | |
| const INSTALL_DIR = "/usr/local" | |
| const DL_URL = "https://go.dev/dl/" | |
| let num_threads = sys | get cpu | length | |
| let GO_ROOT = $INSTALL_DIR | path join go | |
| let GO_BIN = $GO_ROOT | path join bin | |
| let TMP_DIR = $env.PWD | path join go_dl_tmp | |
| let ADD_TO_PATH = $"add_to_path ($GO_BIN)" | |
| # let ADD_TO_PATH = $"$env.PATH = \(if ($GO_BIN) in $env.PATH { $env.PATH } else { \($env.PATH | split row \(char esep) | append ($GO_BIN)) })" | |
| def get_os [] { | |
| uname | get kernel-name | str downcase | str trim | |
| } | |
| def get_arch [] { | |
| let arch = arch | to text | |
| match $arch { | |
| "x86" => "386", | |
| "x86_64" => "amd64", | |
| "arm" => "armv6l", | |
| "aarch64" => "arm64", | |
| "loongarch64" => "loong64", | |
| "m68k" => "mips", | |
| "csky" => "mips", | |
| "mips" => "mips", | |
| "mips64" => "mips64", | |
| "powerpc" => "ppc64", | |
| "powerpc64" => "ppc64", | |
| "riscv64" => "riscv64", | |
| "s390x" => "s390x", | |
| "sparc64" => "amd64", | |
| _ => "", | |
| } | |
| } | |
| def get_version [] { | |
| if (which go | is-empty) { | |
| return "null" | |
| } | |
| return (go version | parse "go version go{major}.{minor}.{patch} {os}/{arch}") | |
| } | |
| def is_up_to_date [current, latest] { | |
| if ($current.major != $latest.major) { | |
| return false | |
| } | |
| if ($current.minor != $latest.minor) { | |
| return false | |
| } | |
| if ($current.patch != $latest.patch) { | |
| return false | |
| } | |
| return true | |
| } | |
| def check_update [] { | |
| print "Checking for updates... π§" | |
| let query = {mode: "json"} | url build-query | |
| let url = [$DL_URL ? $query] | str join | |
| let data = http get $url | first 1 | |
| let version = $data | get version | parse "go{major}.{minor}.{patch}" | |
| let os = get_os | |
| let arch = get_arch | |
| let file = $data.files.0 | where os == $os and arch == $arch | |
| if ($file | is-empty) { | |
| print $"π¨ Error: No download target found for OS = ($os) and ARCH = ($arch)" | |
| exit 1 | |
| } | |
| let filename = $file.0.filename | |
| return {version: $version, filename: $filename} | |
| } | |
| def download [file_name: string, file_size: int ] { | |
| rm -rf $TMP_DIR | |
| mkdir $TMP_DIR | |
| cd $TMP_DIR | |
| let per_thread = $file_size // $num_threads | |
| let remain = $file_size mod $num_threads | |
| let timer_start = date now | |
| 0..($num_threads - 1) | par-each {|i| | |
| let start = $i * $per_thread | |
| mut end = if $i == ($num_threads - 1) {$file_size - 1} else {($i + 1) * $per_thread - 1} | |
| let bytes_header = [range $"bytes=($start)-($end)"] | |
| let url = $"($DL_URL)($file_name)" | |
| let tmp_file = $"($i | fill -a right -c 0 -w 3)_tmp_($start)_($end)" | |
| http get -H $bytes_header $url | save $tmp_file | |
| } | |
| let file_path = $TMP_DIR | path join $file_name | |
| ls -s | sort-by name | each {|f| open $f.name | into binary } | bytes collect | save -frap $file_path | |
| let duration = (date now) - $timer_start | format duration ms | |
| print $"Download finished in ($duration) β " | |
| return $file_path | |
| } | |
| let update_info = check_update | |
| let latest = $update_info.version | |
| let current = get_version | |
| if ($current != "null") and (is_up_to_date $current $latest) { | |
| print "Go is up to date π" | |
| print $"(go version) β " | |
| exit 0 | |
| } | |
| print "Removing old version... π§" | |
| sudo rm -rf $GO_ROOT | |
| let file_name = $update_info.filename | to text | |
| let file_size = http head ($DL_URL | path join $file_name) | where name == "content-length" | get value | to text | into int | |
| print $"Downloading new version: ($file_name) \(($file_size) bytes)... β³" | |
| let file_path = download $file_name $file_size | |
| open $file_path | bytes length | print | |
| sudo tar -xzvf $file_path -C $INSTALL_DIR | |
| print "Cleaning up temporary files... π§Ή" | |
| rm -rf $TMP_DIR | |
| let added_to_path = $GO_BIN in $env.PATH | |
| if not $added_to_path { | |
| print "Adding Go binary dir to $PATH" | |
| open ($nu.env-path) | append $ADD_TO_PATH | save -f $nu.env-path | |
| } | |
| print $"Update successfully: (go version) β " |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment