Skip to content

Commit 3f4ce57

Browse files
committed
feat(安装器): 添加macOS应用安装检测和命令生成功能
添加对macOS上brew cask应用的安装检测功能,并改进跨平台应用安装检测逻辑 重构安装命令生成逻辑到独立函数,支持自定义命令和多种包管理器 在apps-config.json中添加dockdoor和docker的安装配置
1 parent 60a8104 commit 3f4ce57

3 files changed

Lines changed: 201 additions & 18 deletions

File tree

profile/installer/apps-config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@
257257
"cliName": "go",
258258
"description": "golang",
259259
"command": "brew install go"
260+
},
261+
{
262+
"name": "dockdoor",
263+
"cliName": "dockdoor",
264+
"description": "macOS 的窗口预览和 Alt-Tab",
265+
"command": "brew install --cask dockdoor"
266+
},
267+
{
268+
"name": "docker",
269+
"cliName": "docker",
270+
"description": "macOS的docker可视化工具",
271+
"command": "brew install --cask docker"
260272
}
261273
]
262274
}

psutils/modules/install.psm1

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,10 @@ function Install-PackageManagerApps() {
161161
$cliName = if ($appInfo.cliName) { $appInfo.cliName } else { $appInfo.name }
162162

163163
# 生成安装命令(如果未配置则根据包管理器自动生成)
164-
$command = if ($appInfo.command) {
165-
$appInfo.command
166-
}
167-
else {
168-
switch ($PackageManager.ToLower()) {
169-
'choco' { "choco install $appName -y" }
170-
'scoop' { "scoop install $appName" }
171-
'winget' { "winget install $appName" }
172-
'cargo' { "cargo install $appName" }
173-
'homebrew' { "brew install $appName" }
174-
'apt' { "apt install $appName" }
175-
default {
176-
Write-Warning "未知的包管理器: $PackageManager,跳过 $appName"
177-
continue
178-
}
179-
}
164+
$command = Get-PackageInstallCommand -PackageManager $PackageManager -AppName $appName -CustomCommand $appInfo.command
165+
if (-not $command) {
166+
Write-Warning "未知的包管理器: $PackageManager,跳过 $appName"
167+
continue
180168
}
181169

182170
# 检查是否跳过安装
@@ -187,8 +175,16 @@ function Install-PackageManagerApps() {
187175

188176
# 执行安装逻辑
189177
try {
190-
# 检查应用是否已安装
191-
if (-not (Test-EXEProgram $cliName)) {
178+
# 检查应用是否已安装(使用更智能的检测方法)
179+
$isInstalled = if ($appInfo.filterCli) {
180+
# 如果配置中指定仅检测CLI,则只检测命令行程序
181+
Test-ApplicationInstalled -AppName $cliName -FilterCli $true
182+
} else {
183+
# 默认检测所有类型(命令行和应用程序)
184+
Test-ApplicationInstalled -AppName $cliName
185+
}
186+
187+
if (-not $isInstalled) {
192188
if ($PSCmdlet.ShouldProcess($appName, "安装应用")) {
193189
Write-Host "正在安装 $appName..." -ForegroundColor Yellow
194190
Invoke-Expression $command
@@ -205,4 +201,58 @@ function Install-PackageManagerApps() {
205201
}
206202
}
207203

204+
function Get-PackageInstallCommand {
205+
<#
206+
.SYNOPSIS
207+
根据包管理器和应用名称生成安装命令
208+
.DESCRIPTION
209+
根据指定的包管理器类型和应用名称,生成对应的安装命令。
210+
如果提供了自定义命令,则优先使用自定义命令。
211+
.PARAMETER PackageManager
212+
包管理器名称,支持:choco、scoop、winget、cargo、homebrew、apt
213+
.PARAMETER AppName
214+
要安装的应用名称
215+
.PARAMETER CustomCommand
216+
自定义安装命令(可选)
217+
.EXAMPLE
218+
Get-PackageInstallCommand -PackageManager "scoop" -AppName "git"
219+
返回: "scoop install git"
220+
.EXAMPLE
221+
Get-PackageInstallCommand -PackageManager "choco" -AppName "nodejs" -CustomCommand "choco install nodejs.install -y"
222+
返回: "choco install nodejs.install -y"
223+
.OUTPUTS
224+
[string] 安装命令字符串,如果包管理器不支持则返回 $null
225+
#>
226+
[CmdletBinding()]
227+
param(
228+
[Parameter(Mandatory = $true)]
229+
[string]$PackageManager,
230+
231+
[Parameter(Mandatory = $true)]
232+
[string]$AppName,
233+
234+
[Parameter()]
235+
[string]$CustomCommand
236+
)
237+
238+
# 如果提供了自定义命令,优先使用
239+
if ($CustomCommand) {
240+
return $CustomCommand
241+
}
242+
243+
# 根据包管理器生成默认安装命令
244+
switch ($PackageManager.ToLower()) {
245+
'choco' { return "choco install $AppName -y" }
246+
'scoop' { return "scoop install $AppName" }
247+
'winget' { return "winget install $AppName" }
248+
'cargo' { return "cargo install $AppName" }
249+
'homebrew' { return "brew install $AppName" }
250+
'apt' { return "apt install $AppName" }
251+
default {
252+
Write-Verbose "不支持的包管理器: $PackageManager"
253+
return $null
254+
}
255+
}
256+
}
257+
208258
Export-ModuleMember -Function *

psutils/modules/test.psm1

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,125 @@ function Test-PathHasExe {
117117

118118

119119
}
120+
function Test-MacOSCaskApp {
121+
<#
122+
.SYNOPSIS
123+
检测macOS上通过brew cask安装的应用程序是否已安装
124+
.DESCRIPTION
125+
通过检查/Applications目录或使用brew list --cask命令来判断macOS应用程序是否已安装
126+
.PARAMETER AppName
127+
要检测的应用程序名称
128+
.PARAMETER UseBrew
129+
是否使用brew命令检测,默认为$true。如果为$false则检查/Applications目录
130+
.EXAMPLE
131+
Test-MacOSCaskApp -AppName "DockDoor"
132+
检测DockDoor应用是否已安装
133+
.EXAMPLE
134+
Test-MacOSCaskApp -AppName "Visual Studio Code" -UseBrew $false
135+
通过检查Applications目录来检测VS Code是否已安装
136+
.OUTPUTS
137+
[bool] 如果应用已安装返回$true,否则返回$false
138+
#>
139+
[CmdletBinding()]
140+
param(
141+
[Parameter(Mandatory = $true)]
142+
[string]$AppName,
143+
144+
[Parameter()]
145+
[bool]$UseBrew = $true
146+
)
147+
148+
try {
149+
if ($UseBrew) {
150+
# 使用brew命令检测
151+
if (Test-EXEProgram -Name "brew") {
152+
$brewList = brew list --cask 2>$null
153+
if ($LASTEXITCODE -eq 0) {
154+
return $brewList -contains $AppName
155+
}
156+
}
157+
# 如果brew命令失败,回退到目录检查
158+
}
159+
160+
# 检查/Applications目录
161+
$appPath = "/Applications/$AppName.app"
162+
return (Test-Path $appPath)
163+
}
164+
catch {
165+
Write-Warning "检测macOS应用 '$AppName' 时发生错误: $_"
166+
return $false
167+
}
168+
}
169+
170+
function Test-ApplicationInstalled {
171+
<#
172+
.SYNOPSIS
173+
跨平台应用程序安装检测
174+
.DESCRIPTION
175+
整合了跨平台应用安装检测逻辑,支持Windows、macOS和Linux系统。
176+
在macOS上会同时检测命令行程序和cask应用,在其他系统上使用命令行程序检测。
177+
.PARAMETER AppName
178+
要检测的应用程序名称
179+
.PARAMETER FilterCli
180+
是否仅检测命令行程序,默认为$false(检测所有类型)
181+
.EXAMPLE
182+
Test-ApplicationInstalled -AppName "git"
183+
检测git是否已安装(包括命令行和应用程序)
184+
.EXAMPLE
185+
Test-ApplicationInstalled -AppName "git" -FilterCli $true
186+
仅检测git命令行工具是否已安装
187+
.EXAMPLE
188+
Test-ApplicationInstalled -AppName "dockdoor"
189+
在macOS上检测DockDoor(会同时检测命令行和cask应用)
190+
.OUTPUTS
191+
[bool] 如果应用已安装返回$true,否则返回$false
192+
#>
193+
[CmdletBinding()]
194+
param(
195+
[Parameter(Mandatory = $true)]
196+
[string]$AppName,
197+
198+
[Parameter()]
199+
[bool]$FilterCli = $false
200+
)
201+
202+
try {
203+
# 获取当前操作系统
204+
$os = Get-OperatingSystem
205+
206+
Write-Verbose "当前操作系统: $os"
207+
Write-Verbose "检测应用: $AppName (FilterCli: $FilterCli)"
208+
209+
switch ($os) {
210+
"macOS" {
211+
if ($FilterCli) {
212+
# 仅检测命令行程序
213+
return Test-EXEProgram -Name $AppName
214+
}
215+
else {
216+
# 检测所有类型:先检测命令行程序,再检测cask应用
217+
$cliInstalled = Test-EXEProgram -Name $AppName
218+
if ($cliInstalled) {
219+
return $true
220+
}
221+
# 如果命令行程序未安装,检测cask应用
222+
return Test-MacOSCaskApp -AppName $AppName -UseBrew $true
223+
}
224+
}
225+
{ $_ -in @("Windows", "Linux") } {
226+
# Windows和Linux使用命令行程序检测
227+
return Test-EXEProgram -Name $AppName
228+
}
229+
default {
230+
Write-Warning "未知操作系统: $os,使用默认命令行程序检测"
231+
return Test-EXEProgram -Name $AppName
232+
}
233+
}
234+
}
235+
catch {
236+
Write-Error "检测应用程序 '$AppName' 时发生错误: $($_.Exception.Message)"
237+
return $false
238+
}
239+
}
240+
120241
Export-ModuleMember -Function *

0 commit comments

Comments
 (0)