-
-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Programmatically generate ellie links for showcase examples #56
Comments
Ooh this looks really interesting. I'd like to take a shot at this! I was just wondering how you would like to approach this. Would this be python file (or whatever executable) we'd run to generate an ellie link given the file, and print out the link? Or maybe it doesn't matter as long as the link generation is slightly automated haha. On a side note, do you want to add a hacktoberfest topic to this repo? It might attract some more contributors and people who can help :)). Also my PRs don't count toward Hacktoberfest right now because this repo isn't opted in 😅. |
Go for it!
We would generate the url in elm once the source code is loaded from the file-server. So clicking the Does that make sense?
Done! |
Oh I think I get it! What I understand is that the Ellie link will be created in Elm by the file contents, once it's received by the
Thank you so much! |
I'll be busy over the weekend but I just wanted to give you an update on what I did recently (Sorry for the long comment!) TL;DR: URL encoding is finished (with gist and github repo) but there are some caveats that prevent us from using it right away. Good newsURL encoding is surprisingly easy, since all you have to do is replace some reserved characters with their percent encodings. I made this gist that showcases that functionality. It hardcodes the Ellie title, HTML and the packages that the Ellie link will generate, but those aren't too difficult to change. For example, a simple Hello World example: module Main exposing (main)
import Html exposing (Html)
main : Html msg
main =
Html.text "Hello World!" Will be converted to this Ellie link. If you want to test it out yourself in the command line, I made a small headless Elm program that prints out the URL when the file is taken as a CLI argument. The repo is here. CaveatsThis seems close to actual functionality, but it unfortunately doesn't work on the antd code examples, without some major refactoring. The program assumes the code is already compatible with Ellie straight off the bat, so file names that aren't called I looked into the examples and it seems like there are three main types of "files": 1. Stateless and Message-less (most common) module Routes.ButtonComponent.TypeExample exposing (example) Files like these are pretty easy to make compatible because we just have to rename the file to main : Html msg
main = example 2. Stateless with Messages module Routes.ButtonComponent.IconExample exposing (Msg, example) This will be harder to make compatible because, along with changing the name and exports, we'd have to add some extra code to make this able to export a 3. Stateful with Messages module Routes.AlertComponent.CloseableExample exposing
( Model
, Msg
, init
, update
, view
) This is similar to the above problem, but we have lot more things already defined for our I believe these problems are all solvable with Apologies for the really long winded comment! This problem's really interesting to look into. I'll be busy with homework for this weekend so I won't be able to do much, but I hope this comment helps you out with this issue. |
Amazing! Don't apologize for the long comment. This is great research & detail! Regarding the list of packages, I thought that it was optional to specify package versions with this hidden ellie API? We need to use the latest version of So ideally there's an option to say One drawback with this approach is that ellie link generation won't work for local development if the example is using an unpublished API. But quite frankly I don't see why that matters. Regarding the size & scope of this change: I would recommend first implementing a naive approach / v1 implementation that only generates links for the "Stateless and Message-less" examples. That way the size of the refactor is reduced by a considerable amount, and no one is biting off more than they can chew :) Once that's merged, then we can iterate on this design and generalize it for the more complex examples.
I would say, do what you think makes sense in the context of a v1 implementation. We can then do some manual QA'ing to make sure things are still good. |
You're right, I feel like we should be able to specify the latest package version automatically, but unfortunately I couldn't find a way to do that with the URLs :((. I looked at the source code for the Ellie URL parsers a bit more, specifically at Version.elm and Package.elm, and it seems that they only accept hardcoded numbers. Not specifying a package version at all would make the Package parsing fail completely. Hardcoding the latest elm-antd version is going to be kind of annoying, but it seems to be the best we can do unless one of the Ellie devs has something to say about it.
A naive v1 implementation is definitely possible! I will be a little slow to make it due to a couple of midterms that are coming up, but I'll submit a PR with basic functionality sometime within a week and we can slowly work on making it more powerful. |
Hmm, ok I think another thing that could be done is to dynamically get the version of It might be possible to do this in elm using the metadata-utils package (but I am not very familiar with the package, so I can't make any promises). Alternatively, the version could be hardcoded* at build time by fetching the version of *hardcoded is a bit of misnomer (but webpack basically does hardcode environment variables for anything that has the |
I took a quick look at the options and it seems like Github's API is the easiest to use. I'm not too familiar with JS environment variables, though, especially with Webpack. Maybe you can make some changes once I have a PR ready 😅 . Right now, I can just do an HTTP request (either in JS or on the |
No worries! It's quite straight forward. Let me see if I can explain in a simple manner: JS that runs in browsers technically does not have environment variables. The However, in NodeJS, So what webpack does (remember, webpack runs in a NodeJS context), with the help of the awkwardly named " So for example, when I write See here for the actual line of code where the above happens. Does that make sense? With regard to HTTP requests, they should be done at build time, meaning in a Circle CI script. So your PR would do an HTTP request inside of the Side note: I can install the github cli in the Docker file so that the github cli is usable within CI/CD runs in Circle. So imagine there was something like this: # inside of config.yml
# create an env variable based on an api call to list git tags from most recent to oldest, and then pipe it to 'head' to attain only the most recent git tag
export CURRENT_ANTD_VERSION=$(github-cli list-tags supermacro/elm-antd | head -n 1) Note that the above is a hypothetical usage of the github cli as I actually am not familiar with the cli's API. ... Then in JS, you would call |
Wow, thanks for such a good explanation of the environment variables! I definitely understand env variables a lot more, and your string replace webpack plugin is really cool. My experience with webpack (and I guess environment variables as well) only went as far as using create-elm app and firebase, so I'm glad I'm getting to learn so much from this project.
Oh wow I really misinterpreted your earlier comments, sorry! I haven't had a lot of experience with CI/CD, but it seems like a really neat thing to learn, and has a lot of good documentation online. For the Github CLI, It turns out that you don't even need to install anything, since the API is a simple fetch command from a URL which returns a JSON string. From what I've seen, you can run terminal commands right in the curl -s 'https://api.github.com/repos/supermacro/elm-antd/releases/latest' | \
python3 -c "import sys, json; print(json.load(sys.stdin)['tag_name'])" This works on my terminal, though the python script is a bit weird. Alternatively, the jq library can make it a lot simpler, though this requires a 3rd party library. curl -s 'https://api.github.com/repos/supermacro/elm-antd/releases/latest' | jq -r '.tag_name'
I'm looking at the Circle CI documentation and there seems to be a lot of different ways to export an environment variable. If it doesn't matter how we do it, I'll just wrap the terminal command with My last question in this unfortunately long comment is about passing down the version number from the |
Happy to help :) I just checked to see if either So I've taken the liberty of adding jq to the Circle CI environment. In The best way to test out if your code works is to run it inside of a docker container.
After you run the above command, you'll be running an interactive bash shell within the docker container. Here you can prototype ideas, and once you're happy with them, then add them to the I did however just realize that the actual building / deployment of the app is done outside of circle 😅 It's done via netlify, so I'm going to have to read a bit about programmatic builds for netlify. Meaning that right now this task is a bit blocked until I figure out how to build the app within circle and then upload it to netlify. |
If you want to, you can set up a free netlify account and learn how you can use the netlify cli to build a site and upload it to netlify (but not publish it ... I manually deploy builds on netlify). |
Oh, I forgot to answer your last question! Yup, I think passing the version as a flag makes total sense. Happy to review a PR around this. |
Thanks for installing And sorry for not being active lately, school's been pretty annoying. I'll look at netlify when I have more time later, but right now I'll just do a quick PR showcasing what I've got for the URL generator. I decided to go the parsing route because generating an AST gives the most flexibility with the code manipulation. It's pretty bare bones and the parsing code is a bit wacky, but it works on Stateless and Message-less files, such as the Alerts and Typography. To pass the versions down, I added a "version" field to every component's One issue regarding the Ellie links is that we don't import the CSS, so the Buttons and Alerts don't have the necessary styling. One approach I was thinking of (at least on stateless and message-less files) is to generate a new function at the bottom of the file which we'll expose: main : Html Msg
main model =
div []
[ Ant.Css.defaultStyles
, example
] but I'll focus on the functionality of the URL generator first, before dealing with this. |
Reading through your PR now. Very excited about this 🤩 👏 🤩 👏 🤩 👏 |
Problem: When creating new code examples in the
showcase
app, we need to specify ametaInfo
record with aellieDemo
url (see code snippet below for an example). The issue is that for a lot of these demos, the code is not yet published in https://package.elm-lang.org/ ... so we have to then do a follow up PR / commit after publishing to https://package.elm-lang.org/ to update theellieDemo
link to actually contain the demo code.Right now I just enter a dummy url and forget to update it (plus, it's extra work and I'm lazy to follow up and update it).
Desired Outcome
1. Use Ellie's programmatic API to dynamically create ellie demos programmatically.
Documentation on how to do this.
Specifically, use Luke Westby's suggestion of encoding the entire elm demo app in the URL.
2. Update all existing demos to use this new API
The text was updated successfully, but these errors were encountered: