safe_monkey_patching 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +39 -0
  3. data/lib/safe_monkey_patching.rb +82 -0
  4. metadata +58 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c7ced24c8b951983501b1c890c3b0caa643f9b2e68f366465741fd5493a8e24f
4
+ data.tar.gz: eda8d97d249ef17c44d909c23eb20d034f64d049ac96f862c16afaeb375dc63b
5
+ SHA512:
6
+ metadata.gz: 754b46804461f1181097339ba7975d5f81d8f6081f443660b6392e40601f2c171cdb5c371996d89c50d3a1670154f4bde765e4c1ff9f5d21a1f1a1423c1379dd
7
+ data.tar.gz: 94fc54058102b2439807d3b5d1379390c4c85f532d5d80d53a835f3612ef74097aa646a3cb4207faee4e4364bbd2b27819ea40cdcd40df7282351f9fb506d812
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # safe_monkey_patching
2
+
3
+ **Przykład**
4
+ ```ruby
5
+ module ActiveJob
6
+ class Base
7
+ class << self
8
+ monkey_patch :deserialize
9
+
10
+ def deserialize(job_data)
11
+ ...
12
+ end
13
+ end
14
+ end
15
+ end
16
+ ````
17
+
18
+ metoda `#monkey_patch` generuje hash kodu źródłowego `#deserialize` (tej oryginalnej) i zapisze go do pliku
19
+ ```yml
20
+ ---
21
+ ActiveJob::Core::ClassMethods:
22
+ deserialize:
23
+ sha1: c29634da4f1731775868a6eba5efc837dd711a54
24
+ ```
25
+ a więc, gdy podbijemy railsy i zmieni się kod źródłowy, to `gif diff` nam o tym powie 🤩
26
+
27
+
28
+ ```diff
29
+
30
+ diff --git a/monkey_patchs.yml b/monkey_patchs.yml
31
+
32
+ ActiveJob::Core::ClassMethods:
33
+ deserialize:
34
+ - sha1: c29634da4f1731775868a6eba5efc837dd711a54
35
+ + sha1: 131d3acf24768b30a3ccb1052591b1cdb603f0cd
36
+ ```
37
+
38
+ Dzięki temu będziemy wiedzieli, że trzeba tam zajrzeć 🥳
39
+
@@ -0,0 +1,82 @@
1
+ module SafeMonkeyPatching
2
+ module Behavior
3
+ class << self
4
+ def load_store(path)
5
+ begin
6
+ YAML.load_file(path)
7
+ rescue Errno::ENOENT
8
+ {}
9
+ end
10
+ end
11
+
12
+ def gems_with_patches
13
+ (@gem_paths || []).uniq
14
+ end
15
+
16
+ def add_gem_with_patch(path)
17
+ @gem_paths ||= []
18
+ @gem_paths << path
19
+ end
20
+ end
21
+
22
+ where = ENV.fetch('SAFE_MONKEY_PATCHING_STORE_PATH', '.')
23
+ ERROR_LOCATION = File.join(where, "WRONG_MONKEY_PATCHES.txt")
24
+
25
+ unless ENV['GITHUB_SHA']
26
+ begin
27
+ File.delete(ERROR_LOCATION)
28
+ rescue Errno::ENOENT
29
+ end
30
+ end
31
+
32
+ def monkey_patch(method_sym)
33
+ caller = caller_locations.first.path
34
+ gem_path = Gem::Specification.find do |spec|
35
+ File.fnmatch(File.join(spec.full_gem_path, '*'), caller)
36
+ end&.full_gem_path || Rails.root
37
+
38
+ SafeMonkeyPatching::Behavior.add_gem_with_patch(gem_path)
39
+ return unless Rails.env.test?
40
+
41
+ method = instance_method(method_sym)
42
+ database = SafeMonkeyPatching::Behavior.load_store(File.join(gem_path, 'monkey_patches-new.yml'))
43
+
44
+ method_entry = { method.owner.to_s => { method.name.to_s =>
45
+ { 'sha1' => Digest::SHA1.hexdigest(method.source) } } }
46
+
47
+ new_database = database.merge(method_entry)
48
+ File.open(File.join(gem_path, 'monkey_patches-new.yml'), 'w') do |f|
49
+ f.puts(new_database.to_yaml)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ class Object
56
+ prepend SafeMonkeyPatching::Behavior
57
+ end
58
+
59
+ at_exit do
60
+ return unless Rails.env.test?
61
+ SafeMonkeyPatching::Behavior.gems_with_patches.each do |gem_path|
62
+ old_patches = SafeMonkeyPatching::Behavior.load_store(File.join(gem_path, "monkey_patches-old.yml")).to_yaml
63
+ new_patches = SafeMonkeyPatching::Behavior.load_store(File.join(gem_path, "monkey_patches-new.yml")).to_yaml
64
+
65
+ FileUtils.mv(File.join(gem_path, "monkey_patches-new.yml"),
66
+ File.join(gem_path, "monkey_patches-old.yml"))
67
+
68
+ diff = Diffy::Diff.new(old_patches, new_patches)
69
+
70
+ if diff.to_s.size.positive?
71
+ $stderr.puts 'Wrong monkeypatches!'.red.bold
72
+ $stderr.puts gem_path
73
+ $stderr.puts diff.to_s(:color)
74
+
75
+ open(ERROR_LOCATION, 'a') do |f|
76
+ f.puts("\n")
77
+ f.puts(gem_path)
78
+ f.puts(diff.to_s)
79
+ end
80
+ end
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safe_monkey_patching
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrzej Bisewski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: diffy
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Safe monaky patching
28
+ email: andrzej@bisewski.dev
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/safe_monkey_patching.rb
35
+ homepage:
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubygems_version: 3.0.9
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Safe monkey patching
58
+ test_files: []