twostraws / Ignite

A static site generator for Swift developers.
MIT License
985 stars 34 forks source link

Added local server functionality #17

Closed markbattistella closed 1 month ago

markbattistella commented 1 month ago

Adds in functionality to serve a local version of the Ignite website when run directly from Xcode. (Addresses issue #1)

What this change does

  1. Adds a new testingPort parameter to the Site protocol and extension.
  2. Adds a new function (serveLocalSite(on:) to the PublishingContext
  3. Adds that new function to the publish() method
  4. Creates a new Server struct to serve the website directly from Xcode

How it works

The Server struct has one public method - start() which firstly checks if the port intended for use - default 8000 - is available. If it isn't then an error is thrown.

If that port is available, then an AppleScript is called to launch a Terminal window with the cd /Build && python3 -m http.server 8000 call.

It then launches the webpage after a 2 second delay.

On subsequent Xcode runs, the AppleScript does not fire or open new Terminal windows.

Customisation

The use of the testingPort in the Site struct allows the user to specify a custom port for use in the event they or some other local service is using port 8000.

Considerations

This obviously relies on two external areas - Terminal and AppleScript. Neither should be viewed as high level risks, however there could be additional security alerts or notifications in future macOS releases, or even a deprecation of AppleScript.

Though I doubt users would be removing Terminal from their system entirely (or if even possible) this does mean that it will launch for the server opposed to other preferred apps. Not an issue, but something which may come up as a point of contention from die-hard terminal fans.

Future expansion

Without feature creep (into the Site struct) or over-engineering a flag to allow the user bypass or disallow webpage serving.

Something along the lines of --env=development vs --env=production.

This way if we were to implement a Github Action or another external script to generate websites, then we don't fall into the trap of it attempting to launch Terminal or a web browser.

Mcrich23 commented 1 month ago

I think this is great! and if @twostraws does not want to publish the cli I sent in #1, I am more than happy to publish it with homebrew.

Mcrich23 commented 1 month ago

One thing, I have a github action that builds and published my site, can you please clarify how I would tell it to only build the site and not serve it?

markbattistella commented 1 month ago

One thing, I have a github action that builds and published my site, can you please clarify how I would tell it to only build the site and not serve it?

Not yet a function in this PR. Trying to think of the easiest way without having user interaction.

I think the optimal way would be so that it doesn't require schemas or anything too complicated - particularly for the simple nature of this package.

The only way I can think of it now would be adding in another flag into Site of an enum for the website state:

enum SiteState {
  case development // build and run local server
  case production  // build only
}

Then in the start() function we can check the state and only open web browsing and terminal if in .development.

But then it opens the world of deploying, forgetting to change it, action issues, etc. Or even the vice-versa.

Ideally, your CLI version would be the robust method but takes away the ease from users who are learning Xcode Swift development, but then need to learn terminal.

I think this really does dial down to how @twostraws and team want to aim this type of package. Is it for beginners with everything inside the one package, or advanced where terminal and running the python server is a prerequisite.

Mcrich23 commented 1 month ago

maybe cli mode instead of production?

twostraws commented 1 month ago

There are two very different approaches here, and I like parts of both. @Mcrich23's approach is a command-line tool, which neatly separates creating new projects / running them from the process of building sites, and @markbattistella's approach puts about half the work in Swift, combining running with building.

I'm going to read through all your code now, and try to produce some kind of composite that brings together the best of both of them.

twostraws commented 1 month ago

Okay; I've pushed up a command-line tool. You should be able to install it by cloning this repository then running make, or perhaps sudo make depending on your directory permissions. If you then run ignite it should show you how to use the tool.

Hopefully this takes the best of both of your approaches – let me know if you're happy to close this PR. If you have further improvements etc, that should probably be fresh issues/PRs.

Mcrich23 commented 1 month ago

Can we please also get it on Homebrew?

twostraws commented 1 month ago

Homebrew is definitely possible, but one thing at a time please – does this command-line tool achieve what you both were looking for?

Mcrich23 commented 1 month ago

Yes! the one thing I would recommend is being able to change the template name on when running the command

twostraws commented 1 month ago

I've added a --template option now; hopefully that's what you're looking for! If so, I can close this issue, and formally document the CLI tool.

twostraws commented 1 month ago

I haven't heard back about this, so I'm going to close the issue now and document the CLI tool. Thank you for your help!