Skip to content

Commit

Permalink
Bottle Terminal button (#843)
Browse files Browse the repository at this point in the history
* Bottle Terminal button

* Use WhiskyCmd to fetch bottle shellenv

* Fix opening exe files with one bottle

---------

Co-authored-by: nastys <nastys@users.noreply.github.com>
  • Loading branch information
nastys and nastys committed Apr 9, 2024
1 parent 3f1b491 commit 6a781a5
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
39 changes: 39 additions & 0 deletions Whisky/Extensions/Bottle+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,40 @@
import Foundation
import AppKit
import WhiskyKit
import os.log

extension Bottle {
func openCDrive() {
NSWorkspace.shared.open(url.appending(path: "drive_c"))
}

func openTerminal() {
let whiskyCmdURL = Bundle.main.url(forResource: "WhiskyCmd", withExtension: nil)
if let whiskyCmdURL = whiskyCmdURL {
let whiskyCmd = whiskyCmdURL.path(percentEncoded: false)
let cmd = "eval \\\"$(\\\"\(whiskyCmd)\\\" shellenv \\\"\(settings.name)\\\")\\\""

let script = """
tell application "Terminal"
activate
do script "\(cmd)"
end tell
"""

Task.detached(priority: .userInitiated) {
var error: NSDictionary?
guard let appleScript = NSAppleScript(source: script) else { return }
appleScript.executeAndReturnError(&error)

if let error = error {
Logger.wineKit.error("Failed to run terminal script \(error)")
guard let description = error["NSAppleScriptErrorMessage"] as? String else { return }
await self.showRunError(message: String(describing: description))
}
}
}
}

@discardableResult
func getStartMenuPrograms() -> [Program] {
let globalStartMenu = url
Expand Down Expand Up @@ -174,4 +202,15 @@ extension Bottle {
func rename(newName: String) {
settings.name = newName
}

@MainActor private func showRunError(message: String) {
let alert = NSAlert()
alert.messageText = String(localized: "alert.message")
alert.informativeText = String(localized: "alert.info")
+ " \(self.url.lastPathComponent): "
+ message
alert.alertStyle = .critical
alert.addButton(withTitle: String(localized: "button.ok"))
alert.runModal()
}
}
13 changes: 12 additions & 1 deletion Whisky/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -2327,6 +2327,17 @@
}
}
},
"button.terminal" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Terminal"
}
}
}
},
"button.unpin" : {
"localizations" : {
"da" : {
Expand Down Expand Up @@ -16655,4 +16666,4 @@
}
},
"version" : "1.0"
}
}
3 changes: 3 additions & 0 deletions Whisky/Views/Bottle/BottleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ struct BottleView: View {
Button("button.cDrive") {
bottle.openCDrive()
}
Button("button.terminal") {
bottle.openTerminal()
}
Button("button.winetricks") {
showWinetricksSheet.toggle()
}
Expand Down
22 changes: 21 additions & 1 deletion WhiskyCmd/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ struct Whisky: ParsableCommand {
// Export.self,
Delete.self,
Remove.self,
Run.self
Run.self,
Shellenv.self
/*Install.self,
Uninstall.self*/])
}
Expand Down Expand Up @@ -178,6 +179,25 @@ extension Whisky {
}
}

struct Shellenv: ParsableCommand {
static var configuration = CommandConfiguration(abstract: "Prints export statements for a Bottle for eval.")

@Argument var bottleName: String

mutating func run() throws {
var bottlesList = BottleData()
let bottles = bottlesList.loadBottles()

guard let bottle = bottles.first(where: { $0.settings.name == bottleName }) else {
throw ValidationError("A bottle with that name doesn't exist.")
}

let envCmd = Wine.generateTerminalEnvironmentCommand(bottle: bottle)
print(envCmd)

}
}

struct Install: ParsableCommand {
static var configuration = CommandConfiguration(abstract: "Install Whisky dependencies.")

Expand Down
26 changes: 25 additions & 1 deletion WhiskyKit/Sources/WhiskyKit/Wine/Wine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,36 @@ public class Wine {
var wineCmd = "\(wineBinary.esc) start /unix \(url.esc) \(args)"
let env = constructWineEnvironment(for: bottle, environment: environment)
for environment in env {
wineCmd = "\(environment.key)=\(environment.value) " + wineCmd
wineCmd = "\(environment.key)=\"\(environment.value)\" " + wineCmd
}

return wineCmd
}

public static func generateTerminalEnvironmentCommand(bottle: Bottle) -> String {
var cmd = """
export PATH=\"\(GPTKInstaller.binFolder.path):$PATH\"
export WINE=\"wine64\"
alias wine=\"wine64\"
alias winecfg=\"wine64 winecfg\"
alias msiexec=\"wine64 msiexec\"
alias regedit=\"wine64 regedit\"
alias regsvr32=\"wine64 regsvr32\"
alias wineboot=\"wine64 wineboot\"
alias wineconsole=\"wine64 wineconsole\"
alias winedbg=\"wine64 winedbg\"
alias winefile=\"wine64 winefile\"
alias winepath=\"wine64 winepath\"
"""

let env = constructWineEnvironment(for: bottle, environment: constructWineEnvironment(for: bottle))
for environment in env {
cmd += "\nexport \(environment.key)=\"\(environment.value)\""
}

return cmd
}

/// Run a `wineserver` command with the given arguments and return the output result
private static func runWineserver(_ args: [String], bottle: Bottle) async throws -> String {
var result: [ProcessOutput] = []
Expand Down

0 comments on commit 6a781a5

Please sign in to comment.