JohnSundell / Marathon

[DEPRECATED] Marathon makes it easy to write, run and manage your Swift scripts πŸƒ
MIT License
1.86k stars 78 forks source link

Add export command #71

Open garricn opened 7 years ago

garricn commented 7 years ago

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
JohnSundell commented 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?

garricn commented 7 years ago

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

kareman commented 7 years ago

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.

pixyzehn commented 7 years ago

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.

garricn commented 7 years ago

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

pixyzehn commented 7 years ago

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

JohnSundell commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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 πŸ˜‡

pixyzehn commented 7 years ago

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

garricn commented 7 years ago

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?

cojoj commented 7 years ago

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:

JohnSundell commented 7 years ago

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

alexisakers commented 7 years ago

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

garricn commented 7 years ago

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

JohnSundell commented 7 years ago

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.

cojoj commented 7 years ago

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

JohnSundell commented 7 years ago

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

garricn commented 7 years ago

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

cojoj commented 7 years ago

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.

JohnSundell commented 7 years ago

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

garricn commented 7 years ago

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

cojoj commented 7 years ago

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

JohnSundell commented 7 years ago

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

garricn commented 7 years ago

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

garricn commented 7 years ago

I started working on it. Having fun :)

garricn commented 7 years ago

Can the label be changed to in progress?

garricn commented 7 years ago

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 commented 7 years ago

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

Should output include:

Also:

JohnSundell commented 7 years ago

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

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

garricn commented 7 years ago

@JohnSundell Great! That's super helpful. I updated the issue description with the output structure. Let me know if its incorrect.

JohnSundell commented 7 years ago

@garricn It's correct πŸ‘