Rumah >pembangunan bahagian belakang >Golang >Laksanakan peningkatan Deno berdasarkan Go
Selepas arahan naik taraf, saya melaksanakan arahan naik taraf saya sendiri menggunakan bahasa Go.
Mari kita lihat kod sumber Deno dahulu:
use deno_runtime::deno_fetch::reqwest::Client; const RELEASE_URL: &str = "https://github.com/denoland/deno/releases"; ... async fn get_latest_release_version( client: &Client, ) -> Result<String, AnyError> { println!("Looking up latest version"); let res = client .get(&format!("{}/latest", RELEASE_URL)) .send() .await?; let version = res.url().path_segments().unwrap().last().unwrap(); Ok(version.replace("v", "")) }
https://github.com/denoland/deno/releases/latest akan dialihkan ke keluaran terkini https://github.com/ denoland/deno/releases/tag/v1.7.1, melalui operasi rentetan kami mengeluarkan "" kod> Dapatkan nombor versi<code style='padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(145, 109, 213);font-weight: bolder;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;'>replace
方法替换 v
为 ""
得到版本号
让我们用 Go 来实现它:
代码看起来差不多,比如模板字符串写法、字符串处理
package release import ( "net/http" "strings" ) func getLatestVersion() string{ releaseURL := fmt.Sprintf("https://github.com/%s/%s/releases/latest", user, repo) resp, _ := http.Get(releaseURL) defer resp.Body.Close() // 为了防止内存泄漏 pathArr := strings.Split(resp.Request.URL.Path, "/") latest := strings.Replace(pathArr[len(pathArr)-1], "v", "", 1) return latest }
版本的处理少不了SemVer。我们使用 go-version 来处理版本相关工作,有了版本比较我们便可以实现一个版本检查的功能。以下代码是 我封装的 go-release 中的一段代码:
type UpdateInfo struct { IsUpdate bool LatestVersion string } func CheckUpdate(user string, repo string, current string) (updateInfo *UpdateInfo, err error) { releaseURL := fmt.Sprintf("https://github.com/%s/%s/releases/latest", user, repo) resp, err := http.Get(releaseURL) if err != nil { return nil, err } defer resp.Body.Close() current = strings.Replace(current, "v", "", 1) pathArr := strings.Split(resp.Request.URL.Path, "/") latest := strings.Replace(pathArr[len(pathArr)-1], "v", "", 1) currentVersion, err := version.NewVersion(current) if err != nil { return nil, err } latestVersion, err := version.NewVersion(latest) if err != nil { return nil, err } updateInfo = &UpdateInfo{ IsUpdate: currentVersion.LessThan(latestVersion), LatestVersion: latest, } return updateInfo, nil }
下面的代码中,我们基于 go-release 实现了一个带 upgrade
Mari kita laksanakannya dalam Go:
Kod kelihatan serupa, seperti penulisan rentetan templat dan pemprosesan rentetan🎜
const Version = "0.0.1" func checkUpgrade(current string) { fmt.Println("Looking up latest version") update, err := release.CheckUpdate("youngjuning", "tpc", current) if err != nil { panic(err) } if update.IsUpdate { fmt.Printf("Found latest version %v \n", update.LatestVersion) sh.Command("bash", "-c", "curl -fsSL https://raw.githubusercontent.com/youngjuning/tpc/main/install.sh | sh").Run() } else { fmt.Printf("Local version %v is the most recent release \n", current) } } var rootCmd = &cobra.Command{ Use: "app", Version: Version, } var cmdUpgrade = &cobra.Command{ Use: "upgrade", Run: func(cmd *cobra.Command, args []string) { checkUpgrade(Version, force) }, } func main() { rootCmd.AddCommand(cmdUpgrade) rootCmd.Execute() }🎜🎜🎜🎜pengesanan versi🎜🎜
Versi pemprosesan SemVer sangat diperlukan. Kami menggunakan versi go untuk mengendalikan kerja berkaitan versi Dengan perbandingan versi, kami boleh melaksanakan fungsi semakan versi. Kod berikut ialah sekeping kod dalam keluaran go yang dibungkus saya: 🎜
// rootCmd 代表没有调用子命令时的基础命令 var rootCmd = &cobra.Command{ Use: "tpc", Version: Version, Run: func(cmd *cobra.Command, args []string) { sh.Command("tpc", "-h").Run() }, // 每次执行完命令后去执行检查更新,Start 表示不阻塞原来的任务,还有一个 Run 方法则是会阻塞 PersistentPostRun: func(cmd *cobra.Command, args []string) { sh.Command("bash", "-c", "tpc upgrade --force=false").Start() }, }🎜🎜🎜🎜cobra melaksanakan peningkatan🎜🎜
Dalam kod berikut, kami melaksanakan upgrade
perintah CLI mudah, logik teras adalah untuk membandingkan sama ada versi tempatan adalah yang terkini, dan jika tidak, pasang yang terkini. 🎜
const Version = "0.0.1" func checkUpgrade(current string) { fmt.Println("Looking up latest version") update, err := release.CheckUpdate("youngjuning", "tpc", current) if err != nil { panic(err) } if update.IsUpdate { fmt.Printf("Found latest version %v \n", update.LatestVersion) sh.Command("bash", "-c", "curl -fsSL https://raw.githubusercontent.com/youngjuning/tpc/main/install.sh | sh").Run() } else { fmt.Printf("Local version %v is the most recent release \n", current) } } var rootCmd = &cobra.Command{ Use: "app", Version: Version, } var cmdUpgrade = &cobra.Command{ Use: "upgrade", Run: func(cmd *cobra.Command, args []string) { checkUpgrade(Version, force) }, } func main() { rootCmd.AddCommand(cmdUpgrade) rootCmd.Execute() }
Node.js 命令行工具检查更新的正确姿势 对这个问题做了很深入的研究并实现了 Node 版的工具。核心逻辑就是每次执行命令时异步去执行检查更新。这句话翻译成 Go 就是用协程去执行检查更新的动作,这样执行命令还是会立马得到反馈,程序则会在后台执行检查更新,当检测到有新版本则强制更新。
完整代码在go-release/example,对 Cobra 不熟悉的同学可以看一下 Cobra 中文文档。
执行 shell 命令推荐 go-sh,它对 exec 包做了封装,提供了更好地使用体验( PS:还不是因为我菜)
// rootCmd 代表没有调用子命令时的基础命令 var rootCmd = &cobra.Command{ Use: "tpc", Version: Version, Run: func(cmd *cobra.Command, args []string) { sh.Command("tpc", "-h").Run() }, // 每次执行完命令后去执行检查更新,Start 表示不阻塞原来的任务,还有一个 Run 方法则是会阻塞 PersistentPostRun: func(cmd *cobra.Command, args []string) { sh.Command("bash", "-c", "tpc upgrade --force=false").Start() }, }
go-release 核心代码翻译自 Deno 的
upgrade
,开源项目,点赞是我维护的动力,在此求个 Star。
Atas ialah kandungan terperinci Laksanakan peningkatan Deno berdasarkan Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!