Marathon icon indicating copy to clipboard operation
Marathon copied to clipboard

Add export command

Open garricn opened this issue 7 years ago β€’ 33 comments

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. Running marathon export {myScript.swift} will copy myScript.swift into the following new folder structure:

MyScript/
    Sources/
        MyScript.swift
    Package.swift

garricn avatar May 21 '17 02:05 garricn

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?

JohnSundell avatar May 21 '17 22:05 JohnSundell

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...

garricn avatar May 21 '17 22:05 garricn

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.

kareman avatar May 21 '17 22:05 kareman

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.

pixyzehn avatar May 21 '17 23:05 pixyzehn

Hi @pixyzehn :) Why do you think it would be complicated if marathon had an export function?

garricn avatar May 22 '17 05:05 garricn

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:)

pixyzehn avatar May 22 '17 06:05 pixyzehn

@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 πŸ‘

JohnSundell avatar May 22 '17 17:05 JohnSundell

@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 πŸ˜„

JohnSundell avatar May 22 '17 17:05 JohnSundell

@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).

JohnSundell avatar May 22 '17 17:05 JohnSundell

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 avatar May 22 '17 19:05 JohnSundell

@JohnSundell I agreed to itπŸ‘ Let's go with that!

pixyzehn avatar May 22 '17 23:05 pixyzehn

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?

garricn avatar May 23 '17 01:05 garricn

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:

  • Simple one, you just create .swift file and use Marathon for everything.
  • Advanced, you have regular Swift script based on SPM and Marathon automatically uses what it needs, or copies it to Cache/ (maybe with some help from Marathonfile?).

cojoj avatar May 26 '17 11:05 cojoj

@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 avatar May 26 '17 12:05 JohnSundell

@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!

alexisakers avatar May 26 '17 13:05 alexisakers

@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?

garricn avatar May 27 '17 19:05 garricn

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 avatar May 28 '17 12:05 JohnSundell

@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 avatar May 28 '17 15:05 cojoj

@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 avatar May 28 '17 16:05 JohnSundell

@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?

garricn avatar May 28 '17 19:05 garricn

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.

cojoj avatar May 28 '17 20:05 cojoj

@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 avatar May 29 '17 16:05 JohnSundell

@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 avatar May 29 '17 19:05 garricn

@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 ❀️

cojoj avatar May 29 '17 19:05 cojoj

@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.

JohnSundell avatar May 29 '17 19:05 JohnSundell

Sweet! I'll start working on it and reach out when I need help :)

garricn avatar May 29 '17 20:05 garricn

I started working on it. Having fun :)

garricn avatar May 29 '17 23:05 garricn

Can the label be changed to in progress?

garricn avatar Jun 01 '17 01:06 garricn

~~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 :)

garricn avatar Jun 01 '17 04:06 garricn

@JohnSundell I updated the Issue description with the agreed upon output. Please confirm. Also, I have some questions:

Should output include:

  • gitignore?
  • README?
  • Marathonfile?
  • Makefile?
  • Xcode project?

Also:

  • What does the contents of Package.swift look like?
  • How can I get the list of Packages?
  • What does the contents of MyScriptTests.swift look like?

garricn avatar Jun 01 '17 04:06 garricn