Make open command multi-platform
Describe the problem
It's often useful to open an URL from a script, for example if the other needs to install something.
It's not trivial though, you have to use open on Mac, xdg-open on Linux, something else on Windows
Describe your solution
https://github.com/jmfayard/my-kotlin-scipts/blob/main/scripts/goto.main.kts#L86-L93
Checklist
- [x] I've read the guide for contributing.
- [x] I've checked there are no other open pull requests for the feature.
- [x] I've checked there are no other open issues for the same feature.
I actually included the Mac open command initially, as I use it a lot. However, I wasn't sure how to handle commands that are different on different platforms.
Currently, Turtle was only really "designed" with Mac in mind, I haven't tested using it on Windows or Linux. I wasn't sure how likely it was someone would run a program that uses Turtle with the same commands on multiple platforms. I.e. whether Turtle's built-in commands needed to be cross-platform, vs having Turtle commands that actually match the underlying shell commands.
I do like the idea of being able to just run 'open(...)' and it run the appropriate commands. Therefore, I think adding this is a great idea!
We might need to consider having CI run tests on Linux and Windows as well, although no idea how to check those commands work!
The only way to test that a browser opens is to try it.
It's good to have open() available. You could have xdgOpen() as well.
But for something so common that opening an URL it would be good to have a dedicated multiplatform command
You could handle multiple platforms this way:
fun main() {
// default : all commands available
shellRun<All> {
git.clone("https://github.com/lordcodes/turtle")
}
// a few core abstractions that work everywhere
shellRun<Multiplatform> {
openUrl("http://example.com")
}
// access to Mac specific things
shellRun<Mac> {
brew("install", "wget")
}
// access to Linux specific things
shellRun<Linux> {
aptGet("install", "wget")
}
}
fun <Platform> shellRun(workingDirectory: File? = null, script: ShellScript.() -> String): String =
ShellScript(workingDirectory).script()
sealed interface Platform {
object All: Platform // all commands
object Multiplatform: Platform // abstractions that work everywhere
object Unix: Platform // Linux + Mac
object Linux: Platform // Linux only
object Mac: Platform // Mac only
object Windows: Platform // Windows only
}
Now that is a very interesting idea.
I think it's too complex though. Since there are subclasses of commands like GitCommands, FileCommands, ... we would have a matrix of (All, Multiplatform, Unix, Linux, Mac, Windows) x (GitCommands, FileCommands, ...)
so I would scale my request down to have simply
shellRun { multiplatform.openUrl("http://example.com") }
and whoever wants to add a new command can do this in MultiplatformCommands
Fair enough. May as well just add the command like any other then. Not sure the 'MultiplatformCommands' grouping adds much and breaks from the currently technique of grouping commands by functionality.
@jmfayard The open command for Mac is already available in the API via: files.openFile(...).