changing gem behaviour and packing it for deployment - ruby-on-rails-3

I have made minor modifications to mislav's famous will_paginate gem. I would like to "pack" those changes along with the rest of the gems I have so I can deploy on other machines easily. What I'm looking for is not a github commit as I only need those changes on my own app for my own purposes.
When I use "bundle pack" it indeed packs all my gems, but the original gem files that were downloaded and not the modifications i've made to the raw files.
How does one go about packing the current gems and then deploying them somewhere else along with changes made to them?
thanks!

You say you are not looking for a github commit, but honestly I think that is the easiest way to do it. Fork the repo, make the changes, commit and push to github and then add it to your Gemfile and point it to your fork. Bundler can install the gem directly from github. I don't even think you will have to regenerate the gemspec, as long as you are not adding new files. In the Gemfile you do this:
gem 'will_paginate', :git=>'git://github.com/your_username_goes_here/will_paginate.git'
So in summary (in case you are not that familiar w/ github):
Login or sign up for github account.
Go to the will_paginate repo and click the "Fork" button
Copy the URL from your new fork
local_shell> git clone git://github.com/your_username_goes_here/will_paginate.git
Make your changes
local_shell> git commit -a
local_shell> git push
Add the git fork URL to your Gemfile
local_shell> bundle install
If you already have a github account, aside from making changes to the code, this whole process will probably take you about 2 minutes. Easy and you will be able to keep track of what you have changed on github. IMO its a bad idea to make changes locally and not commit them to a remote repo... things can get messy and confusing, especially if you are deploying these changes to prod.

Related

How to organize development of Rails App and multiple Engines

It's hard to formulate the question actually so I just explain the situation.
I'm working on a application that consists of multiple sub applications. The main app just provides an navigation bar and some basic functionality like configuration of users and permissions while the sub applications provide the actual functionalities.
Now this is a Rails 2 application and the sub applications get embedded in frames, it's not really nice design and pretty complex to setup.
Fortunately we have Engines now and that would be the saner solution for this application.
Until now everything lives in subversion and can be updated at once, shared code uses externals. We would like to move to git while we're at restructuring and refactoring.
I've been searching the web the past few days about bundler, git submodules and git subtrees but I haven't found a good description how to properly manage a large project which consists of multiple Engines/Gems when you are developing on all of them the same time.
In particular I would like to be able to:
use Bundler to manage dependencies
do not install our own Gems and Engines into the global gem path but relative to the main app, as an git repository
have our own Gems and Engines setup as git repository (maybe with Bundler's local path override)
an easy way to fetch all dependencies (bundle install) which pulls the latest version of our own Gems and Engines, if that's not possible then one command to git pull all own Gems and Engines (maybe an rake task?)
make it easy for new developers to setup the entire development enviroment fast (git clone the app, bundle install dependencies including all own Gems and Engines, locally)
deploy with Capistrano, easily
What I already thought about:
including everything into one repository, seems to defeat the purpose of separate Gems/Engines for me, also I think it wouldn't allow us to manage the dependencies of the main app on our Engines via Bundler
using submodules, I read too many posts about why it's bad, and with our number of developers it's only a matter of time until somebody commits a submodule pointer to a commit that only exists in his local repo
git subtree utility, seems quite complex to me
So has anybody of you a similar setup and how do you manage it to make updating and committing changes as easy as possible? Where do you put your Engine/Gem code on which the application depends?
TL;DR How do manage a large rails project which consists of multiple Engines and Gems?
We have a similar (but probably less complex) case at my company. What we do (as for now) and that could work for you too :
Put your Rails app in its own git repository. The various gems each get their own repository also (while it is possible to do otherwise, the "one gem = one git repository" will make your life easier).
Then in your Rails app Gemfile, you have several options
Default should be to refer each gem to its git repository (so that bundle will load them from there)
When working locally on some of the gems and the Rails app, either change the Gemfile to use the local path (http://gembundler.com/v1.2/gemfile.html) or better, by overriding the path locally (see: http://gembundler.com/v1.2/git.html). Be careful that those two options are different : the first one use the path, the second the local git repository (so a new uncommitted change will be visible by the first, not by the second).
For updating all your gems easily, I would create a small .sh script (just to launch the various clone or update operations, and the bundle install so that everything comes out clean), and commit it with the main app. I would also get a "standard folder organization" among the team (ie, that everyone use a base folder of their choice, with under it folders for the Rails app and each gem), to make the procedure easier.
I hope this can help or get you ideas (your question is quite complex and manifold, so I'm not 100 % sure this is what you are looking for).
How to manage your Gem dependencies?
Bundler via Gemfile.
How to manage your Engines?
Bundler via Gemfile.
Architect your Engines as Gems and provide their git repo location in your Gemfile. If you want examples, check out how to include the https://github.com/radar/forem gem in your Gemfile.
Also, this helped me learn Rails Engines, http://edgeguides.rubyonrails.org/engines.html.
Are you coming from Java Land?
Rails does have a learning curve, but not like the Java mountain cliff drop off.

Pushing new Rails 3.1 app to Heroku causing problems with Sorcery mod (requiring bson-1.4.1)

I have an app that runs great locally. Everything seems to be set up correctly to transfer over to Heroku, including the Postgres gem (and dev was done using a postgres server).
The problem is, when I try to push it up, I get error messages surrounding the three currently problematic dependencies, bson_ext, bson, and mongoid, 1.4.1. It seems that Sorcery requires these (at 1.4.1) to run. I got them installed locally by downloading the manually, but they were yanked from the online sources. So when Heroku tries to find them, it can't, and it aborts. I tried specifying to use 1.4.0 for all of them, and the app then installs fine (and does the database setup stuff for the Cedar stack, etc).
The problem is that when I load the app on their server, I get the generic "oops, there's been a problem" Heroku message. Upon checking the actual heroku log, I can't really find anything wrong. What is the way to make this work?
Thanks for your help.
I ran into the same problem, and I was able to get past it by specifying version 1.3.1 for the mongo, bson, and bson_ext gems. I just put this in my Gemfile:
gem 'mongo', '1.3.1'
gem 'bson', '1.3.1'
gem 'bson_ext', '1.3.1'

Playframework: Upgrade process -- Best Practices

I'd very much appreciate anyone sharing best-practices, patterns, anti-patterns, backup, rollback processes that you have formulated for a pain-free, foolproof, Play framework upgrade.
I'm thinking just replacing the bin/play directory with the latest version can cause problems
Edit:
I'm looking for more specific version management strategies, say,
a) Do you just have /bin/play directory having the latest play version or
b) Do you keep versions like /bin/play-1.1 /bin/play-1.2 and change your $PATH to point to the latest (cons: you have to rebuild your modules, dependencies & libs; pros: gives better control over rollback)
I prefer to install play from source using git:
git clone git://github.com/playframework/play.git
cd play
# checkout specific version
git checkout 1.2.1
cd framework
ant
cd ..
ln -s $PWD/play ~/bin
So I have a full install including all source. Later, when play was updated to version 1.2.2 I did the following:
cd <play_home>
git pull
git checkout 1.2.2
cd framework
ant
In your application you then do
play clean && play run
The advantage of running play from a source build is that you can always and easily roll back to the previous version or even test out features from current development. This does not solve the problem of having multiple versions of play active at the same time though.
I agree with Andre. However, if you are asking for best practice for a live project, I would do it differently.
You can have multiple version installed on your local machine. The only thing you have to change is which one is visible in the path. For instance you could have 1.1, 1.2, 2.0 and depending on which one you want, you just modify your /home/youruser/.bashrc file.
The reason, why simple update of play from git or hg will not work/good idea is because, incase there are problems, you have to revert, rollback modules, or goodness know what not.
It is far better to simple swap out the play version, rebuild, test extensively, once you are ok that everything is good, then you can make the same changes in a live site.
If things don't workout, or your are hopelessly lost, all you have to do is revert the changes to your project and switch the play version. You will be back to where you started.

How to deal with different gem dependencies within Bundler for scripts within a single Rails project?

Our Rails application pulls feeds from multiple sources. The workers that pull these feeds need gem dependencies for rmagick, oracle databases, and many other gems. In short, they have very different dependency needs than the main web application. Until Rails 3 and Bundler, life was good.
These worker gem dependencies are irrelevant to our actual production website. Under Rails 3, one Gemfile is expected to contain all these dependencies. This has the nasty side effect of requiring all gem dependencies to be loaded within the production app, which would cause pointless bloat, possible security issues, memory leaks, complicate deployment, and other ills. Sadly, Bundler breaks the standard require mechanism, which would have provided a way out of the quagmire by allowing us to simply require the necessary gems only in the worker and have them somewhere on the system, not in the bundle. The workers use our rails models to file their data.
Can anyone suggest solutions to make the system practical in Rails 3? I am tempted to make the Gemfile use conditional environment variables in places to drive the gem commands, however, it seems the Gemfile.lock could make this problematic going from working on one worker script (for the feeds) to the next, which would have different dependencies. Help???
I've been contemplating a similar problem, and although I don't have a solution in use anywhere yet, your question did make me think it out some more. I think you should be able to use a group to accomplish this. You can add something like this to your Gemfile:
group :workers do
gem "extra_gem_1"
gem "extra_gem_2"
end
Then, you can call
Bundler.require(:default, :workers)
and that should load your gems. How this works will depend on your setup, you might be able to add logic to config/application.rb, or you might need to do this elsewhere. This might be hackish, but it works in the console anyway.
When installing your gems, you can call:
bundle install --without workers
to exclude those gems from production.
Alternatively, you can use two Gemfiles, but that seems like a mess as well since presumably there's some crossover.

Which SCM system to use with Xcode 4 for a lone developer?

I'm an iOS developer looking to better manage the projects I am creating. I've never touched SCM before so I'm not sure which system to use.
I'd like to keep track of changes to the different apps I'm making for my boss, but also have them in a centralised place, and be able to branch off and be working on features separate from the main app and then merge the changes back in when I'm finished. All of this will be done locally (stored on an external hard disk in my office), and once versions are complete I'd like to be able to export a copy without the SCM features to send to my boss.
I've just upgraded to Xcode 4 and noticed Git is built in. I played around with both Subversion and Git, but it sounds like Git is what would fit my needs better. However, it seems to be totally different to Subversion. The Xcode 4 documentation suggests Git is best for lone developers, but that doesn't seem the case. If the git repository is inside your working copy, how on earth do you make branches of it? Where do you send your changes to? Do you copy the entire working directory and use that as your branch?
Just looking for someone to explain in plain english which SCM system would be best for a lone developer to use and any tutorials people may know of to help me understand it.
Thanks for any help!
Go for git!
The repository actually resides in your working directory. There is .git folder which contains all the data about your branches and commits and whatsoever. You can create a bare repository(only the contents of the .git folder) if you like but having both in the same place is nice, especially if you are a single developer who doesn't need distribution.
Branching in git is very easy:
# create the branch
git branch mybranch
# switch to branch
git checkout mybranch
# show branches
git branch
Git does not depend on a server like svn does. You can have distributed development by using remotes but this is not necessary.
If you like to make a copy for your boss without the git files in it do a
git archive branchname --format=zip -o tree.zip
I suggest some reading on git
Git in five minutes
Git Community Book
The Thing About Git
Branching in git is very different from SVN. Branching happens in place, in stead of in another directory.
Read this book and other resources to get a better understanding about how git works
About the centralized server, Git is a decentralized SCM. That means that every clone contains the entire repository, not only the current working directory.
That doesn't mean you can't have a central repository. On the central server you create a bare repository, and on you're local machine you clone from that repository, push and pull from that repository, often through ssh.