开发了一个管理本地开发环境的软件
前言
前阵子换了新电脑,我在整理本地开发环境时,看到一堆需要重新装的,顿时感觉好麻烦。想着都过去这么久了,应该有工具可以做到统一管理,实现快速安装、更新、切换版本吧。
经过一番查找后,找到了mise[1]这个东西,只需要简单的一句命令就能安装java、node、redis、go等工具,而且还支持对这些工具做统一管理(更新、删除),支持三大主流平台(macOS/Windows/Linux)
命令行始终不方便,于是我萌生了一个做GUI的想法,花了亿点时间用Flutter把它开发出来了,欢迎各位有需要的开发者阅读本文。
项目地址
-
GitHub地址:https://github.com/likaia/mise_gui -
下载地址:https://github.com/likaia/mise_gui/releases

主要解决什么问题?
对于我这种经常切换项目的人来说,纯命令行总感觉不是很直观。
比如我想知道:
-
当前电脑装了哪些工具? -
node、python、java、go这些工具当前用的是哪个版本? -
哪些项目里的 mise.toml覆盖了全局版本? -
我现在执行安装、切换、卸载,到底会影响哪些文件? -
上一次通过界面执行命令失败了,具体错误是什么?
这些事情,命令行当然都能查,但需要来回敲命令,有时候还要打开配置文件对比。Mise GUI想做的就是把这些常用信息集中到一个界面里,让本地环境管理更直观一点。
实现效果
目前主要做了4个功能:
-
环境总览 -
工具版本 -
项目覆盖 -
配置管理
环境总览
总览页主要用于快速查看当前机器的开发环境状态。
这里会展示当前系统、已安装工具数量、项目覆盖情况、mise版本以及最近通过界面执行过的操作。

工具版本
工具模块是本软件的核心功能之一。
它会展示每个工具的当前版本和最新版本,比如Flutter、Go、Java、Python等。

点进某个工具后,可以查看这个工具的已安装版本、远端可安装版本、当前版本来源,以及这个版本会影响哪些项目。
这里还做了一些操作入口,比如:
-
安装新版本 -
切换当前版本 -
升级到推荐版本 -
卸载工具 -
查看实际命令
这些操作不会直接执行,每次都会先进入命令预览。
安装新工具
安装工具时,只需要输入工具名和版本号。
如果工具支持远端版本查询,界面会把可选版本列出来,方便直接选择。

确认后不会立刻执行,而是先展示即将运行的命令,例如:
mise install redis@8.6.2
mise use --global redis@8.6.2
同时也会提示这次操作会影响哪些文件、影响范围是什么、可能有什么风险。
这个设计主要是为了避免“点一下按钮,背后偷偷执行了一堆命令”的情况。毕竟本地开发环境这种东西,改之前最好知道自己在改什么。
项目覆盖
mise支持项目级配置,比如在项目目录里放一个mise.toml,就可以指定这个项目使用的工具版本。
这个很好用,但是项目一多之后,就很容易忘记哪个项目覆盖了全局版本。
所以我做了一个项目覆盖页面。

你可以添加多个扫描目录,软件会递归查找里面的mise.toml,然后只展示和全局版本存在差异的项目。
比如全局node是20,但是某个项目指定了18,那么这里就能很直观地看出来。
比如:当你想排查“为什么这个项目跑出来的node版本和我想的不一样”,这个功能就派上用场了。
配置管理
配置页主要是用来查看和编辑全局配置以及项目配置。

目前支持:
-
查看全局配置文件: ~/.config/mise/config.toml -
选择某个项目查看项目级 mise.toml -
编辑配置文件 -
保存前查看diff差异 -
配置文件变化后自动刷新
此处我特意加了保存前的差异预览。因为配置文件不像普通表单,改错一个版本号或者删错一行,可能就会影响很多项目。
技术栈
这个项目是用Flutter写的,主要技术栈如下:
-
Flutter Desktop:用于构建跨平台桌面应用 -
Dart:主要开发语言 -
Riverpod:状态管理 -
GoRouter:页面路由 -
file_selector:选择扫描目录 -
Process.run:调用本机mise命令
整体代码结构大概是这样:
lib/
app/ # 应用启动、路由、主题和外壳
features/
dashboard/ # 环境总览
tools/ # 工具版本、安装、升级、卸载
projects/ # 扫描目录和项目覆盖
config/ # 全局与项目配置管理
repositories/ # 页面数据聚合
services/ # mise CLI、配置、历史、更新等底层服务
shared/ui/ # 通用面板、状态、对话框和预览组件
我没有把命令执行逻辑直接写在页面里,而是拆成了:
-
Page:负责界面展示和用户交互 -
Provider:负责页面状态 -
Repository:负责聚合页面需要的数据 -
Service:负责调用mise、读取配置、记录历史等底层逻辑
这样做的好处是后面要扩展功能时,不至于所有逻辑都堆在页面文件里。
和mise CLI的交互
这个软件本质上不是替代mise,而是给mise套了一层图形界面。
所以核心逻辑还是调用本机的mise CLI,例如:
mise --version
mise ls --json
mise current
mise outdated
mise ls-remote --json node
mise install node@20
mise use --global node@20
Flutter里通过Process.run来执行这些命令,然后把输出结果解析成界面需要的数据。
这里有个比较麻烦的点:桌面应用启动时拿到的环境变量,不一定和终端里的环境变量完全一致。
比如你在终端里能执行mise,但GUI应用直接执行可能找不到。
所以我在这里做了一些兜底:
-
优先读取常见路径,比如 /opt/homebrew/bin/mise、/usr/local/bin/mise -
尝试读取shell环境 -
如果仍然找不到,就进入安装引导页 -
给出当前系统对应的安装命令
为什么选择Flutter
这类工具其实用很多技术都能做,比如Electron、Tauri、Qt、SwiftUI等。
最后选择Flutter,主要有几个原因:
-
我对Flutter比较熟悉 -
桌面端支持macOS/Windows/Linux -
UI写起来比较直接 -
状态管理和组件拆分比较适合做这种工具型应用 -
最终打包出来是一个桌面应用,使用门槛比较低
用Flutter写的时候,也遇到了一些坑,比如:系统文件选择、macOS打包、公证、不同平台的命令执行差异,这些都需要额外处理。
整体写下来,这种小型桌面工具开发体验还是很不错的。
如何使用
目前可以直接去Release页面下载对应系统的版本:
https://github.com/likaia/mise_gui/releases
如果电脑里还没有安装mise,软件启动后会提示安装命令。
也可以先手动安装:
# macOS
brew install mise
# Windows
winget install jdx.mise
# Linux
curl https://mise.run | sh
如果你想本地运行源码:
git clone https://github.com/likaia/mise_gui.git
cd mise_gui
flutter pub get
flutter run -d macos
其他平台可以把运行目标换成:
flutter run -d linux
flutter run -d windows
写在最后
这个软件算是我给自己做的一个小工具,也是我第一个用Flutter作为开发语言写的开源项目。一开始只是因为换电脑时嫌重新配置环境太麻烦,后来越写越觉得这种东西挺适合做成可视化工具。
至此,文章就分享完毕了。
我是神奇的程序员,一位前端开发工程师。
如果你对我感兴趣,请移步我的个人网站[2],进一步了解。
-
文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊 -
本文首发于神奇的程序员[3]公众号,未经许可禁止转载💌
mise: https://mise.jdx.dev/
[2]个人网站: https://www.kaisir.cn/
[3]神奇的程序员: https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8b7566ab57814aad861b378882c1ee58~tplv-k3u1fbpfcp-watermark.image?
夜雨聆风