How to serve/manipulate git repo from rails - ruby-on-rails

I'm building a rails (rails 6) app that facilitates collaboration on math papers. As the papers are usually written in tex but produce PDFs there may be pictures of blackboards, text note files and sketches I'd like to avoid resolving the merge/source control issues and simply serve a git repository to members of that group of users who want to clone it. But not everyone wants to use the gitcli and the point is to create a single page to manage the collaboration so I also need to be able to display and edit (eg issue commits) directly from the webapp (likely restricted to only fast forwards to master...at least at first).
I suspect there is a gem or engine that allows this and it might even have been answered before here but all my attempts to search just return discussions about using git to version your rails app not using it in the app.
Heck, I'm even willing (at least to hack together a quick working version) to insist that one of the group members setup a GitHub repo and grant some kind of permission to the app (and other users who want direct repo access) if that's a quicker and easier way to hack together a quick solution but I need the rails app to be able to make commits and query the head.
Any suggestion for existing utilities that allow this? If not suggestions on the best way to approach coding that functionality?

This answer (thanks to Int'l man of coding mystery for the pointer) suggests using the library Ruby/Git or Rugged. I haven't had the chance to look closely at the libraries but that solves the problem I had of being unable to find them with search thanks to all the results about putting your ruby code in a git repo.

Related

Share code/configurations/conventions/gems between Rails apps

THE PROBLEM
First a little bit of context: I am currently working as a freelancer, developping webapps using Ruby on Rails. Because I am working solo, the need to optimize my workflow is pretty important.
That's why I have always had the same question since I begun working with Rails:
How can I share code/configuration/conventions/tests between my apps?
More precisely, I want to share:
common gems that I always use, with their configuration
common integration tests, to ensure some conventions
common view helpers, test helpers, extensions to the core classes, javascript/sass partials
common files: .gitignore, git hooks, .eslintrc, configuration files of my CI etc
Some concrete examples of what I need in all my apps:
disable turbolinks by default, to add it later if need be
use javascript instead of coffeescript
use slim instead of ERB
install/configure capistrano
install a CSS framework (bootstrap, bourbon + neat + refills)
So far I don't really have the need to share models nor controllers.
I don't want to share behavior or functional components of the system itself, I am not looking for a micro-services architecture.
I have found that so far when creating new applications, all this setup work does take me a lot of time. Also, I would like to apply it retro-actively to existing apps when I add something new.
I have done quite a bit of research, but I haven't found a lot of answers. Many people are trying to share models, but few people seem to want to share a common ground between all their apps. Finding the right keywords may have been the problem though.
It seems to me that Rails is really good at DRY within an application, not so easy when trying to DRY between applications.
POSSIBLE SOLUTIONS
1 - Rails application template
The solution I am using right now, described in the Rails Application Templates guide, using the same API than the Rails generators described in the Creating and Customizing Rails Generators & Templates guide.
That's the solution used by Thoughtbot, with their popular suspenders gem. In the case of Thoughbot though, they have years of experience to draw from, have many employees and their common setup does not change that much.
Pros:
saves a lot of time when creating a new application
really nice API
Cons:
a lot of duplication: all the apps have the same common code, with the problem of this code getting out-of-sync
not retroactive: useless to add a common feature to already created apps
heavy maintenance work: my current workflow is to go through the git log of my apps once per month, and for each commit that could be common to all the apps I have, add it to the application template, and add it to the other apps manually
So far this solution is not that bad, because I only have two applications. But once I will have more, I will suffer from more and more overhead.
A better solution would be maybe to create a generator/rake task for every common new feature, to be able to apply it quickly to existing apps, and call it directly in the application template for new apps.
I haven't tried it though, and I am not really sure it will work. For example what if I want to propagate a one-line change in an existing common file in all the apps?
2 - Rails Engine
I have tinkered a bit with the Rails Engines to share code.
I have not understood from the Getting Started with Engines guide if I should better use a --full engine or a --mountable one for this specific purpose.
Pros:
once I update the gem version, all the changes are made available to the app
DRY: all the common code is in a unique place (the gem)
Cons:
the gems I would like to share are put in the *.gemspec file, which has not as many features as the Gemfile (from what I understand)
overhead caused by the need to update the version of the gem in all the apps, migrate to the new API of helpers, etc
no way to share non-rails files (.gitignore, git hooks, .eslintrc)
This solution has too many important shortcomings.
3 - Hybrid solution: Rails Application Template + Rails Engine
Maybe the best would actually to use both the above solutions.
In the gem share helpers and tests, in the rails template share the gems, their configuration/files and other files (for git, linters, etc)
It is indeed adding more complexity and overhead...
4 - Use git subtrees
Some people use git subtrees to share folders between multiple webapps.
Cons:
one has to share whole folders, not easy to share everything I would need, in their different target directories in the rails app
seems a bit "hacky" to me
Conclusion
Is there another solution than the ones I mentionned above?
What do you think would be the best way to do it?
How about having a blank "Master" rails app in the git somewhere. With all the settings and configurations you'd like to share. When creating a new app from scratch, you can merge the "Master" into it to apply the defaults. When you have an existing app, same thing, just merge and resolve conflicts as needed.This also gives you the ability to override the merged code if needed to.
Few things I can see wrong with this approach though:
Rails application name could cause a lot of headaches
Any updates could cause merge conflicts
I created a tool to deal with this when working in nodejs projects. But the tool is really just a command line tool so you should be able to use it.
https://github.com/tomasbjerre/dictator-builder
It is a concept with creating a dictator that dictates parts of your code base.

Allowing others to copy and tweak my Rails app online

I have developed a relatively simple Rails web application that others (non-programmers) may find useful. I would like to provide a web interface for anyone who wants to create their own copy of my app and change some minor settings, like the appearance, the name of the app and some of its resources, that type of thing. What kind of technology would allow me to do this? Thank you in advance!
GitHub is probably one of the most popular tools to support this, but there are many others such as SourceForge. I'd start from there and do some research to decide the best one for your purposes.
The best way to collaborate code online is through git. The most popular sites for git management include GitHub and BitBucket. Here's a good article suggesting nine alternatives.
However, you stated it would be used by "non-programmers". I can't tell if they will find it useful through the function of the application or the simplicity of the code, so it seems reasonable to also suggest non-git options.
You could use something like Amazon Web Services or Google Cloud to host the static files. See the AWS S3 docs regarding creating a bucket and adding an object.
If you would like to host the entire application online and allow users to easily edit and view the application in-browser, check out cloud9.

How to run multiple "Applications" under one compoundJS instance?

I've been using nodeJS + expressJS for several years now developing a custom Application Platform for our organization. Our central framework provides a common set of services (authentication, language, administration, etc...) for any installed Modules/Applications under it.
I would like to switch our framework out with compoundJS. However I'm not familiar with the design constraints imposed by it (and Rails apps in general) and can't seem to figure out how to accomplish what I'm after.
I would like to only have a single server instance running: all
requests first process through our common authentication checking.
Then are passed on to an application's controllers.
I would also like to have each application separated out: preferably
under a separate site/applications/ directory. Each of these
applications could be designed using compoundJS normally. And I would like to install them like:
cd site/applications
npm install site-hr
npm install site-finance
npm install site-payroll
this would then have all the routes from /hr, /finance, /payroll operational.
How do I accomplish this?
Is there a way to get compoundJS to search the nonstandard /applications/* folders for models/controllers/views and load them while keeping the central /site configurations?
Or is there a better way?
Sorry for the late answer, but I needed something similar: I needed to put together tool applications in a portal.
I found a way to include child applications in a parent's Compound application as node modules. I wrote a guide on how to do it and sent a pull request to add it in the advanced folder of CompoundJS' guides. It is also available here. It requires a bit of work, but it works fine with 4 applications for us.
Hope it can help.
It's simple. Just use app.use in config/environment.js to map your sub-apps:
var mod = require('your-compound-module');
app.use('/subroot', mod());
When you visit /subroot/any-path, then it will be handled by /anypath route of your sub-app. Note, that you don't need any additional work on path helpers, as they will start with '/subroot' automatically (handled on compound side).
This is a good point, but we haven't seen any implementation yet. May be years later there would be some.
Using a proxy layer in front of the instances would be a general method, usually with Nginx, Vanish Cache etc. For the bleeding edge techs, I've heard Phusion Passenger has implemented Node.js support, but I haven't successfully tested yet. If you are familiar with Ruby, it would be a good try.
If you really want to construct a big project with many modules, you can try out some industrialized frameworks for instance Architect for Cloud9 IDE project.
For authentication, I think it's necessary to use independent methods in each application, but they can share with one user database.

Limiting developer access to git repository for a website and how to deploy it

I am considering taking on a new developer for my rails based website but, because I do not know them, I do not want them to have complete read access to my code. I only want them to be able to read and write to one directory.
Requirements:
I would also like them do be able to deploy their updates/changes.
Both myself and the developer use windows so symbolic linking is not a good idea...
I currently use capistrano to deploy the website but will use vlad or anything else that will work...
Background Reading
So, I have been reading about submodules, subtrees (apenwarr's git-subtree and the subtree merge strategy), giternal, piston, braid, etc, etc and I am completely flummoxed! Any help that can be provided would be greatly appreciated!
My current thoughts
I don't think that submodules are the right choice here because:
1) I would like to make as few changes as possible to the main repository
2) i) The developer would need access to the main repository to notify it of submodule changes... which defeats the purpose of making them work with a submodule.
ii) I could create a master repository that would reference the divided sections of the website but I have no idea how to do this or if it would even work.
Subtrees
If I understand them correctly, someone can work on the subtree and commit to it as if they had full access to only that part of the master repository. At first glance this seems to make them just exaclty what I need - especially since the master repository can reference the current HEAD of a subtree by default and doesn't need manual updating. Unfortunately I can't see how I would deploy the website with subtree nor can I tell if this is really want I want. There is a lot of conflicting opinion about submodules, subtrees etc and it is difficult to sort through it.
Thank you very much for your time reading this and any help that you can offer!
Submodules:
2) send you "pull request", by email or web-based system.

How to extend an existing Ruby on Rails CMS to host multiple sites?

I am trying to build a CMS I can use to host multiple sites. I know I'm going to end up reinventing the wheel a million times with this project, so I'm thinking about extending an existing open source Ruby on Rails CMS to meet my needs.
One of those needs is to be able to run multiple sites, while using only one code-base. That way, when there's an update I want to make, I can update it in one place, and the change is reflected on all of the sites. I think that this will be able to scale by running multiple instances of the application.
I think that I can use the domain/subdomain to determine which data to display. For example, someone goes to subdomain1.mysite.com and the application looks in the database for the content for subdomain1.
The problem I see is with most pre-built CMS solutions, they are only designed to host one site, including the one I want to use. So the database is structured to work with one site. However, I had the idea that I could overcome this by "creating a new database" for each site, then specifying which database to connect to based on the domain/subdomain as I mentioned above.
I'm thinking of hosting this on Heroku, so I'm wondering what my options for this might be. I'm not very familiar with Amazon S3, or Amazon SimpleDB, but I feel like there's some sort of "cloud database" that would make this solution a lot more realistic, than creating a new MySQL database for each site.
What do you think? Am I thinking about this the wrong way? What advice do you have to offer in this area?
I've worked on a Rails app like this, and the way it was done there was named-based virtual hosts, with db entries for each site running. Each record was scoped to a site if necessary (blog posts, etc.) while users would have access to all sites running out of that db. Administrator permissions could be global or scoped to one or more sites.
You're absolutely correct when you say you'll reinvent the wheel a million times during the project. Plugins will likely require hacking on top of the CMS itself.
In my situation, it ended up being a waste of almost a million dollars of company money to build that codebase to run multiple sites while still being able to cater to the whims of each client site. It worked, but was not very maintainable due to the number of site-specific hacks that subsequently entered the codebase. You may be able to make it work if you don't have to worry about catering to specific client sites running on your platform.
In the end, you're going to need a layer of indirection to handle the different sites regardless of methodology. We ended up putting it in the database itself. If you go with the different-db-for-each-site method you mentioned, you'll put that layer in your code instead. I'm not sure which one is the better method.
I hope you're able to pull this off. I failed.
Also, as I learned today, Heroku offers postgres instead of mysql for rails apps.
There's James Stewart's Theme Support Plugin for Rails 2.3, and lucasefe's themes_for_rails gem for Rails 3+.
I just started using the 2.3 version and it's working well so far.

Resources