外部命令行工具 ongoing
Scoop
INFO
Scoop 是专门为 Windows 平台开发的包管理工具.
类似功能的工具还有 Chocolatey 以及 Windows 自带的 Winget.
对比 Scoop, Chocolatey, Winget (ChatGPT)
Scoop、Chocolatey 和 Winget 都是 Windows 上常用的包管理工具,它们各自有不同的特点和优劣势:
Scoop:
- 特点:
- 简单、轻量级,基于 PowerShell。
- 每个软件包被视为一个独立的 Git 仓库,使得安装和更新过程直观明了。
- 主要使用 GitHub 作为软件包的源。
- 适合开发者和技术爱好者,特别是对于开发工具的需求。
- 适用场景:
- 管理开发工具和一些实用程序。
- 特点:
Chocolatey:
- 特点:
- 类似传统的包管理器,使用脚本和二进制包来安装和管理软件。
- 庞大的社区支持,软件包数量庞大,覆盖各种类型的软件。
- 提供数字签名和校验功能,确保软件包的完整性和来源。
- 支持多种软件包源,包括 Chocolatey 社区仓库和官方软件库。
- 适用场景:
- 适合企业环境或需要大量软件部署的场景。
- 特点:
Winget:
- 特点:
- 微软官方推出的包管理器,可以用于命令行安装软件,类似于其他包管理器如 apt、yum 和 dnf。
- 使用微软的软件库作为主要软件源,可以保证软件的来源和安全性。
- 适用场景:
- 适合广泛的 Windows 用户,尤其是那些希望使用官方工具的用户。
- 特点:
总结:
- 如果你喜欢简洁、轻量级的工具,并主要需要开发者工具,那么选择 Scoop 可能更适合你。
- 如果你需要一个功能丰富、庞大社区支持的包管理器,或者在企业环境中部署软件,那么 Chocolatey 是一个不错的选择。
- 如果你希望使用微软官方提供的工具,并且对软件来源和安全性有较高要求,那么 Winget 可能是一个理想的选择。
最终的选择取决于你的个人偏好以及特定的使用场景。
搜索软件包
可以使用以下命令搜索.
scoop search [package]WARNING
不推荐使用命令搜索, 因为速度较慢.
建议直接在官网 https://scoop.sh/ 搜索.
检查可更新的软件包
scoop update # 获取最新的版本信息
scoop status # 检查可更新的软件包
scoop update [package] # 更新清理所有旧版本
在更新软件包之后, scoop 不会自动清理旧版本.
如果希望将所有软件包的旧版本都删除, 可以这么做:
scoop cleanup -ak # 短选项
scoop cleanup --all --cache # 长选项单用户或全局安装
默认情况下, scoop install 命令会将软件包安装在当前用户的路径下.
但我们也可以使用以下命令全局安装 (安装在系统中给所有用户使用):
scoop install -g # 短选项
scoop install --global # 长选项WARNING
需要使用 管理员 权限才能全局安装.
因此需要以管理员身份启动终端, 然后执行以上命令.
部分软件包只能全局安装, 这种情况下的 scoop install 命令会被默认加上 -g 选项.
Scoop 中名为 nonportable 的 bucket 基本上只能全局安装.
TIP
Nvidia 显卡驱动推荐使用 Scoop 来安装.
毕竟 GeForce Experience 登录后才能更新驱动, 又经常需要重新登陆.
HomeBrew
INFO
HomeBrew 是 macOS 中使用最广泛的包管理工具.
自动卸载依赖
brew uninstall 命令只会卸载软件, 不会卸载其所依赖的软件包.
HomeBrew 也没有任何自带的命令可以做到这一点.
因此我们需要额外安装 brew-rmtree 工具来扩展 brew 命令的功能, 实现自动卸载依赖.
brew tap beeftornado/rmtree # 添加三方仓库
brew install brew-rmtree # 安装 brew-rmtree 工具
brew rmtree [package] # 卸载软件包及其依赖如果打算使用 HomeBrew 原生命令来清理依赖, 可以这么做:
brew uninstall [package] # 卸载目标 package
brew autoremove # 移除所有 "因为被依赖才被安装的 package"禁用软件包的更新
默认情况下, 如果使用 brew upgrade 命令将会自动更新所有软件包.
在这种情况下如果希望个别软件包不要被更新, 则可以使用 pin 命令.
brew pin [package] # 禁止更新
brew unpin [package] # 恢复正常, 可以更新删除过时的安装包
brew cleanup 只会删除 "在电脑中保留超过 120 天" 的安装包.
若希望删除所有安装包, 可以使用以下命令:
brew cleanup --prune allBtop
简介和截图
在 Linux 中 top 命令可以实时查看当前设备的 CPU, 内存, 网络, 进程等信息.
而 btop 就是 top 的上位替代. 界面更美观清晰, 可定制, 更易用, 且跨平台.

常用快捷键
TIP
大多数快捷键都可以直接从 UI 中看到, 例如上图中各单词的红色字母.
所有快捷键可以通过 Ecs 打开菜单后进一步查看.
| 快捷键 | 功能 | 提示词 |
|---|---|---|
Esc | 打开菜单 | |
Q | 退出 | Quit |
Asciinema
简介和安装
asciinema 可以理解为 "专门为命令行界面制作的录屏和播放工具".
例如我们有些时候会在 GitHub 代码仓库的 README 中看到下面这种画面:
asciinema cli 使用使用 python 开发, 因此可以使用 pip 安装.
pip install asciinemaWARNING
asciinema cli 无法在 Windows 系统中运行, 可以考虑使用替代方案 powersession.
可以用来录制 PowerShell 的命令行界面 (局限在于不能录制其他 Shell).
使用方法非常接近. 通过 Scoop 安装 powersession:
scoop install powersession-rs常用命令
asciinema rec # 开始录制, 快捷键 Ctrl+D 停止录制
asciinema play [file-name] # 播放录制好的本地文件
asciinema cat [file-name] # 直接展示录制结果的最后一帧TIP
如果需要将录制的视频转换为 gif, 可以使用官方的 agg 工具.
Tokei
Tokei 简介
Tokei 用于统计代码行数.
scoop install tokeibrew install tokei使用场景
基础使用:
# 统计当前路径下的所有编程语言 (忽略那些被 .gitignore 的文件)
tokei ./输出结果的格式如下:
===============================================================================
Language Files Lines Code Comments Blanks
===============================================================================
Dockerfile 1 28 16 10 2
HTML 1 26 20 0 6
Markdown 1 3 0 2 1
TOML 2 45 30 10 5
YAML 1 27 23 1 3
-------------------------------------------------------------------------------
Rust 7 462 377 9 76
|- Markdown 4 32 0 31 1
(Total) 494 377 40 77
===============================================================================
Total 13 591 466 32 93
===============================================================================常用选项:
# 统计当前路径下的所有编程语言 (无视 .gitignore)
tokei ./ --no-ignore
# 统计当前路径, 并按照行数排序
# --sort 的可选值包括 blanks, code, comments, lines
tokei ./ --sort lines
# 统计当前路径, 但忽略所有 .rs 文件
tokei ./ --exclude *.rs
# 只统计 rust 和 markdown 两种语言
tokei ./ -t=rust,markdownUnity CLI
INFO
这里只记录比较重要且常用的子命令与选项.
详见 Unity 官方文档 Unity Editor command line arguments.
调用静态方法
我们需要找到具体版本的 Unity 来执行命令, 例如以下路径:
/c/Program\ Files/Unity/Hub/Editor/2021.2.13f1c1/Editor/Unity.exe
此文档中使用 $UNITY_EXECUTABLE_PATH 代表 Unity 引擎的可执行文件路径.
以下命令可以调用位于 Editor 文件夹内的代码的静态方法.
为了在命令行中返回错误信息, 可以通过抛出异常来实现.
$UNITY_EXECUTABLE_PATH -executeMethod [ClassName.MethodName]
$UNITY_EXECUTABLE_PATH -executeMethod [NamespaceName.ClassName.MethodName]可以给调用的方法传入参数:
- 需要在命令行中写入打算传入的参数.
- 需要在方法内部调用 System.Environment.GetCommandLineArgs() 来获取从命令行传入的参数 (返回值类型是
string[]).
Unity 常用选项
WARNING
Unity 的命令行选项都只有一个短横杠.
# 默默地在后台运行, 不打开任何界面, 不需要人来干预.
# 在代码中可以使用 `Application.isBatchMode` 来判断.
-batchmode# 用于指定以哪个平台来加载工程.
# 和我们有关的选项包括: Standalone, Win64, iOS, Android.
-buildTarget [TargetName]# 用于指定 Unity 工程目录的位置.
# 如果 Unity 工程目录就是 Git 工程目录, 则不需要指定使用该命令行参数.
# 如果使用了 ET 框架, Git 工程目录不再与 Unity 工程目录相同, 此时则需要指定.
-projectPath [PathName]# 将 Unity 命令的执行过程中的日志记录在指定的文件中.
-logFile [PathName]WARNING
注意 CI/CD Job 执行完后, 如果没有报错, 就会自动还原 (因此会自动删除日志文件).
因此为了长期保存, 应该使用 Job artifact.
-EnableCacheServer # 启用 Cache Server.
-cacheServerEndpoint [ip-address:port] # 指定 IP 地址和端口号
-cacheServerEnableDownload [true or false] # 是否从 cache server 中下载
-cacheServerEnableUpload [true or false] # 是否允许向 cache server 上传数据以上选项都与 Cache Server 相关.
-runTests # 执行自动化测试
-testPlatform EditMode # 还可以是 PlayMode, Android, iOS 等
-testResults test-result.xml # 将测试结果保存在 xml 格式的文件中Unity Test Framework 官方文档专门有一页用于说明 如何使用命令行来做测试.
Gradle
Gradle 常用选项
gradle 的常用命令行选项:
gradle --parallel # 多线程编译
gradle --daemon # 使用 gradle 守护进程
gradle --quiet # 只在控制台输出错误信息
gradle --status # 查看正在运行的和不久前停止的 gradle 守护进程gradle wrapper
# 启用 gradle wrapper, 设置版本为 7.2, 初始化 gradle 工程
gradle wrapper --gradle-version=7.2 --distribution-type=bingradle wrapper 解决的问题是: 电脑中安装的 gradle 版本可能不是打包所需的 gradle 版本.
而当我们调用 gradle wrapper 命令后, 会下载指定版本的 gradle 到工程中, 并在工程根目录下生成 gradlew 可执行文件. 我们就通过 ./gradlew 来执行针对工程的 gradle 命令.
# 进入 gradle 工程根目录
cd [gradle-project]
# 查看所有可以执行的 gradle task
./gradlew tasks
# 执行工程中存在的任意 gradle task
./gradlew [task-name]
# 将因构建而生成的文件清除
./gradlew cleanINFO
Unity 生成的 Gradle 工程中就有很多 task, 其中用于构建的包括:
./gradlew assemble # 构建 apk, 包括 Debug 和 Release
./gradlew assembleRelease # 仅构建 Release 版本的 apk
./gradlew bundle # 构建 aab, 包括 Debug 和 Release
./gradlew bundleDebug # 仅构建 Debug 版本的 aabXCode
xcode-select
我们需要使用 XCode Command Lines Tool, 它是 xcode 开发相关的命令行工具集合.
系统默认的路径: /Library/Developer/CommandLineTools
XCode 自带的路径: /Applications/Xcode.app/Contents/Developer
我们可以通过 xcode-select 命令来检查当前所用的 CommandLineTools:
# 请确保以下命令的输出结果为 /Applications/Xcode.app/Contents/Developer
xcode-select -p
# 如果没有安装 `xcode-select`, 则可以通过以下命令安装
xcode-select --installxcodebuild
WARNING
xcodebuild 的命令行选项都只有一个短横杠.
构建所用到的命令主要是 xcodebuild.
# 测试 xcodebuild 命令是否可用
xcodebuild -version在构建前可以使用以下命令打印一些信息:
xcodebuild -list # 打印 Targets, Configuration, Schemes 等信息
xcodebuild -showBuildSettings # 打印所有构建设置
xcodebuild -showdestinations -scheme xxx # 指定 scheme 下所有 destination
xcodebuild -showsdks # 打印所有 xcode 自带的 sdk
xcodebuild -usage # 列出常用的构建命令尝试构建并上传:
参考这篇 stackoverflow 帖子.
cd [xcode 工程目录]
# 记得选择一个恰当的到处路径
export IOS_ARCHIVE_PATH=xxx/Unity-iPhone.xcarchive
# 提前准备好用于上传 AppStore Connect 的配置文件, 详见下文.
export EXPORT_OPTIONS_PATH=xxx/exportOptions.plist
# 删除更早构建的 archive
if [ -d $IOS_ARCHIVE_PATH ]; then rm -r $IOS_ARCHIVE_PATH; fi
# 构建
xcodebuild archive \
-archivePath $IOS_ARCHIVE_PATH \
-project Unity-iPhone.xcodeproj \
-scheme Unity-iPhone \
-configuration Release \
-arch arm64 \
-quiet
# 上传至 appstore connect
xcodebuild -exportArchive \
-archivePath $IOS_ARCHIVE_PATH \
-exportOptionsPlist $EXPORT_OPTIONS_PATH \
-quietexportOptions.plist
exportOptions.plist 文件示例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<true />
<key>destination</key>
<string>upload</string>
<key>manageAppVersionAndBuildNumber</key>
<true />
<key>method</key>
<string>app-store</string>
<key>signingStyle</key>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true />
<key>teamID</key>
<string>MR2X4AAG42</string>
<key>thinning</key>
<string><none></string>
<key>uploadBitcode</key>
<true />
<key>uploadSymbols</key>
<true />
</dict>
</plist>exportOptions.plist
compileBitcode: Bool
For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.
destination: String
Determines whether the app is exported locally or uploaded to Apple. Options are export or upload. The available options vary based on the selected distribution method. Defaults to export.
distributionBundleIdentifier: String
Reformat archive to focus on eligible target bundle identifier.
embedOnDemandResourcesAssetPacksInBundle: Bool
For non-App Store exports, if the app uses On Demand Resources and this is YES, asset packs are embedded in the app bundle so that the app can be tested without a server to host asset packs. Defaults to YES unless onDemandResourcesAssetPacksBaseURL is specified.
generateAppStoreInformation: Bool
For App Store exports, should Xcode generate App Store Information for uploading with iTMSTransporter? Defaults to NO.
iCloudContainerEnvironment: String
If the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. Available options vary depending on the type of provisioning profile used, but may include: Development and Production.
installerSigningCertificate: String
For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Developer ID Installer" and "Mac Installer Distribution". Defaults to an automatic certificate selector matching the current distribution method.
manageAppVersionAndBuildNumber: Bool
Should Xcode manage the app's build number when uploading to App Store Connect? Defaults to YES.
manifest: Dictionary
For non-App Store exports, users can download your app over the web by opening your distribution manifest file in a web browser. To generate a distribution manifest, the value of this key should be a dictionary with three sub-keys: appURL, displayImageURL, fullSizeImageURL. The additional sub-key assetPackManifestURL is required when using on-demand resources.
method: String
Describes how Xcode should export the archive. Available options: app-store, validation, ad-hoc, package, enterprise, development, developer-id, and mac-application. The list of options varies based on the type of archive. Defaults to development.
onDemandResourcesAssetPacksBaseURL: String
For non-App Store exports, if the app uses On Demand Resources and embedOnDemandResourcesAssetPacksInBundle isn't YES, this should be a base URL specifying where asset packs are going to be hosted. This configures the app to download asset packs from the specified URL.
provisioningProfiles: Dictionary
For manual signing only. Specify the provisioning profile to use for each executable in your app. Keys in this dictionary are the bundle identifiers of executables; values are the provisioning profile name or UUID to use.
signingCertificate: String
For manual signing only. Provide a certificate name, SHA-1 hash, or automatic selector to use for signing. Automatic selectors allow Xcode to pick the newest installed certificate of a particular type. The available automatic selectors are "Mac App Distribution", "iOS Developer", "iOS Distribution", "Developer ID Application", "Apple Distribution", "Mac Developer", and "Apple Development". Defaults to an automatic certificate selector matching the current distribution method.
signingStyle: String
The signing style to use when re-signing the app for distribution. Options are manual or automatic. Apps that were automatically signed when archived can be signed manually or automatically during distribution, and default to automatic. Apps that were manually signed when archived must be manually signed during distribtion, so the value of signingStyle is ignored.
stripSwiftSymbols: Bool
Should symbols be stripped from Swift libraries in your IPA? Defaults to YES.
teamID: String
The Developer Portal team to use for this export. Defaults to the team used to build the archive.
thinning: String
For non-App Store exports, should Xcode thin the package for one or more device variants? Available options: <none> (Xcode produces a non-thinned universal app), <thin-for-all-variants> (Xcode produces a universal app and all available thinned variants), or a model identifier for a specific device (e.g. "iPhone7,1"). Defaults to <none>.
uploadBitcode: Bool
For App Store exports, should the package include bitcode? Defaults to YES.
uploadSymbols: Bool
For App Store exports, should the package include symbols? Defaults to YES.Trivy
trivy 简介与安装
trivy 用于检测安全性问题, 例如漏洞, 危险配置, 硬编码的密码等.
正如 trivy 在其 GitHub 主页的介绍:
Find vulnerabilities, misconfigurations, secrets, SBOM
in containers, Kubernetes, code repositories, clouds and more.
通过常用的软件包管理器可以将 trivy 安装在本地:
scoop install trivybrew install trivytrivy 的常见用法
# 递归检查当前路径下的文件, 可以找到潜在的安全性问题.
# 例如硬编码的密码, 例如所依赖的 package 存在漏洞.
trivy fs .
# 如果想要检测所以来 package 的漏洞, 记得要先编译.
# 例如 rust 工程通过 Cargo.lock 文件来检测, 而此文件来自于上一次编译.
# 检测某个容器镜像的漏洞.
# **无需** 提前将镜像下载至本地.
trivy image [image-name]
# 检测某个配置文件有哪些风险, 是否遵守最佳实践.
trivy config [file-path]
# 例如可以检测 Dockerfile 的配置
trivy config ./Dockerfile有些时候希望 trivy 忽略部分文件或文件夹, 此时可以这么做:
# 使用 --skip-files 来忽略文件, 多个文件之间使用逗号隔开.
trivy image --skip-files "/Gemfile.lock,/app/Pipfile.lock" \
quay.io/fluentd_elasticsearch/fluentd:v2.9.0
# 使用 --skip-dir 来忽略文件夹, 多个文件夹之间使用逗号隔开.
trivy image --skip-dirs "/usr/lib/ruby/gems,/etc" fluent/fluentd:edge在 CI/CD 中使用
如果在 CI/CD 管线中使用 trivy, 则建议使用其官方容器镜像 aquasec/trivy.
例如在 GitLab CI/CD 管线中, 可以使用类似如下 Job 来检测镜像漏洞.
# .gitlab-ci.yml
container-scanning:
stage: test
image:
# 官方镜像.
name: aquasec/trivy
# 默认 entrypoint 就是 trivy,
# 这里覆盖掉, 使后续命令更易理解.
entrypoint: [""]
script:
- trivy image
--input app.tar # app.tar 来自于前面的 job 上传的 artifact.
-o trivy-image-result.log # 将结果输出到日志文件中.
--dependency-tree # 将依赖树也输出到结果中.
--severity HIGH,CRITICAL # 只关注 HIGH 和 CRITICAL 级别的漏洞.
--quiet # 减少 job 执行过程中的日志噪音.
--exit-code 1 # 如果发现漏洞则返回错误代码, 将此 job 的执行状态标记为失败.
artifacts:
# 如果执行失败, 才上传日志 (若成功, 则说明没有漏洞被发现).
when: on_failure
expire_in: "7 days"
paths:
- trivy-image-result.log.trivyignore
我们可以在 .trivyignore 文件中声明那些希望被忽略的漏洞:
# Accept the risk
CVE-2018-14618
# Accept the risk until 2023-01-01
CVE-2019-14697 exp:2023-01-01
# Ignore secrets
generic-unwanted-rule
aws-account-idErdtree
erdtree 的简介与安装
erdtree 用于 "列出路径结构" 并 "显示文件大小".
相比于同类工具, erdtree 的优势在于:
| 优势 | 说明 |
|---|---|
| 优秀的错误处理 | 出错时的提示非常有用, 例如会提示某个选项的备选值 |
| 能处理 gitignore 规则 | 默认不显示被 git 忽略的文件, 可通过 -i 或 --ignore 显示 |
| 能处理隐藏文件 | 默认不列出隐藏文件, 可通过 -. 或 --hidden 列出 |
| 便于阅读 | 默认会显示颜色, 不同类型的文件与不同单位的文件大小都有颜色区分 |
| 跨平台 | 主流操作系统都可以使用, 且可执行文件非常小 (只有 3.2 MB) |
通过以下命令安装:
scoop install erdtreebrew install erdtreeerdtree 的常见用法
直接使用 erd 命令, 默认的效果大致如下:

通常我们会添加一些选项, 使得输出的结果更容阅读:
# -L [NUM] 或 --level [NUM] 可以限制递归的层级数
# -H 或 --human 将会让文件大小更容易阅读 (恰当选择单位)
# -. 或 --hidden 将会列出隐藏文件 (那些以 . 开头的文件)
erd -L 2 -H -.有些时候我们希望借助 erd 命令将路径结构输出, 可以这么做:
# 将当前路径结构打印出来
erd --suppress-size -C none -y inverted
# --suppress-size 不输出文件大小
# -C none 让输出的文本不带颜色
# -y inverted 或 --layout inverted 将会反向排序# 效果大致如下
cicd-demo-chart
├─ Chart.yaml
├─ values.yaml
├─ helmfile.yaml
├─ templates
│ ├─ _helpers.tpl
│ ├─ service.yaml
│ ├─ secret.yaml
│ ├─ NOTES.txt
│ └─ deployment.yaml
└─ chartsGitLab Time Tracker
gtt 的简介与安装
GitLab 提供了针对 issue 和 merge reqest 的 时间追踪 功能.
而 gitlab-time-tracker (简称 gtt) 是用于简化 GitLab 时间追踪的工具.
安装前请确保可以使用 npm 命令.
若缺少 npm 命令, 则应该安装 node.js.
可以考虑在官网下载安装, 但更简易使用包管理器:
# 在 Windows 系统中借助 scoop 安装 node.js 的 LTS 版本.
scoop install nodejs-tls# 在 macOS 系统中借助 HomeBrew 安装 node.js 的 20 版本 (最新的 TLS 版本).
brew install node@20全局安装 gitlab-time-tracker:
# 通过 npm 全局安装
npm install -g gitlab-time-tracker
# 检查能否使用 gtt 命令
gtt --help# 通过 pnpm 全局安装
pnpm install -g gitlab-time-tracker
# 检查能否使用 gtt 命令
gtt --helpgtt 的配置
在开始配置前, 需要在 GitLab 中创建 Personal Access Token.
请访问 User Settings / Access Token 页面, 点击右上角的 Add new token 按钮.
如下图所示, 需要勾选 api 权限, 并建议删除默认的 Expiration date.
(若不设置 Expiration date, 则会自动采用最长的失效时间, 即一年).

创建完成后不要立即关闭页面, 请先复制 token, 后面的配置中要用到.

最后执行以下命令完成配置:
# 此命令会用默认的代码编辑器打开 gtt 配置文件.
# 默认的配置文件路径是: ~/.local/share/.gtt/config.yml
gtt config在配置文件中输入以下内容 (更多配置项, 详见 官方文档):
# ~/.local/share/.gtt/config.yml
# 若是私有部署的 GitLab, 请注意替换 url.
url: https://gitlab.com/api/v4/
# 将 MY_PERSONAL_ACCESS_TOKEN 替换成前面复制的 token.
token: MY_PERSONAL_ACCESS_TOKEN
# 将时区设置为北京时间 (UTC+08:00).
timezone: Asia/Shanghai
# 将时间以小时为单位显示, 保留两位小数.
timeFormat: "[%sign][%hours_overall:2] h"
# 设置日期的显示格式 (例如 2024-03-29 17:06:41).
dateFormat: YYYY-MM-DD HH:mm:ssgtt 的常用命令
# 开始记录.
gtt start [repo] [issue-id]
# 例如开始记录 mygroup/myrepo 仓库中编号为 666 的 issue.
gtt start mygroup/myrepo 666
gtt status # 查看当前是否存在正在记录的项.
gtt stop # 将正在记录时间的项停止.
gtt log # 查看已经存在与本地的时间记录日志文件.
gtt sync # 将本地的时间记录上传至 GitLab.
# 将一段时间内的统计数据抓取下来.
gtt report
# 例如将名为 mygroup 的 GitLab Group 中的数据抓下来,
# 通过 --closed 选项来包含已关闭的 issue,
# 指定时间范围, 从 2024-03-01 到 2024-03-31,
# 并以 markdown 格式输出, 创建名为 report.md 的文件.
gtt report mygroup --type=group --closed \
--from="2024-03-01" --to="2024-03-31" \
--output=markdown --file=report.md在实际使用中, 用的最多应该是 gtt start 和 gtt stop.
每隔一段时间, 再集中将时间记录通过 gtt sync 上传至 GitLab.
上传前可能会希望通过 gtt log 命令, 查看所有记录在本地的日志文件.
文件路径是 ~/.local/share/.gtt/frames/xxx.json, 其中 xxx 是日志的 id.
(gtt 采用了 RFC 3339 时间格式, 默认为 UTC+0, 建议通过 timezone 改为当地时间).

TIP
有些时候我们可能错误记录了一段时间, 此时:
如果希望 删除, 则可以通过 gtt delete [id] 来删除.
如果希望 修改, 则可以通过 gtt edit [id] 来修改.
gtt 常见问题
报错信息 "Could not resolve..." 可能有多种原因, 包括且不限于:
- 没有正确配置 gtt. 请检查 url 和 token 是否正确.
- 代码仓库或 issue 不存在. 请检查仓库名和 issue id 是否正确.
如果发现是因为代码仓库或 issue 输入错误, 则可以通过gtt edit命令修复.

报错信息 "Already running" 是因为:
已经正在计时的项还未被停止, 此时又尝试开始新的计时项.
(显然不应该同时开启多项计时, 这是正确的设计).

gtt 的缺陷
- personal access token 被明文存储, 有安全性问题.
- 没法使用
cr快捷键复制的 issue 和 mr 索引, 例如all/stuff#98. gtt sync之后, 缓存在本地文件应该删除 (或至少标记synced状态).- 无法批量删除日志文件, 这些文件会长期存放在 ~/.local/share/.gtt/frames 路径中.
gtt report子命令等待时间较长 (理论上并不需要下载那么多数据).- 在输入不存在的命令时, 什么都不会输出 (缺少提示和帮助信息).
gtt start时, 没有检测 repo 或 issue 是否存在 (缺少防呆设计).gtt log的排版不整齐 (持续时间小于和大于 1 小时的 log 没有对齐).- 无法在操作系统 UI 界面 (例如任务栏) 中得知当前是否在追踪.
- 长时间没有更新维护 (最近一次 commit 日期是 2020-06-10).