All Projects β†’ Jcambass β†’ sane_patch

Jcambass / sane_patch

Licence: MIT license
Making monkey patches sane again

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to sane patch

Bashcov
Code coverage tool for Bash
Stars: ✭ 113 (+79.37%)
Mutual labels:  rubygems
Bundler Leak
Known-leaky gems verification for bundler: `bundle leak` to check your app and find leaky gems in your Gemfile πŸ’ŽπŸ’§
Stars: ✭ 184 (+192.06%)
Mutual labels:  rubygems
KanColle-English-Patch-KCCP
English Patch for the original KanColle browser game, to be used with KCCacheProxy. Translates most of the game into english.
Stars: ✭ 28 (-55.56%)
Mutual labels:  patch
Sepa king
Ruby gem for creating SEPA XML files
Stars: ✭ 125 (+98.41%)
Mutual labels:  rubygems
Gem Compiler
A RubyGems plugin that generates binary gems
Stars: ✭ 136 (+115.87%)
Mutual labels:  rubygems
Vueonrails
πŸ’Ž Rails gem with the power of Vue.js components
Stars: ✭ 250 (+296.83%)
Mutual labels:  rubygems
Factory bot instruments
Instruments for benchmarking, tracing, and debugging Factory Girl models.
Stars: ✭ 108 (+71.43%)
Mutual labels:  rubygems
ctn
Unofficial Android patch for GTASA Android with various quality of life improvements
Stars: ✭ 44 (-30.16%)
Mutual labels:  patch
Instagram Crawler
Crawl instagram photos, posts and videos for download.
Stars: ✭ 178 (+182.54%)
Mutual labels:  rubygems
flake8-putty
Flake8 plugin to control reporting per file and line
Stars: ✭ 38 (-39.68%)
Mutual labels:  monkey-patching
Guides
An effort to provide awesome documentation for the RubyGems ecosystem.
Stars: ✭ 128 (+103.17%)
Mutual labels:  rubygems
Waterdrop
WaterDrop is a standalone Karafka component library for generating Kafka messages
Stars: ✭ 136 (+115.87%)
Mutual labels:  rubygems
yavdb
Yet Another Vulnerability Database
Stars: ✭ 14 (-77.78%)
Mutual labels:  rubygems
Openpgp.rb
[Retired] OpenPGP.rb is a pure-Ruby implementation of the OpenPGP Message Format (RFC 4880).
Stars: ✭ 115 (+82.54%)
Mutual labels:  rubygems
diffy
Tools for finding and manipulating differences between files
Stars: ✭ 47 (-25.4%)
Mutual labels:  patch
Tor.rb
Tor.rb is a Ruby library for interacting with the Tor anonymity network.
Stars: ✭ 108 (+71.43%)
Mutual labels:  rubygems
Rubygems
Library packaging and distribution for Ruby.
Stars: ✭ 2,902 (+4506.35%)
Mutual labels:  rubygems
php.rb
[Retired] PHP.rb translates Ruby code into PHP code.
Stars: ✭ 86 (+36.51%)
Mutual labels:  rubygems
bitcache
[Retired] Distributed, content-addressable storage system.
Stars: ✭ 30 (-52.38%)
Mutual labels:  rubygems
OS-X-Yosemite-on-Unsupported-Macs
Install OS X Yosemite on Unsupported Macs
Stars: ✭ 23 (-63.49%)
Mutual labels:  patch

SanePatch Gem Version Gem Downloads Build Status

SanePatch is a simple and non intrusive helper that aims to make monkey patching a little bit safer.

It achieves this by only applying your patches to a specific version of a gem and raising a exception if the gem version changed. This means that you will always double check that your patches still work after upgrading gems. No surprises anymore!

But wait.. Isn't monkey patching bad?

As with many things in life there is no pure good or bad. Monkey patching can be dangerous in certain situations and should be avoided sometimes but there are reasons to use it.

Good reasons to monkey patch a gem could be:

  • Fixing a bug in a broken gem until a new version of it is released.
  • Performance optimizing a specific method of a gem that is used in a hot code path.

Installation

Add this line to your application's Gemfile:

gem 'sane_patch', '~> 1.0'

And then execute:

$ bundle

Usage

The usage of SanePatch is straight forward:

SanePatch.patch('<gem name>', '<current gem version>') do
  # Apply your patches here the same way as usual.
end

A more specific example:

Greeter.greet # => 'Hello'

# Let's patch the `Greeter.greet` method to output 'Hello Folks'
module GreeterPatch
  def greet
    "#{super} Folks"
  end
end

# We currently have version 1.1.0 of the greeter gem
SanePatch.patch('greeter', '1.1.0') do
  Greeter.prepend(GreeterPatch)
end

Greeter.greet # => 'Hello Folks'

If somebody updates the gem version the patch will raise as soon as its code path is executed:

SanePatch::Errors::IncompatibleVersion:
  It looks like the greeter gem was upgraded.
  There are patches in place that need to be verified.
  Make sure that the patch at initializers/greeter_patch.rb:8 is still needed and working.

Setting the raise_error keyword argument to false will skip the execution of the block but will not raise an error. (The default value for the keyword is true.)

Complex version constraints

SanePatch supports all version constraints you know and love from RubyGems.

SanePatch.patch('greeter', '~> 1.1.0') { # your patch }
SanePatch.patch('greeter', '> 1.1.0') { # your patch }
SanePatch.patch('greeter', '< 1.1.0') { # your patch }

It even supports version ranges based on multiple constraints:

SanePatch.patch('greeter', '> 1.0.0', '< 1.1.0') { # your patch }

This is especially useful if you patch a bug where you know the affected gem versions.

Providing additional information

If you patch a known bug in a gem it might be useful to provide additional information why the patch is needed and when it can be removed.

Greeter.silence # => nil

module GreeterPatch
  def silence
    ''
  end
end

details = <<-MSG
  The `silence` method should output an empty string rather than nil.
  This is a known issue and will be fixed in the next release.
  See: https://github.com/Jcambass/greeter/issues/45
MSG

SanePatch.patch('greeter', '1.1.0', details: details) do
  Greeter.prepend(GreeterPatch)
end

Greeter.silence # => ''

The additionally provided details will also show up in the exception message.

SanePatch::Errors::IncompatibleVersion:
  It looks like the greeter gem was upgraded.
  There are patches in place that need to be verified.
  Make sure that the patch at initializers/greeter_patch.rb:8 is still needed and working.
  Details:
  The `silence` method should output an empty string rather than nil.
  This is a known issue and will be fixed in the next release.
  See: https://github.com/Jcambass/greeter/issues/45

Logging support

The logger keyword argument can be used to supply a logger instance. SanePatch will pass the exception message to that object's #warn method when the version constraint is not satisfied:

SanePatch.patch('greeter', '1.1.0', logger: Logger.new(STDOUT)) { # your patch }

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Jcambass/sane_patch. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the SanePatch project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].