How to version control a rails plugin and the testing app together - ruby-on-rails

I'm in the process of creating my first rails plugin and am finding managing version control of the plugin and testing app rather annoying.
Here's my problem:
To actually test my plugin in action I need to run it within a test application (which is basically just a scaffold app where I install the plugin)
When I'm making changes to the plugin, it's convenient for me to change it within the test application so i can immediately see the changes come through. However, when I want to commit and push my changes back to github I end up copying all the files out of the test app back into my "naked plugin" folder and doing my commits.
Is there a better way to manage this without copying files back and forth? I'm interested to hear from other plugin developers if possible on how you manage this situation.
One potential solution I've conceived of is to have another git repository within the vendor/plugins/myplugin directory (which will have the remote repo of github). Im not sure if this is best though (and so far I haven't been very successful in making it work...)

I recommend to use git submodules, check a detailed description.

I create a soft link in the vendor/plugin directory to point to the plugin source code.
If you are on Windows you can use the junction tool to create a softlink.
E.g:
c:\test_app
vendor
plugin
foo_plugin -> points to c:\foo_plugin
c:\foo_plugin
lib

Submodules are going work best I think. What I don't like about developing plugins is that you're always starting/stopping the script/server. Without knowing what kind of plugin you're building, I'll just assume that you're building an abstracted class of some kind.
I personally think the best way to go is to develop the class in the lib directory of your rails app. Once you get it about 99% done, then move the class into the lib directory of your plugin. Then commit the changes to the plugin repo.

If you're willing to package your final plugin as a gem, then there is a much easier way. In your basic scaffold app, inside your Gemfile you can point to a local path:
gem 'foo', :path => "../foo"
This way your scaffold app and engine/plugin are in two separate directories; two completely unrelated git repos. You don't even have to start & stop your scaffold web server when you make changes to the plugin (at least in rails 3).
I just wrote up a tutorial for how I created my first rails engine and I extracted the foundation into a good starting point for other engine builders:
http://keithschacht.com/creating-a-rails-3-engine-plugin-gem
As an end user of a plugin, I think it's much easier if it's packaged as a gem. Not only is more functionality possible with a gem, developers can install it once and use it in many apps, dependencies can be easily handled, upgrades are as simple as changing a version number, and you don't have to store the entire plugin in your main app's repo.

Related

Nesting Ruby gems inside a Rails project

How do I create a gem project nested inside my current Rails project?
I've got a Rails project with several parts that could easily be gems. I would like to extract these parts into gems but not leave the current Rails project. Creating new source control repos for the gems add additional complexity that project or organization is not ready or able to handle. These complexities will be overcome at some point and I would like to be ready.
So far I can only think of these items.
Relocate code to a single directory root. I'm guessing this would be in the vendor path
Create a <something>.gemspec
Link to the gem in the Gemfile of the Rails app
gem 'my_lib_code', path: 'vendor/my_lib_code'
What else do I need to do? I'm sure I'm missing something important.
If this were a c project I would create another shared library that the make process spits out. Or if this where a c# project I would make a .dll. For Java I would...
I'm sure Ruby can do the same as all the other languages. Something that is a half way step between a normally fully extracted gem and just some code siting in my lib path.
This is a perfectly fine approach for a component-based architecture.
You have a single repository, a single test suite, and a single deployment process, while at the same time you are "forced" to think of clean interfaces and separation of concerns.
Of course if you are planning on sharing this functionality with other projects, an externally hosted (but not necessarily public) Gem would serve better.
Implementation wise, you can get some nifty ideas from Stephan Hagemann's talk at this year's RailsConf: "Get started with Component-based Rails applications!"

Is it possible to create a self contained ruby on rails package?

I'm currently looking into what language to build a web application on that will be sold to companies. To make things easier, I was hoping to package the webapp into a convenient installer that contains the entire stack which will run automatically.
Is there any way to create a self contained RoR package?
The only project I'm aware of is called pkgr, which bundles an entire rails app into a DEB package. So if you don't mind limiting your installs to Ubuntu/Debian, you could give it a try.
pkgr home page
Github
You can write a rake task to automatize everything for you. Migrations, bundling, enviroment setup. And it's pretty much plain Ruby, too.
In the end it would be just running a script file to do the job.

Ruby on Rails: what is the best choice of Web UI for managing I18n yml files?

I want to grant to external people possibility to change translation in my project. I want to use web interface for it. And I want all this changes to be git commited. And, if it possible, I want to see authors of changes, so in the best case this web ui should have users and it's own authorization system.
I found question Is there a web UI for modifying I18n locales for Rails 3?, but this isn't satisfy all conditions (like git for example or different users).
So it would be great if you pointing such Web UIs to me.
P.S. I use Rails 3
Rails Translation Center Gem is awesome! https://github.com/BadrIT/translation_center
It is free; you don't need to pay for such locale or phrase!
We are using https://webtranslateit.com/ with our Rails 3 project.
It has users, translator groups etc. and works pretty well. It can read the changes of the translation files from git, but it cannot commit automatically back. However, for us that has not been a problem as when there are updated translations some of the developers can easily do a "WTI pull" to get newest translations, check that nothing is broken and make a git commit of those.
It seems like the translate app would do what you want, just add git commits to it. There's a storage module. Fork the repo, add git functionality using the ruby-git gem. Make a git commit call after the yml file is written. You'll have to hook the commit.author.name and commit.author.email to your authorization system in Rails to make it "multi-user".
Should be a fun little project.
You can use locale or phrase. They are both free in beta.
Alternatively, you can setup your own translation web service with copycopter.

Share visual assets along with some controllers between two rails apps?

I have two rails apps that I am thinking about merging into one because they share a similar layout. Right now there is a script in one app that pulls the resources from the other app (including a base controller) into the second app. There are a few ways I have been thinking about doing this:
Merge the apps with namespaces and upon deploy have a script that creates two separate RPM packages (this is for deployment on CentOS/RHEL) with the appropriate files in it
Run one app as the engine of another. Put all the shared controllers and visual assets into the top-level app. Upon deployment rip rip out the engine if I don't need it. (i.e. if it is just the first app and I don't want to give the code of the second app)
Create a GEM with the common controllers and CSS/JS and find a way to inject it into each running app.
Any thoughts/ideas? I am thinking of going with number 1 as it will probably be the easiest for development (2 would be easier for deployment I think)
At Brighter Planet we do (3). Our shared layout gem supports both Rails 2 and Rails 3.
In particular you'll want to look at:
lib/brighter_planet_layout/rails.rb which helps Rails 2
lib/brighter_planet_layout/railtie.rb which helps Rails 3
lib/brighter_planet_layout/rake_tasks.rb which helps you copy shared files into Rails 2 public dirs
How about 4: make three engines (or gems, or engines encapsulated in gems): one for the common stuff, and one for each application's unique stuff?
Have you considered creating an engine with the common controllers, css, and js, then packaging the engine as a gem. When you are working locally, you can have both apps point to a shared development copy of the gem using bundler. To deploy, package the gem with each app, and deploy the whole thing. There are a lot of benefits to doing it as a gem, like the ability to have different versions of the gem in the future so you don't have to update both apps at the same time.
This seems like a pretty decent engines guide: http://www.themodestrubyist.com/2010/03/05/rails-3-plugins---part-2---writing-an-engine/.
I'd be very leery of it, and would probably go with the above approach, but you may consider using symlinks to permanently pull files into one or the other of the projects. I think it's a bad idea, but in some narrow cases it might make sense. It really depends on your exact situation since it's kind of a nasty hack, but nasty hacks can sometimes solve specific problems eloquently.
Most importantly, I'd recommend not merging the apps. The scenarios of modifying the package on deployment to separate the two apps is error prone, and counter to current quality control procedures-- you want the code you develop to match the deployed app as much as possible.
Given that, you want to look at the different modularity approaches. There are actually lots of options for sharing code:
gem
plugin
library code included with a git submodule or equivalent
rails engine
separate deployed app
Probably a shared engine packaged as a gem is the nicest way to go, but it requires you be on the right version of Rails to get the full benefit. Even without an engine, you can get this to work... it'll just take a little more setup.
By "separate deployed app", I mean a third application that has the shared functionality. This may be the needed resources (CSS, JS), and can even be portions of the pages (loaded dynamically). This is potentially a funky solution, but I've seen it work in the right situation.
And any of these solutions requires a bit more effort on the developers' part... but in the end it's better the deployment troubles you'd get by mergine the code bases

How do I either "unrm" in git repository or move files from one repository to another

I have a large rails project currently using rails 2.3.11 and I want to migrate it up to rails 3. I had an idea that I'd like to try but I need some git help.
What I want to do is start from a fresh new rails 3 app. One idea is to get in my current rails project directory and delete everything. Then do a commit so the tree is empty. Then create a new rails 3 project. This way I am starting fresh so everything will be current.
Then as I add the old controllers, etc back into the project, I want to "unrm" them. Git knows the history of the files and I'd like to keep that history.
Another alternative would be to start a fresh rails 3 app and then somehow transport files from the old git repository to the new git repository but I'd like to keep the history of the file.
This is a half baked idea but it seems a more viable approach to moving this particular project is to essentially start over fresh and then move things from the old project into the new project. But when I move things from old to new, I'd like to keep the history of each particular file.
Can anyone suggest a method of doing what I've just outlined?
First: check out this to automatically find some of the things that need to be upgraded: https://github.com/rails/rails_upgrade
To answer your question: You can upgrade your rails gem and then run rails new . to generate a new rails 3 app on top of your rails 2 app. It will clobber a few of your important files, but you can use git diff to figure out what was in them and copy the important things into the new file. Finally, there's a few things you might need to manually delete (like all of the files in the script/ folder except for rails). "Generating" a new rails 3 app on top of your existing app seems to be the recommended practice, and worked well for me when I upgraded a rather large and old app.

Resources