Open garricn opened 7 years ago
I think it would make a lot of sense for Marathon to include an export
command, that would set up a folder structure that is both Marathon & SPM compatible - just like TestDrive. It could also include a README
, .gitignore
and the little Package.swift
trick to ad-hoc generate a main.swift
file like I do here.
What do you guys think @garricn, @kareman, @pixyzehn, @darthpelo, @alexaubry?
I think that would be amazing. Sounds like it would be fun to implement too! So user would run marathon export myScript.swift
and output would be something like this at a given path:
MyScript
|-- .gitignore
βββ README.md
|ββ LICENSE
|ββ Marathonfile
βββ Package.pins
βββ Package.swift
βββ Sources
βΒ Β βββ main.swift (myScript.swift renamed)
βββ Tests
βΒ Β βββ LinuxMain.swift
βΒ Β βββ MyScriptTests
βββ MyScript.xcodeproj
βββ MyScriptTests_Info.plist
βββ project.pbxproj
Interesting question is now that I've exported it, how do I import it back into marathon for further development...
What if Marathon worked equally well with Package Manager projects as with individual swift files? So marathon run <folder>
would build and run it, and marathon install <folder>
would put an alias to .build/release/<name>
in /usr/local/bin. Leaving out <folder>
would just use the current directory.
I understand what you guys say, but in my opinion, I'm a bit afraid that it may be complicated if Marathon
has an import and export function. I prefer to be the outside of Marathon
. I think it's better to create a package by SwiftPM for now, and then you'll put your script on a relevant part. What you have to do in here is just copy scripts and add dependencies if you have.
Also, you can use PackageBuilder that I created recently to build a simple tool like a Marathon
. It may save your time. However, it's not compatible with Marathon
. I'm thinking about implementing this feature.
Hi @pixyzehn :) Why do you think it would be complicated if marathon
had an export
function?
Hi @garricn, I thought marathon
is the management tool for scripts in Swift, so if marathon
creates SwiftPM, I feel like not a responsibility of marathon
at my first impression. But in terms of an automation tool, looks good. I'd like to hear thoughts from others:)
@garricn Exactly, but I would instead git ignore main.swift
and ad-hoc generate it like I did for TestDrive. Makes the Marathon commands intact π
@kareman That's a really interesting idea, kind of plays into the idea of https://github.com/JohnSundell/Marathon/issues/43, that Marathon would be smart enough to figure out which Swift script to run. I don't think it solves this usecase though, but it's a very interesting idea nontheless π
@pixyzehn @garricn Marathon is a tool for Swift scripting, but eventually you might want to share those scripts with the world, and making it easy to do so is definetly a primary goal of this project. And until Marathon has achieved world dominance as a scripting tool (he he), other tools will need to be supported (in this case using SPM directly). So having an export
command that outputs a folder structure that's ready to put on GitHub I think is super valuable (I would use it a lot myself).
Although to @pixyzehn's point, we should keep it as simple as possible, as to not complicate Marathon or turn it into a full-blown project generator like SwiftPlate or PackageBuilder π
@JohnSundell I agreed to itπ Let's go with that!
I totally understand your point, @pixyzehn to keep it simple. There is a section in the README that talks about sharing scripts with team members. Maybe this sharing method is good enough and I'm just unable to understand how it works. If I used marathon to create a script, how can I share it as is? What are your workflows like guys for sharing your marathon scripts and turning them into actively developed projects?
Just my 2 cents... I'd really love to see export
functionality.
I'd really love to start simple with Swift scripting, and for this the current implementation of Marathon is perfect, because creating mySweetScript.swift
and running it via Marathon is super simple and cuts the whole overhead described in one of John's blog posts. The problem is when it comes to sharing, cause right now if I start with marathon create niceScript
I end up with just one Swift file, which I have to manually move to some directory, and eventually add a Marathonfile and that's fine if I'm not planning to share it on GitHub, but if I do... I'm forcing my future users to use Marathon as well. Which is funny, cause Marathon already generates everything for you in ~/.marathon/Scripts/Cache/
. I don't know about implementation details (yet), but I'd love to see either moving Cache to the directory with original Swift file, or having export
, but in that case development would happen somewhere and then we get generated project etc.
Just one idea popped in my mind... What if we can have duality? Marathon would support two scenarios:
.swift
file and use Marathon for everything.Cache/
(maybe with some help from Marathonfile?).@garricn I think the best example of how I share Marathon scripts is TestDrive. It supports both installing/running through Marathon, Make & SPM.
The easiest way to share a Marathon script (given that the recipient is also able to run it using Marathon) is to use inline dependency annotations. That way you can just share the script file (as a gist or on a GitHub project) and have it work out-of-the-box.
I agree with @cojoj that we shouldn't force users of our scripts to use Marathon though. Since Marathon scripts are inherently fully SPM compatible there's no reason for it. What I'm looking for with marathon export
is to simply take the script file, and generate the folder structure and Package.swift
file required to run the script using only SPM. It could also generate a Makefile
, since it's easy to do. But I think that's it - we shouldn't be too clever in export
and try to generate a whole repo - that's not the point π
We can't just grab the cache folder, since Marathon does some cleverness with symlinking in order to not have to re-clone dependencies for each script, so that script execution is fast. But all we have to do is figure out what dependencies a script has (by looking at either the Marathonfile or inline specified dependencies, just like we do for run
, edit
and install
), and create a Package.swift
file based on that.
What do you guys think? π
@JohnSundell That sounds like a great solution π I think it's important to let the user choose the most appropriate tool for its needs. Plus that would not complicate Marathon too much. +1!
@JohnSundell Sounds great to me! How will it work when we want to use marathon
to continue development of a project that was exported with marathon export
? Do we just marathon run
and then marathon export
again?
The way I'm thinking that this will work is say you have a script called MyScript.swift
. You export it using marathon export MyScript.swift
. This will generate a new folder called MyScript
in the current folder, with the following contents:
Sources/
MyScript.swift
Tests/
MyScriptTests.swift
Package.swift
You now have the choice to continue developing the script using the original MyScript.swift
file, or simply delete it and run marathon edit MyScript/Sources/MyScript.swift
whenever you want to make a change.
@JohnSundell it's a great idea, but one thing I'd love to see - having both of them in sync. The current state of Marathon is when you run marathon edit script.swift
it waits until you save in Xcode to reflect changes in script.swift
file (I always forget as I keep Xcode open all the time). Would be nice to have sync mechanism.
@cojoj Actually, it doesn't π It runs a timer that periodically saves the file back to the original source - since Xcode doesn't seem to report file change events consistently (at least I couldn't get it to work when I tried to). You can check the code here: https://github.com/JohnSundell/Marathon/blob/master/Sources/MarathonCore/Script.swift#L193.
The one problem with the current sync mechanism is if you stop Marathon running and keep editing the script, the changes won't be sycned anymore (haven't heard anyone running into that yet though).
But I'd love a better syncing solution, think it's out of scope for export
though π
@JohnSundell Sounds great! So marathon export
will create a copy of MyScript.swift
and place it in the exported file structure and it will leave a copy of the original MyScript.swift
in its original parent directory, correct?
Shall I change the name of this issue?
Orrrrrr, how about having marathon create --spm
Which will make just a copy of Chached
project, so that user can decide on creation whether he wants a full SPM project or a simple file fully managed by Marathon. But this would be something additional to export
I guess, cause it's more about development process and not only exporting.
@JohnSundell I guess you'd need some sort of cron
job running and doing dual-syncing, so no matter what you edit you'll have everything in sync. I guess that'd create some nice feeling for the end user.
@garricn Yeah, exactly π Sure, please do - I'll add the ready for implementation
label to indicate that we are ready to start working on this π
@cojoj The question is, if you're gonna use SPM directly, why even use Marathon at all? For larger projects this is totally a great option - when things stop being simple scripts and more complex command line tools I think it's better to use SPM directly. And then you can use tools like @pixyzehn's awesome Package Builder.
About the syncing, let's discuss that in a separate issue. Let's try to stay focused here on making Marathon support a great way of preparing scripts for sharing using export
π
Anyone wants to do the implementation of export
? π
@JohnSundell I would love to implement this improvement. I will certainly need your help though. You think I can do it? How long should it take?
@garricn it doesn't matter how long it'll take. We're all here to help π.
You're right @JohnSundell, I was wandering somewhere else and forgot to keep it simple. Thanks for the Package Builder hint β€οΈ
@garricn Of course you can do it! π And like @cojoj says, we're here to help! π I think it should be fairly straight forward, just using Files
to create the folders and move the files into place.
As for the code structure, you can look at how the other tasks are organized, they basically are contained in a file with the task's name (so in this case Export.swift
), and get resolved in Command.swift
.
Sweet! I'll start working on it and reach out when I need help :)
I started working on it. Having fun :)
Can the label be changed to in progress?
I am working on this right now. I have a question. Where is marathon creating a swift file if it doesn't exist? Running marathon export
creates a swift file. What should be the behavior? It seems to me that maybe marathon should throw an error: No script found. Or do we want export to create a swift file if it doesn't exist? You can view my WIP branch here: https://github.com/garricn/Marathon/tree/feature/add-export-command-I71
nevermind, I figured it out :)
@JohnSundell I updated the Issue description with the agreed upon output. Please confirm. Also, I have some questions:
Should output include:
Also:
@garricn About the output, let's keep it very simple for now. @clayellis is working on adding testing support for scripts in #77, so no need to add a MyScriptTests.swift
file for now (we'll extend export
later to support the testing functionality) π For now, this output is expected:
Package.swift
that defines the name of the package that was exported, as well as its required dependencies. You'll probably need to add an API to get all the dependencies from a given script on ScriptManager
(probably some code from resolveInlineDependencies()
can be extracted, to figure out all the imports
).
Sources/{ScriptName}.swift
, which'll contain the script. It would be cool if the script could have inline dependency annotations added, so that we don't need to include a Marathonfile
.
And that should be it π We don't need to include any other files in export
for now (like gitignore, etc.) a Makefile
could be added, but let's take that after getting the basic functionality in π
@JohnSundell Great! That's super helpful. I updated the issue description with the output structure. Let me know if its incorrect.
@garricn It's correct π
I used marathon today to build a cool little tool. It was super fun and marathon made it really easy. When it came time to release my tool to the world, I wasn't really sure how to do that. I ended up using the SPM and the SPM install instructions on marathon's readme for install readme. It worked! After I SPN init'ed and some other things. Am I missing something? Is it easier to deploy a marathon script than what I did? Anyhoo, I'd love to help make the instructions more clear or chat about the topic. Thanks again. I love marathon. Great work John and team!
UPDATE
After significant discussion (see below) we've decided to implement this issue as an
export
function. Runningmarathon export {myScript.swift}
will copymyScript.swift
into the following new folder structure: