From 97b2a2fbb0149b65ee93c3cda8801ab34ef903f5 Mon Sep 17 00:00:00 2001 From: K Date: Sun, 31 Dec 2023 01:48:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpager=3Dmore=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98;=20=E4=BF=AE=E5=A4=8D--update=E6=97=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=9D=83=E9=99=90=E9=97=AE=E9=A2=98;=20build?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release-tags.yml | 16 ++--- README.md | 8 ++- cmd/kd.go | 1 + internal/update/update.go | 96 ++++++++++++++++++++---------- logger/logger.go | 7 ++- pkg/terminal.go | 36 +++++++++-- plan.md | 13 ++-- scripts/build.sh | 91 ++++++++++++++-------------- 8 files changed, 169 insertions(+), 99 deletions(-) diff --git a/.github/workflows/release-tags.yml b/.github/workflows/release-tags.yml index 217f6dc..b714a0b 100644 --- a/.github/workflows/release-tags.yml +++ b/.github/workflows/release-tags.yml @@ -21,6 +21,14 @@ jobs: steps: - uses: actions/checkout@v3 + - name: "Build Changelog" + id: build_changelog + uses: mikepenz/release-changelog-builder-action@v4 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + commitMode: true + - name: Set up Go uses: actions/setup-go@v4 with: @@ -38,14 +46,6 @@ jobs: bash scripts/build.sh linux arm64 bash scripts/build.sh windows amd64 - - name: "Build Changelog" - id: build_changelog - uses: mikepenz/release-changelog-builder-action@v4 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - commitMode: true - - name: echo changelog run: echo ${{steps.build_changelog.outputs.changelog}} diff --git a/README.md b/README.md index bcd1903..597bf7a 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ sudo sh -c 'curl --create-dirs -L -o /usr/local/bin/kd && chmod +x /usr/local/bin/kd' ``` + ### Windows @@ -79,8 +80,9 @@ sudo sh -c 'curl --create-dirs -L -o /usr/local/bin/kd && chmod +x /usr/lo 用Powershell执行: ```powershell -# 下载文件放入C:\bin -Invoke-WebRequest -uri '' -OutFile ( New-Item -Path "C:\bin\kd.exe" -Force ) +# 下载文件放入C:\bin,这里是Win64位架构,其他架构需求请提交issue +Invoke-WebRequest -uri 'https://github.com/Karmenzind/kd/releases/latest/download/kd_windows_amd64.exe' -OutFile ( New-Item -Path "C:\bin\kd.exe" -Force ) + # (需要管理员权限)将C:\bin加入PATH环境变量 [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\bin", "Machine") ``` @@ -126,7 +128,7 @@ GLOBAL OPTIONS: ```toml # 是否使用分页器,MacOS上默认false paging = true -# 分页器命令,例如:less -F / bat / more +# 分页器命令,例如:less -F / bat / more -e pager_command = "less -F" # 本地最多缓存的单词条数 diff --git a/cmd/kd.go b/cmd/kd.go index 82f58f8..9583b45 100644 --- a/cmd/kd.go +++ b/cmd/kd.go @@ -171,6 +171,7 @@ func flagStatus(*cli.Context, bool) error { fmt.Printf(" Daemon PID:%d\n", di.PID) fmt.Printf(" 配置文件地址:%s\n", config.CONFIG_PATH) fmt.Printf(" 数据文件目录:%s\n", cache.CACHE_ROOT_PATH) + fmt.Printf(" Log地址:%s\n", logger.LOG_FILE) kdpath, err := pkg.GetExecutablePath() if err == nil { fmt.Printf(" Binary地址:%s\n", kdpath) diff --git a/internal/update/update.go b/internal/update/update.go index 2b153d9..e2d4c7d 100644 --- a/internal/update/update.go +++ b/internal/update/update.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "os" + "os/exec" "path/filepath" "regexp" "runtime" @@ -20,6 +21,7 @@ import ( "go.uber.org/zap" ) +// var LATEST_RELEASE_URL = "http://localhost:8901/" var LATEST_RELEASE_URL = "https://github.com/Karmenzind/kd/releases/latest/download/" var TAGLIST_URL = "https://api.github.com/repos/Karmenzind/kd/tags" @@ -122,39 +124,73 @@ func GetNewerVersion(currentTag string) (tag string, err error) { } func UpdateBinary(currentTag string) (err error) { + _ = currentTag // emoji.Println(":eyes: 不好意思更新功能没写好,请手动到release下载") - tmpPath := filepath.Join(cache.CACHE_ROOT_PATH, "kd.temp") - url := getBinaryURL() - - var exepath string - exepath, err = pkg.GetExecutablePath() - if err != nil { - return err - } - if strings.Contains(exepath, "go-build") { - fmt.Println("非binary,已忽略") - return nil - } - - d.EchoRun(fmt.Sprintf("Start downloading: %s", url)) - err = pkg.DownloadFile(tmpPath, url) - if err != nil { - zap.S().Errorf("Failed to download binary file: %s", err) - } - d.EchoRun("已下载完成") - err = os.Rename(tmpPath, exepath) - d.EchoRun("已成功覆盖") - if err != nil { - return err - } - if runtime.GOOS != "windows" { - err = pkg.AddExecutablePermission(exepath) - if err != nil { - d.EchoWrong(fmt.Sprintf("修改权限失败,请手动执行`chmod +x %s`", exepath)) - } - } + tmpPath := filepath.Join(cache.CACHE_ROOT_PATH, "kd.temp") + url := getBinaryURL() + + var exepath string + exepath, err = pkg.GetExecutablePath() + if err != nil { + return err + } + if strings.Contains(exepath, "go-build") { + fmt.Println("非binary,已忽略") + return nil + } + + d.EchoRun(fmt.Sprintf("Start downloading: %s", url)) + // TODO (k): <2023-12-31> 调用curl + err = pkg.DownloadFile(tmpPath, url) + if err != nil { + zap.S().Errorf("Failed to download binary file: %s", err) + } + d.EchoRun("已下载完成") + err = moveFile(tmpPath, exepath) + if err != nil { + return + } else { + d.EchoRun("已成功覆盖") + } + if runtime.GOOS != "windows" { + err = pkg.AddExecutablePermission(exepath) + if err != nil { + d.EchoWrong(fmt.Sprintf("修改权限失败,请手动执行`chmod +x %s`", exepath)) + } + } return // emoji.Println(":lightning: Now we start updating the binary") // emoji.Println(":lightning: updating...") // emoji.Println(":beer: DONE :)") } + +// try sudo if needed +func moveFile(src, tgt string) (err error) { + err = os.Rename(src, tgt) + if err == nil { + return + } + zap.S().Infof("Permission denied. Please make sure you have write access to the destination directory.") + if runtime.GOOS == "windows" { + return fmt.Errorf("文件覆盖失败,遇到权限问题,请到release页面下载") + } + + cmd := exec.Command("sudo", "mv", src, tgt) + cmd.Stdin = os.Stdin + d.EchoRun("覆盖文件需root权限,请输入密码") + err = cmd.Run() + // if linkErr, ok := err.(*os.LinkError); ok { + // if os.IsPermission(linkErr.Err) { + // zap.S().Infof("Permission denied. Please make sure you have write access to the destination directory.") + // if runtime.GOOS == "windows" { + // return fmt.Errorf("文件覆盖失败,遇到权限问题,请到release页面下载") + // } + + // cmd := exec.Command("sudo", "mv", src, tgt) + // cmd.Stdin = os.Stdin + // d.EchoRun("覆盖文件需root权限,请输入密码") + // err = cmd.Run() + // } + // } + return +} diff --git a/logger/logger.go b/logger/logger.go index df77350..def1243 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -11,6 +11,8 @@ import ( "go.uber.org/zap" ) +var LOG_FILE string + func buildLogger(logCfg *config.LoggerConfig, options ...zap.Option) (*zap.Logger, error) { cfg := zap.NewDevelopmentConfig() var f string @@ -19,8 +21,8 @@ func buildLogger(logCfg *config.LoggerConfig, options ...zap.Option) (*zap.Logge if err != nil { f = filepath.Join(os.TempDir(), "kd.log") } else { - name := strings.ReplaceAll(u.Username, " ", "_") - name = strings.ReplaceAll(name, "\\", "_") + name := strings.ReplaceAll(u.Username, " ", "_") + name = strings.ReplaceAll(name, "\\", "_") f = filepath.Join(os.TempDir(), fmt.Sprintf("kd_%s.log", name)) } } else { @@ -29,6 +31,7 @@ func buildLogger(logCfg *config.LoggerConfig, options ...zap.Option) (*zap.Logge if _, err := os.Stat(f); err == nil { os.Chmod(f, 0o666) } + LOG_FILE = f cfg.OutputPaths = []string{f} cfg.ErrorOutputPaths = []string{f} diff --git a/pkg/terminal.go b/pkg/terminal.go index d42a37d..a8fb226 100644 --- a/pkg/terminal.go +++ b/pkg/terminal.go @@ -49,11 +49,12 @@ func GetExecutableBasename() (string, error) { // pager or print // config > $PAGER > less -f // TODO 增加检测pager可用 -func OutputResult(out string, paging bool, pagerCmd string, clear bool) error { +func OutputResult(out string, paging bool, pagerCmd string, doClear bool) error { var err error var logger = zap.S() if paging { if pagerCmd == "" { + // XXX (k): <2023-12-31> expandenv? if sysPager := os.Getenv("PAGER"); sysPager != "" { logger.Debugf("Using system pager %s", sysPager) pagerCmd = sysPager @@ -80,15 +81,17 @@ func OutputResult(out string, paging bool, pagerCmd string, clear bool) error { pager = exec.Command(pagerCmd) } if CommandExists(program) { - pager.Stdin = strings.NewReader(out) + // pager.Stdin = strings.NewReader(out) pager.Stdout = os.Stdout - err = pager.Run() + pager.Stderr = os.Stderr + err = Output2PagerVer2(pager, out) + // err = pager.Run() return err } d.EchoWarn(fmt.Sprintf("pager command `%s` not found", program)) } } - if clear { + if doClear { _, h, err := GetTermSize() if err == nil && strings.Count(out, "\n") < h { ClearScreen() @@ -98,6 +101,31 @@ func OutputResult(out string, paging bool, pagerCmd string, clear bool) error { return nil } +func Output2PagerVer1(pager *exec.Cmd, output string) (err error) { + pager.Stdin = strings.NewReader(output) + err = pager.Run() + + return err +} + +func Output2PagerVer2(pager *exec.Cmd, output string) (err error) { + pipe, err := pager.StdinPipe() + if err != nil { + return + } + + if err = pager.Start(); err != nil { + return err + } + + defer func() { + pipe.Close() + pager.Wait() + }() + fmt.Fprintln(pipe, output) + return err +} + func CommandExists(cmd string) bool { _, err := exec.LookPath(cmd) return err == nil diff --git a/plan.md b/plan.md index 6b5534c..e7ca437 100644 --- a/plan.md +++ b/plan.md @@ -1,8 +1,6 @@ #master plan ## wip -- mac编译 -- 测试mac的DB初始化情况 - powershell命令改成当前用户范围 - 测试windows的--update @@ -23,6 +21,7 @@ - 加入词库设置,供选择词库大小 ## low priority +- --update下载之后缓存,避免重复下载 - cli替换为cobra - source数据 分为base-sourse & web-source - 刷数据,去掉音标[] @@ -34,16 +33,13 @@ # BUG -## Build failed - -mac arm64 / amd64 - -(action) linux 386 +provide: see also ## Risk - 实际文件名 不改的时候的process_name -# Others +## low priority +- (action) linux 386 ## 写入release介绍 @@ -56,3 +52,4 @@ mac arm64 / amd64 如果没有你所使用的平台/架构,请提交issue反馈 如果下载受阻,请前往gitee备份页面 + diff --git a/scripts/build.sh b/scripts/build.sh index be9471f..7404af6 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -13,65 +13,68 @@ mkdir -p $targetdir do_build() { local os=$1 local arch=$2 + local targetfile=$3 - local cgo=1 cc= + local cgo=1 cc= - local filename=kd_${os}_${arch} - [[ $os == "darwin" ]] && filename=kd_macos_${arch} + if [[ $targetfile == "" ]] && [[ $os != "" ]] && [[ $arch != "" ]]; then + echo ">>> Building for $os $arch..." - local targetfile=${targetdir}/${filename} - [[ $os == "windows" ]] && targetfile=${targetfile}.exe + local filename=kd_${os}_${arch} + [[ $os == "darwin" ]] && filename=kd_macos_${arch} - case $os in - windows ) - local cc=x86_64-w64-mingw32-gcc - local buildopts=-buildmode=c-shared - ;; - linux ) - if [[ $arch == "arm64" ]]; then - local cc=aarch64-linux-gnu-gcc - fi - ;; - darwin) - # TODO (k): <2023-12-21> - ;; - esac + local targetfile=${targetdir}/${filename} + [[ $os == "windows" ]] && targetfile=${targetfile}.exe + fi + + case $os in + windows) + local cc=x86_64-w64-mingw32-gcc + local buildopts=-buildmode=c-shared + ;; + linux) + if [[ $arch == "arm64" ]]; then + local cc=aarch64-linux-gnu-gcc + fi + ;; + darwin) + # TODO (k): <2023-12-21> + ;; + esac GOOS=$os GOARCH=$arch CGO_ENABLED=$cgo CC=$cc go build ${buildopts} -o ${targetfile} -ldflags="-s -w" -tags urfave_cli_no_docs cmd/kd.go - if (($?==0)); then - echo " Finished -> ${targetfile}" - else - echo " Failed to build for $os $arch" - fi + if (($? == 0)); then + echo " Finished -> ${targetfile}" + else + echo " Failed to build for $os $arch" + fi } build_all() { - declare -A d=( - ["darwin"]="amd64 arm64" - ["linux"]="amd64 arm64" - ["windows"]="amd64" - ) - rm -rfv $targetdir/* + declare -A d=( + ["darwin"]="amd64 arm64" + ["linux"]="amd64 arm64" + ["windows"]="amd64" + ) + rm -rfv $targetdir/* for os in "${!d[@]}"; do for arch in ${d[$os]}; do - echo ">>> Building for $os $arch..." do_build $os $arch $targetfile done done } - -if [[ $1 == "" ]]; then - echo ">>> Building for current platform..." - do_build '' '' ${PROJECT_DIR}/kd -fi - case $1 in - -a ) - build_all - ;; - *) - do_build $* - ;; +"") + echo ">>> Building for current workspace..." + # do_build '' '' ${PROJECT_DIR}/kd + do_build '' '' /usr/local/bin/kd + exit + ;; +-a) + build_all + ;; +*) + do_build $* + ;; esac -