redmine_with_git 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/initializers/001_patches.rb +11 -3
- data/installer/default_settings.sh +0 -3
- data/installer/programs/redmine_git_hosting/ssh_run.sh +15 -0
- data/installer/programs/redmine_git_hosting/ssh_server_port.sh +6 -0
- data/installer/setup.sh +1 -0
- data/installer/tasks/_before_run.sh +1 -0
- data/installer/tasks/gitolite_setup.sh +2 -2
- data/installer/tasks/redmine_git_hosting.sh +1 -1
- data/installer/tasks/redmine_git_hosting_settings.sh +1 -0
- data/installer/tasks/rugged_build_config.sh +12 -0
- data/installer/tasks/rugged_ssh_support.sh +17 -0
- data/installer/tasks/ssh_client_known_hosts.sh +45 -0
- data/installer/tasks/ssh_server_running.sh +4 -2
- data/installer/template/redmine_git_hosting_setting_value.sql +3 -3
- data/lib/redmine_with_git/patches/redmine_git_hosting/cache/database.rb +23 -0
- data/lib/redmine_with_git/patches/redmine_git_hosting/commands/{git/git_patch.rb → git_patch.rb} +0 -4
- data/lib/redmine_with_git/patches/redmine_git_hosting/gitolite_hook_patch.rb +0 -5
- data/lib/redmine_with_git/version.rb +1 -1
- metadata +21 -35
- data/config/initializers/000_dependencies.rb +0 -25
- data/lib/redmine_with_git/patches/redmine_git_hosting/cache/database_patch.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c597d5c06d8ff60d9ba67d13d4b06ce51a391c647bafc17f3fd3e8bc88707a8
|
|
4
|
+
data.tar.gz: b9d49e4e77549319b28bfcc669b767b6d2e34b649cc548d2f029062e0b6cf8f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb787e09c78accb903648b6ac2ee649ac573fa6a4b7fdc2831bc9fa628089c90f1ea1635695c443f50b85a128cbd43024393fc3d7d5fdfba37d1c984c50fead9
|
|
7
|
+
data.tar.gz: 796da71dce6836904c4f73604d6057799b105aaac6b4195a833b1af769e1a5766dc7a3769b96c648f42f61114d0a841dff3c7ca507b1514e467de41dfca25813
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
EacRubyUtils.patch_module(
|
|
4
|
+
RedmineGitHosting::GitoliteHook,
|
|
5
|
+
RedmineWithGit::Patches::RedmineGitHosting::GitoliteHookPatch
|
|
6
|
+
)
|
|
4
7
|
|
|
5
8
|
apply_patches_version_limit = Gem::Version.new('4.0.0')
|
|
6
9
|
redmine_git_hosting_version = Gem::Version.new(
|
|
@@ -9,5 +12,10 @@ redmine_git_hosting_version = Gem::Version.new(
|
|
|
9
12
|
|
|
10
13
|
return unless redmine_git_hosting_version < apply_patches_version_limit
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
patch = RedmineWithGit::Patches::RedmineGitHosting::Cache::Database
|
|
16
|
+
target = RedmineGitHosting::Cache::Database
|
|
17
|
+
target.send(:include, patch) unless target.include?(patch)
|
|
18
|
+
|
|
19
|
+
patch = RedmineWithGit::Patches::RedmineGitHosting::Commands::GitPatch
|
|
20
|
+
target = RedmineGitHosting::Commands::Git
|
|
21
|
+
target.send(:include, patch) unless target.include?(patch)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
var_set_by STRICT_HOST_KEY_CHECKING bool_s "$1" 'yes' 'no'
|
|
7
|
+
shift
|
|
8
|
+
|
|
9
|
+
sudo -u "$(programeiro /rails/user)" \
|
|
10
|
+
ssh -oBatchMode=yes "-oStrictHostKeyChecking=${STRICT_HOST_KEY_CHECKING}" \
|
|
11
|
+
-i "$(programeiro /redmine_git_hosting/ssh_key)" \
|
|
12
|
+
-p "$(programeiro /redmine_git_hosting/ssh_server_port)" \
|
|
13
|
+
-l "$gitolite_user" \
|
|
14
|
+
"$SSH_SERVER_HOST" \
|
|
15
|
+
"$@"
|
data/installer/setup.sh
CHANGED
|
@@ -4,11 +4,11 @@ set -u
|
|
|
4
4
|
set -e
|
|
5
5
|
|
|
6
6
|
function task_dependencies {
|
|
7
|
-
echo gitolite_rc gitolite redmine_git_hosting_ssh_key ssh_server_running
|
|
7
|
+
echo gitolite_rc gitolite redmine_git_hosting_ssh_key ssh_client_known_hosts ssh_server_running
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
function task_condition {
|
|
11
|
-
|
|
11
|
+
programeiro /redmine_git_hosting/ssh_run no info
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function task_fix {
|
|
@@ -5,6 +5,7 @@ set -e
|
|
|
5
5
|
|
|
6
6
|
function redmine_git_hosting_setting_template {
|
|
7
7
|
export redmine_git_hosting_ssh_key=$(programeiro /redmine_git_hosting/ssh_key)
|
|
8
|
+
var_set_by SSH_SERVER_PORT programeiro /redmine_git_hosting/ssh_server_port
|
|
8
9
|
template_apply "${REDMINE_WITH_GIT_TEMPLATE_ROOT}/redmine_git_hosting_setting_value.sql" -
|
|
9
10
|
}
|
|
10
11
|
export -f redmine_git_hosting_setting_template
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -u
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
function task_dependencies {
|
|
7
|
+
echo redmine_bundle rugged_build_config
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function task_condition {
|
|
11
|
+
programeiro /rails/bundle exec ruby -e "require 'rugged'; exit(Rugged.features.include?(:ssh) ? 0 : 1)"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function task_fix {
|
|
15
|
+
programeiro /rails/bundle pristine rugged
|
|
16
|
+
programeiro /redmine/installer/triggers/set 'restart_application'
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -u
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
function ssh_client_known_hosts_file {
|
|
7
|
+
printf '%s/known_hosts' "$(dirname "$(programeiro /redmine_git_hosting/ssh_key)")"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function ssh_client_known_hosts_spec {
|
|
11
|
+
var_set_by SSH_SERVER_PORT programeiro /redmine_git_hosting/ssh_server_port
|
|
12
|
+
if [ "$SSH_SERVER_PORT" == '22' ]; then
|
|
13
|
+
printf '%s' "$SSH_SERVER_HOST"
|
|
14
|
+
else
|
|
15
|
+
printf '[%s]:%s' "$SSH_SERVER_HOST" "$SSH_SERVER_PORT"
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function ssh_client_known_hosts_entries_count {
|
|
20
|
+
local known_hosts
|
|
21
|
+
known_hosts="$(ssh_client_known_hosts_file)"
|
|
22
|
+
[ -f "$known_hosts" ] || { echo 0; return; }
|
|
23
|
+
sudo -u "$(programeiro /rails/user)" \
|
|
24
|
+
ssh-keygen -F "$(ssh_client_known_hosts_spec)" -f "$known_hosts" | grep -vc '^#'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ssh_client_known_hosts_connection_ok {
|
|
28
|
+
programeiro /redmine_git_hosting/ssh_run yes info >/dev/null 2>&1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function task_dependencies {
|
|
32
|
+
echo redmine_git_hosting_ssh_key ssh_server_running
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function task_condition {
|
|
36
|
+
[ "$(ssh_client_known_hosts_entries_count)" == '1' ] && ssh_client_known_hosts_connection_ok
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function task_fix {
|
|
40
|
+
local known_hosts
|
|
41
|
+
known_hosts="$(ssh_client_known_hosts_file)"
|
|
42
|
+
sudo -u "$(programeiro /rails/user)" \
|
|
43
|
+
ssh-keygen -R "$(ssh_client_known_hosts_spec)" -f "$known_hosts" >/dev/null 2>&1 || true
|
|
44
|
+
programeiro /redmine_git_hosting/ssh_run no info
|
|
45
|
+
}
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
set -u
|
|
4
4
|
set -e
|
|
5
5
|
|
|
6
|
+
PACKAGE_ARGS=('systemctl' "$SSH_SERVER_SERVICE")
|
|
7
|
+
|
|
6
8
|
function task_condition {
|
|
7
|
-
|
|
9
|
+
SUDO=t package_installed "${PACKAGE_ARGS[@]}"
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
function task_dependencies {
|
|
@@ -12,5 +14,5 @@ function task_dependencies {
|
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
function task_fix {
|
|
15
|
-
|
|
17
|
+
SUDO=t package_assert "${PACKAGE_ARGS[@]}"
|
|
16
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
--- !ruby/hash:
|
|
1
|
+
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
2
2
|
all_projects_use_git: 'false'
|
|
3
3
|
delete_git_repositories: 'true'
|
|
4
4
|
download_revision_enabled: 'true'
|
|
@@ -34,8 +34,8 @@ gitolite_resync_all: 'false'
|
|
|
34
34
|
gitolite_resync_all_projects: 'false'
|
|
35
35
|
gitolite_resync_all_ssh_keys: 'false'
|
|
36
36
|
gitolite_scripts_dir: ''
|
|
37
|
-
gitolite_server_host:
|
|
38
|
-
gitolite_server_port: '
|
|
37
|
+
gitolite_server_host: '%%SSH_SERVER_HOST%%'
|
|
38
|
+
gitolite_server_port: '%%SSH_SERVER_PORT%%'
|
|
39
39
|
gitolite_ssh_private_key: "%%redmine_git_hosting_ssh_key%%"
|
|
40
40
|
gitolite_ssh_public_key: "%%redmine_git_hosting_ssh_key%%.pub"
|
|
41
41
|
gitolite_temp_dir: "/tmp/redmine_git_hosting_%%gitolite_user%%/"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RedmineWithGit
|
|
4
|
+
module Patches
|
|
5
|
+
module RedmineGitHosting
|
|
6
|
+
module Cache
|
|
7
|
+
module Database
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.prepend(InstanceMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module InstanceMethods
|
|
13
|
+
def apply_cache_limit
|
|
14
|
+
return unless max_cache_elements >= 0 && GitCache.count > max_cache_elements
|
|
15
|
+
|
|
16
|
+
GitCache.order(created_at: :desc).last.destroy
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: redmine_with_git
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esquilo Azul Company
|
|
@@ -15,68 +15,56 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0.
|
|
19
|
-
- - ">="
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version: 0.102.3
|
|
18
|
+
version: '0.103'
|
|
22
19
|
type: :runtime
|
|
23
20
|
prerelease: false
|
|
24
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
22
|
requirements:
|
|
26
23
|
- - "~>"
|
|
27
24
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: '0.
|
|
29
|
-
- - ">="
|
|
30
|
-
- !ruby/object:Gem::Version
|
|
31
|
-
version: 0.102.3
|
|
25
|
+
version: '0.103'
|
|
32
26
|
- !ruby/object:Gem::Dependency
|
|
33
27
|
name: eac_rails_utils
|
|
34
28
|
requirement: !ruby/object:Gem::Requirement
|
|
35
29
|
requirements:
|
|
36
30
|
- - "~>"
|
|
37
31
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: '0.
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: 0.29.5
|
|
32
|
+
version: '0.31'
|
|
42
33
|
type: :runtime
|
|
43
34
|
prerelease: false
|
|
44
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
45
36
|
requirements:
|
|
46
37
|
- - "~>"
|
|
47
38
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '0.
|
|
49
|
-
- - ">="
|
|
50
|
-
- !ruby/object:Gem::Version
|
|
51
|
-
version: 0.29.5
|
|
39
|
+
version: '0.31'
|
|
52
40
|
- !ruby/object:Gem::Dependency
|
|
53
41
|
name: eac_ruby_utils
|
|
54
42
|
requirement: !ruby/object:Gem::Requirement
|
|
55
43
|
requirements:
|
|
56
44
|
- - "~>"
|
|
57
45
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '0.
|
|
46
|
+
version: '0.134'
|
|
59
47
|
type: :runtime
|
|
60
48
|
prerelease: false
|
|
61
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
62
50
|
requirements:
|
|
63
51
|
- - "~>"
|
|
64
52
|
- !ruby/object:Gem::Version
|
|
65
|
-
version: '0.
|
|
53
|
+
version: '0.134'
|
|
66
54
|
- !ruby/object:Gem::Dependency
|
|
67
|
-
name:
|
|
55
|
+
name: rdoc
|
|
68
56
|
requirement: !ruby/object:Gem::Requirement
|
|
69
57
|
requirements:
|
|
70
|
-
- - "
|
|
58
|
+
- - "~>"
|
|
71
59
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
60
|
+
version: '7.2'
|
|
73
61
|
type: :runtime
|
|
74
62
|
prerelease: false
|
|
75
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
76
64
|
requirements:
|
|
77
|
-
- - "
|
|
65
|
+
- - "~>"
|
|
78
66
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: '
|
|
67
|
+
version: '7.2'
|
|
80
68
|
- !ruby/object:Gem::Dependency
|
|
81
69
|
name: sidekiq
|
|
82
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -97,20 +85,14 @@ dependencies:
|
|
|
97
85
|
requirements:
|
|
98
86
|
- - "~>"
|
|
99
87
|
- !ruby/object:Gem::Version
|
|
100
|
-
version: '0.
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: 0.13.2
|
|
88
|
+
version: '0.15'
|
|
104
89
|
type: :development
|
|
105
90
|
prerelease: false
|
|
106
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
92
|
requirements:
|
|
108
93
|
- - "~>"
|
|
109
94
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0.
|
|
111
|
-
- - ">="
|
|
112
|
-
- !ruby/object:Gem::Version
|
|
113
|
-
version: 0.13.2
|
|
95
|
+
version: '0.15'
|
|
114
96
|
executables: []
|
|
115
97
|
extensions: []
|
|
116
98
|
extra_rdoc_files: []
|
|
@@ -122,7 +104,6 @@ files:
|
|
|
122
104
|
- app/views/backup/_export.html.erb
|
|
123
105
|
- app/views/backup/_import.html.erb
|
|
124
106
|
- app/views/backup/index.html.erb
|
|
125
|
-
- config/initializers/000_dependencies.rb
|
|
126
107
|
- config/initializers/001_patches.rb
|
|
127
108
|
- config/initializers/500_nonproject_modules.rb
|
|
128
109
|
- config/locales/en.yml
|
|
@@ -133,6 +114,8 @@ files:
|
|
|
133
114
|
- installer/programs/linux/sudo_file_exists.sh
|
|
134
115
|
- installer/programs/linux/sudo_write.sh
|
|
135
116
|
- installer/programs/redmine_git_hosting/ssh_key.sh
|
|
117
|
+
- installer/programs/redmine_git_hosting/ssh_run.sh
|
|
118
|
+
- installer/programs/redmine_git_hosting/ssh_server_port.sh
|
|
136
119
|
- installer/programs/text/diff_stdin_file.sh
|
|
137
120
|
- installer/programs/triggers/redmine_git_hosting_rescue.sh
|
|
138
121
|
- installer/setup.sh
|
|
@@ -148,6 +131,9 @@ files:
|
|
|
148
131
|
- installer/tasks/redmine_git_hosting_ssh_key.sh
|
|
149
132
|
- installer/tasks/redmine_gitolite_sudoer.sh
|
|
150
133
|
- installer/tasks/redmine_with_git_bundle_requirements.sh
|
|
134
|
+
- installer/tasks/rugged_build_config.sh
|
|
135
|
+
- installer/tasks/rugged_ssh_support.sh
|
|
136
|
+
- installer/tasks/ssh_client_known_hosts.sh
|
|
151
137
|
- installer/tasks/ssh_server.sh
|
|
152
138
|
- installer/tasks/ssh_server_running.sh
|
|
153
139
|
- installer/template/gitolite.rc
|
|
@@ -170,8 +156,8 @@ files:
|
|
|
170
156
|
- lib/redmine_with_git/load/database.rb
|
|
171
157
|
- lib/redmine_with_git/load/files.rb
|
|
172
158
|
- lib/redmine_with_git/load/git.rb
|
|
173
|
-
- lib/redmine_with_git/patches/redmine_git_hosting/cache/
|
|
174
|
-
- lib/redmine_with_git/patches/redmine_git_hosting/commands/
|
|
159
|
+
- lib/redmine_with_git/patches/redmine_git_hosting/cache/database.rb
|
|
160
|
+
- lib/redmine_with_git/patches/redmine_git_hosting/commands/git_patch.rb
|
|
175
161
|
- lib/redmine_with_git/patches/redmine_git_hosting/gitolite_hook_patch.rb
|
|
176
162
|
- lib/redmine_with_git/version.rb
|
|
177
163
|
- lib/tasks/redmine_with_git.rake
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
Redmine::Plugin.post_register :redmine_with_git do
|
|
4
|
-
# Source: https://github.com/esquilo-azul/redmine_nonproject_modules
|
|
5
|
-
requires_redmine_plugin(:redmine_nonproject_modules, version_or_higher: '0.3.1')
|
|
6
|
-
|
|
7
|
-
if Redmine::VERSION.to_s < '4'
|
|
8
|
-
# Source: https://github.com/jbox-web/redmine_bootstrap_kit.git
|
|
9
|
-
# Note: redmine_bootstrap_kit is a redmine_git_hosting's dependency.
|
|
10
|
-
requires_redmine_plugin(:redmine_bootstrap_kit, version_or_higher: '0.2.5')
|
|
11
|
-
# Source: https://github.com/jbox-web/redmine_git_hosting.git
|
|
12
|
-
requires_redmine_plugin(:redmine_git_hosting, version_or_higher: '1.2.3.1')
|
|
13
|
-
else
|
|
14
|
-
# Source: https://github.com/jbox-web/additionals
|
|
15
|
-
# Note: additionals is a redmine_git_hosting's dependency.
|
|
16
|
-
requires_redmine_plugin(:additionals, version_or_higher: '2.0.24')
|
|
17
|
-
# Source: https://github.com/jbox-web/redmine_git_hosting.git
|
|
18
|
-
requires_redmine_plugin(:redmine_git_hosting, version_or_higher: '4.0.1.1')
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Source: https://github.com/esquilo-azul/redmine_installer
|
|
22
|
-
if Redmine::Plugin.registered_plugins.keys.include?(:redmine_installer)
|
|
23
|
-
requires_redmine_plugin(:redmine_installer, version_or_higher: '0.21.0')
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RedmineGitHosting
|
|
4
|
-
module Cache
|
|
5
|
-
module DatabasePatch
|
|
6
|
-
def self.included(base)
|
|
7
|
-
base.prepend(InstanceMethods)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module InstanceMethods
|
|
11
|
-
def apply_cache_limit
|
|
12
|
-
return unless max_cache_elements >= 0 && GitCache.count > max_cache_elements
|
|
13
|
-
|
|
14
|
-
GitCache.order(created_at: :desc).last.destroy
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
patch = RedmineGitHosting::Cache::DatabasePatch
|
|
22
|
-
target = RedmineGitHosting::Cache::Database
|
|
23
|
-
target.send(:include, patch) unless target.include?(patch)
|