Skip to content
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

Merge native repo into client? #121

Closed
mstenta opened this issue Dec 19, 2018 · 29 comments
Closed

Merge native repo into client? #121

mstenta opened this issue Dec 19, 2018 · 29 comments

Comments

@mstenta
Copy link
Member

mstenta commented Dec 19, 2018

@jgaehring and I have been discussing the possibility of merging the native repo (https://github.com/farmOS/farmOS-native) into this one.

First, a bit of history: I will take the blame for initially pushing for two separate repos. This project was originally a single repo called "farmOS-mobile-app" (if I remember correctly). I suggested that we split it into a "client" (for the app JS code) and a "native" (for the native Cordova wrapper stuff). The idea was to keep the native wrapper code separate so that it could be maintained separately, and so that in the future we could retire it (once native browser support for offline was more mature/standardized).

Now, it's starting to feel like it makes more sense to pull them back together. The "client" is still the bulk of the project, so I think it makes sense for this repo to be the new home. The "native" stuff is largely just one way of building the client app (into an Android/iOS app). But we've talked about other builds too - eg: one that can be included directly in farmOS itself, or one that can be hosted as a simple static site somewhere (like GitHub pages).

Let's use this issue to outline the reasons, costs/benefits, and details for what would be required.

@jgaehring
Copy link
Member

A pro for merging, which is of immediate concern right now as we expand the UI, is that we will need certain components, assets and utilities in both repos. That will lead to a lot of duplication and double maintenance if we don't merge. We already have two copies of the logFactory, and that's presented some issues. As we expand the icon set, that will also result in duplication.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

Here are the three "build use-cases" we've been discussing:

Native Android/iOS

This is currently the main output of this project: an app that can be installed on Android/iOS.

Included with farmOS

Another use-case that I am particularly interested in is including the client directly in farmOS. My hope is that, over time, more and more of the common UI functionality can be moved in to the client app, so that it is more accessible to frontend JS developers, and less reliant on Drupal/PHP. @jgaehring and I tested this out, by dropping the script into farmOS using the Libraries module, and adding it to a page callback, and it worked pretty well! Authentication is handled automatically if you are logged into farmOS, because Drupal stores the session cookie which gets shared with the app JS. We talked about taking next steps with it, including adding a service worker that detects network connection and automatically opens up the app when you are offline.

Standalone statically hosted app

The other idea, which is very similar to including it in farmOS, is to host it as a static site/app. For example, on https://farmOS.app. So anyone could go to it, enter the credentials of their farmOS (which are only stored/used within their local client), and use it that way. This might be a bit redundant, if you already have a farmOS URL with the app included, but it's still a neat idea and worth designing for. I just love the idea of being able to open up the app as a standalone static site, and use that to connect to a remote farmOS.

...

So with those three in mind, perhaps we can give some thought to developing some standardized build processes for each case. They would probably end up being similar.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

Another pro for merging is easier versioning. Right now, the native builds hosted on PhoneGap Build are using their own version numbers, separate from either the native or client repos. This is just because each PGB build is a combination of commits from the two other repos, so it's not really feasible to tie them to tags in the repos themselves. I would much prefer to have a single repo with standard Git tags for versions that correspond directly to builds.

@jgaehring
Copy link
Member

jgaehring and I tested this out, by dropping the script into farmOS using the Libraries module, and adding it to a page callback, and it worked pretty well!

I'd like to play around with this more so I know I understand what our options are for importing the app as a library into Drupal. I'm thinking again if the client and other necessary plugins were npm packages, couldn't we just install the client with npm install into that folder where the libraries are held, and load it that way?

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

On the topic of "builds", here is what seems to be the requirements for each of the three use-cases described in my comment above:

Native Android/iOS

We are using PhoneGap Build to build our native Android and iOS apps. The way PGB works is you give it a repository and a branch, and it sucks that in and uses it to build the apps. The branch needs to be JUST the compiled app (the index.html with included JS+CSS), as well as a config.xml file.

You can see our current branch for those builds here: https://github.com/farmOS/farmOS-native/tree/pgb-build

Included with farmOS

There are lots of ways to use Javascript libraries in Drupal. One way is to pull the JS files in via a build process like Drush or Composer - this would essentially drop them into a directory within the codebase, which you could then include using the Libraries module. Another way is to host them on a CDN, which could then be included in a page similarly. So it's just the difference between local and remote hosting of JS files. In either case, we would need to have a "build" version that only includes the JS and CSS of the app, which could then be used inside the context of a Drupal page callback (eg: use them to activate a DIV within a page with the app).

Standalone statically hosted app

If we consider GitHub Pages as a possible hosting option (eg: to host the app publicly at https://farmOS.app), we would essentially just need the same files as we have in the PGB build, minus the config.xml file. This could then be committed to a branch called gh-pages and GitHub would do the rest.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

I'd like to play around with this more so I know I understand what our options are for importing the app as a library into Drupal. I'm thinking again if the client and other necessary plugins were npm packages, couldn't we just install the client with npm install into that folder where the libraries are held, and load it that way?

Ah we were writing at the same time! :-)

Yea NPM could work, but that's not generally part of a PHP build process. Drush or Composer is what you use to build Drupal. With Drush, you can pull in pre-built JS libraries via simple download of a zip file. That's how we pull in Openlayers. Composer might have more advanced options (and maybe it can even be used to run NPM as a sub-build-process).

The key difference between a Drupal/PHP build and a client/JS build, is that typically with the client you are compiling everything into a single JS script. With Drupal, you don't necessarily want that. Drupal will be building separate HTML pages, which may consist of different combinations of JS libraries in each. For example, you might be using Bootstrap for your theme, and you want Openlayers to display a map on one page, so you want to include the Bootstrap files in every page, but you only want to include Openlayers where you're using it. So Drupal expects that you will be adding multiple JS/CSS libraries to a given page - but then it also provides its own layer of bundling called "JS/CSS Aggregation" which intelligently figures out which libraries are needed on each page, and creates single bundled JS and CSS files for each combination that is needed. These files are stored locally as temporary files, and are rebuilt when necessary (eg: when the cache is cleared).

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

So I think we should plan to have a build process that generates the JS and CSS files for the app, and offers them for download via Github as a zip or tar.gz file. This is a common pattern among JS libraries it seems.

Openlayers does this: https://github.com/openlayers/openlayers

Their main repo branch only includes the source files, but their releases offer a "dist" file that ONLY includes a single JS/CSS file pre-built/bundled: https://github.com/openlayers/openlayers/releases

The other benefit of this approach is the "dist" files can then be hosted on a CDN. Here you can see the Openlayers files in cdnjs: https://cdnjs.com/libraries/openlayers - it is just a single JS file and a single CSS file (they also offer a *-debug variant of each which outputs debug information to console).

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

So I could see us offering a similar "dist" package that just contains: farmOS.js and farmOS.css (for example)

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

The other thing that would be required for hosting the app as https://farmOS.app on GitHub pages is to provide a file called CNAME in the gh-pages branch with one line in it: farmOS.app - This tells GitHub to use that as the domain name for the hosted URL. So perhaps creating the CNAME file could also be part of the build process for that case, similar to the config.xml for PGB builds.

@jgaehring
Copy link
Member

Their main repo branch only includes the source files, but their releases offer a "dist" file that ONLY includes a single JS/CSS file pre-built/bundled: https://github.com/openlayers/openlayers/releases

One thing we'll want to keep in mind is that the client will be a little more than your typical library, in that it won't just be a JS library but will also include CSS, static assets, and possibly an index.html file.

I wonder if it makes sense to keep the build scripts and dist folder in a separate repo for each build, and just keep the client code all together in one repo. Then the native repo can just be the www folder with the build scripts, and the repo that builds the dist for the version that gets included in Drupal can just be its own repo. Maybe?

@jgaehring
Copy link
Member

The service worker has to be its own file as well.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

One thing we'll want to keep in mind is that the client will be a little more than your typical library

Yea, that's true. It's not an exact parallel to Openlayers. With OL, you may want to include multiple maps on a single page. But with the farmOS client, you only want one - and you want it to be everything you see, I think.

will also include CSS, static assets, and possibly an index.html file.

Yea agreed. It seems like all of the cases will need those things. The only difference with native is it will need the config.xml, and the only difference with GitHub pages is it will need a CNAME file (as far as I know).

I wonder if it makes sense to keep the build scripts and dist folder in a separate repo for each build, and just keep the client code all together in one repo.

Yea this is the part to figure out... what does the build process look like (for each case), and where do the finished builds live? I don't love the idea of putting them in different repos, but I can see the appeal of having the gh-pages and pgb-build branches outside of the main repo.

And actually, if we did that, we could consider just having a single branch: build, and we point GitHub and PGB to that branch. This could include both the CNAME file and the config.xml file - it wouldn't really matter that they are both there. And that would mean that the "release" that GitHub automatically builds is just the bundled files (aka the "dist").

Maybe that is the best approach...

So we merge farmOS-native into farmOS-client, and we create a new farmOS-client-build repo that builds get published to?

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

We could then use a similar process as the one we were talking about here: #47

We could have the farmOS-client-build repo checked out in the www sub-directory of the farmOS-client repo, so it's easy to commit and push to that repo like we're currently doing for the pgb-build branch.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

Also related: #5

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

The service worker has to be its own file as well.

I think this could actually live in the farm_offline Drupal module. I don't think it's needed outside of that context, right?

So the farm_offline module (which could itself be part of farmOS core), would provide some basic integration between the client app and Drupal/farmOS. Namely: a Drupal page callback and/or theme function, that would allow you to load the app into Drupal, and also a JS file that contains the service worker code.

@jgaehring
Copy link
Member

jgaehring commented Dec 19, 2018

So we merge farmOS-native into farmOS-client, and we create a new farmOS-client-build repo that builds get published to?

I'm trying to figure out how we could just leave the farmos-native repo master branch as the PGB build directory, but it would have too much bloat I think no matter how we did it.... 🤔

I have to say, I'm not the biggest fan of PGB. If we could build with the Cordova CLI tool, that wouldn't be an issue.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

I'm trying to figure out how we could just leave the farmos-native repo master branch as the PGB build directory, but it would have too much bloat I think no matter how we did it.... thinking

Yea I think it would be better to start fresh. Then we could move the farmOS-native repo to the farmOS-legacy group, so that it is maintained as a snapshot of what it was right before we retired it.

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

I have to say, I'm not the biggest fan of PGB. If we could build with the Cordova CLI tool, that wouldn't be an issue.

Fine with me! You're the one doing the releases, so do whatever works best for you.

I liked how easy it was for me to create a PGB build without having any tooling set up. But that will still be possible either way. So if someone wants to fork the repo and make their own builds, they could do that.

But, if we end up needing a separate build repo for the other cases anyway, then it might as well include the config.xml as well. So the option is there in the future to use PGB if we decide to.

@jgaehring
Copy link
Member

Fine with me! You're the one doing the releases, so do whatever works best for you.

Haha, then it's just incumbent on me to actually get the CLI and its tool chain up and running! 😬

But, if we end up needing a separate build repo for the other cases anyway, then it might as well include the config.xml as well. So the option is there in the future to use PGB if we decide to.

Oh yea, the config.xml is necessary for Cordova CLI too. Actually, right now, there are 2 config.xml's I'm maintaining, one in the root, and one in the www directory. Basically, PGB is just running Cordova CLI for us, in the cloud. But we can't really configure it there.

Now here's a thought, can we Dockerize Cordova?

https://github.com/oren/docker-cordova (only works for Android ☹️)

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

Now here's a thought, can we Dockerize Cordova?

Now you're talkin'! :-D

@mstenta
Copy link
Member Author

mstenta commented Dec 19, 2018

Lol that project README:

I don't want to install and configure Java, Android SDK, Ant, cordova etc.. life is too short.

@paul121
Copy link
Member

paul121 commented Dec 23, 2018

I like the idea of hosting on github pages. It makes sense because it's one less thing for the farm to setup, plus it would always be up to date and maintained without user interaction..

It also makes sense for extensibility. With that in place, could I fork and create a custom 'app' that itself is hosted on github pages, but is consistent with the base app? It could reuse the authentication interface and general design of the base app, create coherent user experience, but provide different functionality - not just managing logs. The other way to do this would be including these 'apps' within the base app - where they get their own page(s) somehow within the base app.

I have a couple ideas for more 'custom' analytical views that would require the farmOS API, and pull from the Stripe payment API to do some near-realtime analysis on what is sold, and integrate it with the crop info from farmOS. Another idea is an app to visually see beds in a timeline, and plan plantings within that timeline (think planning rotations for a market farm)

@jgaehring
Copy link
Member

It makes sense because it's one less thing for the farm to setup, plus it would always be up to date and maintained without user interaction.

Very good point! Also, I have to throw out there as an alternative, b/c it's made updating my personal website so much fun and easy as of late: Netlify. It's basically the same as GitHub Pages, but with some extra tooling that makes deployment even easier, but more configurable at the same time. Maybe described as somewhere between GHP and Heroku? (@mstenta , I think I brought Netlify up to you when discussing about JAM stacks.)

It also makes sense for extensibility. With that in place, could I fork and create a custom 'app' that itself is hosted on github pages, but is consistent with the base app?

Totally. One reason we went with the Hybrid app approach, which certainly has its downsides in the native realm, is to prioritize the web aspect of the project, with the prospect that at some point a fully fledged Progressive Web App based on the same codebase could entirely supplant the native app. The web is so great for extensibility, as well as for updating, as you mentioned above. It's so much more practical to create a new URL, with a forked version of a web app (or perhaps just a component of it), and just point users there, rather than to fork an app in the app store, which creates a ton of confusion and is likely to drive people away. Who wants to download and install multiple versions of the same app and have them all living on their phone all the time, while never being able to remember which one does what?

I have a couple ideas for more 'custom' analytical views that would require the farmOS API, and pull from the Stripe payment API to do some near-realtime analysis on what is sold, and integrate it with the crop info from farmOS. Another idea is an app to visually see beds in a timeline, and plan plantings within that timeline (think planning rotations for a market farm).

I would love to see these ideas come to life! I have similar things I'd like to try out related to marketing (my background is in running farmers markets in NYC, actually); perhaps there would be some overlap. All this is good inspiration to push through some of the architectural changes I've been outlining in the documentation. The bigger picture stuff sometimes gets pushed to the back burner when features and bug-fixes take priority, but hopefully this winter we can actually get some of this stuff implemented and start playing around with new extensions that go beyond just managing the logs.

@mstenta
Copy link
Member Author

mstenta commented Dec 31, 2018

@jgaehring What are the main impediments to merging the repos right now?

A lot of the discussion above is around figuring out different build processes, but I think those things could be figured out after a merge, right?

I'm curious to understand better what the challenges of a merge are, if any.

@jgaehring
Copy link
Member

I guess my main hesitation is doing it in the midst of a Sprint, frankly, and having something go haywire with the build process that would slow that down. But I guess with proper git branches, I could work on the merge separately on an experimental branch while the sprint continues on master.

Apart from that, not technically hard, just some hard choices perhaps?

@mstenta
Copy link
Member Author

mstenta commented Dec 31, 2018

I guess my main hesitation is doing it in the midst of a Sprint, frankly

Ah yea, sorry - I didn't mean "right now" as in "let's do it right now!" - but rather: "as the code stands right now". I don't mean to distract from your current efforts - I'm just curious what will be involved in this merge. I think about it every time I go looking for an issue and can't remember which repo it's in. :-)

@jgaehring
Copy link
Member

I think about it every time I go looking for an issue and can't remember which repo it's in.

Haha, yea, good point! I actually would love to move this forward. It really is just about me biting the bullet and making some choices. Maybe I could start working on it now on a separate branch and be ready to merge before starting sprint 3. That way @alexadamsmith would have an easier time working on the harvest module he has in mind too.

@mstenta
Copy link
Member Author

mstenta commented Feb 19, 2019

We ended up merging farmOS-client into farmOS-native via #92

Closing this - but it has some good info in it to refer to later, so I'll mention it in that other issue too.

@mstenta mstenta closed this as completed Feb 19, 2019
@mstenta mstenta transferred this issue from farmOS-legacy/farmOS-client Feb 19, 2019
@mstenta
Copy link
Member Author

mstenta commented Feb 19, 2019

(Transferring all issues from old repository. See #92)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants