more_core_extensions 4.0.0 → 4.3.1
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/.codeclimate.yml +16 -0
- data/.rubocop.yml +3 -3
- data/.rubocop_cc.yml +4 -0
- data/.travis.yml +3 -9
- data/CHANGELOG.md +32 -1
- data/Gemfile +10 -2
- data/README.md +16 -0
- data/lib/more_core_extensions/all.rb +2 -0
- data/lib/more_core_extensions/core_ext/array/deletes.rb +11 -2
- data/lib/more_core_extensions/core_ext/array/tableize.rb +38 -3
- data/lib/more_core_extensions/core_ext/digest.rb +1 -0
- data/lib/more_core_extensions/core_ext/digest/uuid.rb +26 -0
- data/lib/more_core_extensions/core_ext/hash/deletes.rb +10 -0
- data/lib/more_core_extensions/core_ext/object.rb +1 -0
- data/lib/more_core_extensions/core_ext/object/deep_send.rb +28 -0
- data/lib/more_core_extensions/core_ext/process.rb +1 -0
- data/lib/more_core_extensions/core_ext/process/pause_resume.rb +110 -0
- data/lib/more_core_extensions/core_ext/shared/nested.rb +15 -0
- data/lib/more_core_extensions/core_ext/string.rb +1 -0
- data/lib/more_core_extensions/core_ext/string/to_i_with_method.rb +87 -0
- data/lib/more_core_extensions/version.rb +1 -1
- data/more_core_extensions.gemspec +2 -0
- metadata +42 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb3f91f72b2c1bc1462184ddab53609ba5b5b09f733eb78f0c34c89e7851f507
|
4
|
+
data.tar.gz: b78bda65aa6f835881b77e069cb1d010fb32dddf72d46c2b67187085a36f88f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 955082c21b2f443dcdd3d888d85e22086a80cb9cbe6cce425c2a8293d20550d52052cd67512cd31faa8333d5318d06ee240a5c33a3c8090f2d4cb56f1df636d1
|
7
|
+
data.tar.gz: 7e149a0ee4d1f68258a5a8d76d26d6f4a0b92ab8e39f496c6becc43cbb455e03e0091cf4530cc3ca5cd575d07ddd58761b5ad33944d0887316358e382498ae08
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
prepare:
|
2
|
+
fetch:
|
3
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_base.yml
|
4
|
+
path: ".rubocop_base.yml"
|
5
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_cc_base.yml
|
6
|
+
path: ".rubocop_cc_base.yml"
|
7
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/base.yml
|
8
|
+
path: styles/base.yml
|
9
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/cc_base.yml
|
10
|
+
path: styles/cc_base.yml
|
11
|
+
plugins:
|
12
|
+
rubocop:
|
13
|
+
enabled: true
|
14
|
+
config: ".rubocop_cc.yml"
|
15
|
+
channel: rubocop-0-82
|
16
|
+
version: '2'
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
inherit_from:
|
2
|
-
-
|
3
|
-
|
4
|
-
- .
|
2
|
+
- ".rubocop_local.yml"
|
3
|
+
inherit_gem:
|
4
|
+
manageiq-style: ".rubocop_base.yml"
|
data/.rubocop_cc.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,20 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- "2.
|
4
|
-
- "2.
|
5
|
-
- "2.2
|
6
|
-
- "2.3.8"
|
7
|
-
- "2.4.5"
|
8
|
-
- "2.5.3"
|
9
|
-
- "2.6.0"
|
3
|
+
- "2.5.8"
|
4
|
+
- "2.6.6"
|
5
|
+
- "2.7.2"
|
10
6
|
- ruby-head
|
11
7
|
- jruby-head
|
12
|
-
sudo: false
|
13
8
|
cache: bundler
|
14
9
|
after_script: bundle exec codeclimate-test-reporter
|
15
10
|
matrix:
|
16
11
|
allow_failures:
|
17
|
-
- rvm: "2.6.0"
|
18
12
|
- rvm: ruby-head
|
19
13
|
- rvm: jruby-head
|
20
14
|
fast_finish: true
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,31 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [4.3.1] - 2021-07-13
|
8
|
+
### Changed
|
9
|
+
- Fix String#to_i_with_method to raise the correct error on private methods [[#101](https://github.com/ManageIQ/more_core_extensions/pull/101)]
|
10
|
+
- Fix issue where Array#tableize would not honor a smaller colored field [[#102](https://github.com/ManageIQ/more_core_extensions/pull/102)]
|
11
|
+
|
12
|
+
## [4.3.0] - 2020-10-27
|
13
|
+
### Added
|
14
|
+
- Add String#to_i_with_method and friends [[#95](https://github.com/ManageIQ/more_core_extensions/pull/95)]
|
15
|
+
- Add Object#deep_send [[#94](https://github.com/ManageIQ/more_core_extensions/pull/94)]
|
16
|
+
|
17
|
+
## [4.2.0] - 2020-07-20
|
18
|
+
### Added
|
19
|
+
- Add bundler-inject allowing developers to override dependencies [[#89](https://github.com/ManageIQ/more_core_extensions/pull/89)]
|
20
|
+
- Add Array and Hash #deep_clone and #deep_delete [[#91](https://github.com/ManageIQ/more_core_extensions/pull/91)]
|
21
|
+
- Add Digest::UUID.clean to properly format UUID strings [[#81](https://github.com/ManageIQ/more_core_extensions/pull/81)]
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Update ArrayTableize to properly set field width for color text [[#87](https://github.com/ManageIQ/more_core_extensions/pull/87)]
|
25
|
+
- Change Array#format_table header output to markdown vs postgres [[#83](https://github.com/ManageIQ/more_core_extensions/pull/83)]
|
26
|
+
|
27
|
+
## [4.1.0] - 2020-04-30
|
28
|
+
### Added
|
29
|
+
- Added Ruby 2.7 support [[#79](https://github.com/ManageIQ/more_core_extensions/pull/79)]
|
30
|
+
- Added Process#pause, Process#resume, and Process#alive? [[#73](https://github.com/ManageIQ/more_core_extensions/pull/73)]
|
31
|
+
|
7
32
|
## [4.0.0] - 2020-01-31
|
8
33
|
### Changed
|
9
34
|
- **BREAKING**: Moved Object#descendant_get to Class#descendant_get [[#75](https://github.com/ManageIQ/more_core_extensions/pull/75)]
|
@@ -82,7 +107,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
82
107
|
- Upgraded to RSpec 3 [[#16](https://github.com/ManageIQ/more_core_extensions/pull/16)]
|
83
108
|
- Added the Change Log!
|
84
109
|
|
85
|
-
[Unreleased]: https://github.com/ManageIQ/more_core_extensions/compare/
|
110
|
+
[Unreleased]: https://github.com/ManageIQ/more_core_extensions/compare/v4.3.1...HEAD
|
111
|
+
[4.3.1]: https://github.com/ManageIQ/more_core_extensions/compare/v4.3.0...v4.3.1
|
112
|
+
[4.3.0]: https://github.com/ManageIQ/more_core_extensions/compare/v4.2.0...v4.3.0
|
113
|
+
[4.2.0]: https://github.com/ManageIQ/more_core_extensions/compare/v4.1.0...v4.2.0
|
114
|
+
[4.1.0]: https://github.com/ManageIQ/more_core_extensions/compare/v4.0.0...v4.1.0
|
115
|
+
[4.0.0]: https://github.com/ManageIQ/more_core_extensions/compare/v3.8.0...v4.0.0
|
116
|
+
[3.8.0]: https://github.com/ManageIQ/more_core_extensions/compare/v3.7.0...v3.8.0
|
86
117
|
[3.7.0]: https://github.com/ManageIQ/more_core_extensions/compare/v3.6.0...v3.7.0
|
87
118
|
[3.6.0]: https://github.com/ManageIQ/more_core_extensions/compare/v3.5.0...v3.6.0
|
88
119
|
[3.5.0]: https://github.com/ManageIQ/more_core_extensions/compare/v3.4.0...v3.5.0
|
data/Gemfile
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
plugin 'bundler-inject'
|
4
|
+
require File.join(Bundler::Plugin.index.load_paths("bundler-inject")[0], "bundler-inject") rescue nil
|
5
|
+
|
3
6
|
# Specify your gem's dependencies in more_core_extensions.gemspec
|
4
7
|
gemspec
|
5
8
|
|
6
|
-
#
|
7
|
-
|
9
|
+
# Rails 5 dropped support for Ruby < 2.2.2
|
10
|
+
# Rails 6 dropped support for Ruby < 2.4.4
|
11
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.2.2")
|
12
|
+
active_support_version = "< 5"
|
13
|
+
elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4.4")
|
14
|
+
active_support_version = "< 6"
|
15
|
+
end
|
8
16
|
gem 'activesupport', active_support_version
|
data/README.md
CHANGED
@@ -19,6 +19,7 @@ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveS
|
|
19
19
|
* core_ext/array/deletes.rb
|
20
20
|
* `#delete_blanks` - Deletes all items where the value is blank
|
21
21
|
* `#delete_nils` - Deletes all items where the value is nil
|
22
|
+
* `#deep_delete` - Deletes nested hash key elements
|
22
23
|
* core_ext/array/duplicates.rb
|
23
24
|
* `#duplicates` - Returns an Array of the duplicates found
|
24
25
|
* core_ext/array/element_counts.rb
|
@@ -61,6 +62,7 @@ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveS
|
|
61
62
|
* core_ext/hash/deletes.rb
|
62
63
|
* `#delete_blanks` - Deletes all keys where the value is blank
|
63
64
|
* `#delete_nils` - Deletes all keys where the value is nil
|
65
|
+
* `#deep_delete` - Deletes nested hash key elements
|
64
66
|
* core_ext/hash/nested.rb (see [Shared](#shared))
|
65
67
|
* `#delete_blank_paths` - Deletes all paths where the value is blank
|
66
68
|
* core_ext/hash/sorting.rb (see [Shared](#shared))
|
@@ -87,9 +89,18 @@ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveS
|
|
87
89
|
|
88
90
|
#### Object
|
89
91
|
|
92
|
+
* core_ext/module/deep_send.rb
|
93
|
+
* `#deep_send` - Invokes the specified methods continuously, unless encountering a nil value.
|
90
94
|
* core_ext/module/namespace.rb
|
91
95
|
* `#in_namespace?` - Returns whether or not the object is in the given namespace
|
92
96
|
|
97
|
+
#### Process
|
98
|
+
|
99
|
+
* core_ext/process/pause_resume.rb
|
100
|
+
* `.pause` - Pauses a process
|
101
|
+
* `.resume` - Resumes a paused process
|
102
|
+
* `.alive?` - Returns whether or not a process is running
|
103
|
+
|
93
104
|
#### Range
|
94
105
|
|
95
106
|
* core_ext/range/step_value.rb
|
@@ -113,6 +124,10 @@ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveS
|
|
113
124
|
* `#hex_dump` - Dumps the string in a hex editor style format
|
114
125
|
* core_ext/string/iec60027_2.rb
|
115
126
|
* `#iec_60027_2_to_i` - Convert strings with an IEC60027-2 suffix to an integer
|
127
|
+
* core_ext/string/to_i_with_method.rb
|
128
|
+
* `#to_f_with_method` - Converts to a Float while also evaluating a method invocation
|
129
|
+
* `#to_i_with_method` - Converts to an Integer while also evaluating a method invocation
|
130
|
+
* `#number_with_method?` - Determines if the object contains a number with a method invocation
|
116
131
|
|
117
132
|
#### Symbol
|
118
133
|
|
@@ -122,6 +137,7 @@ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveS
|
|
122
137
|
#### Shared
|
123
138
|
|
124
139
|
* core_ext/shared/nested.rb
|
140
|
+
* `#deep_clone` - Performs a Marshal based deep clone
|
125
141
|
* `#delete_path` - Delete the value at the specified nesting
|
126
142
|
* `#fetch_path` - Fetch the value at the specified nesting
|
127
143
|
* `#find_path` - Detect which nesting holds the specified value
|
@@ -3,11 +3,13 @@ require 'more_core_extensions/version'
|
|
3
3
|
require 'more_core_extensions/core_ext/array'
|
4
4
|
require 'more_core_extensions/core_ext/benchmark'
|
5
5
|
require 'more_core_extensions/core_ext/class'
|
6
|
+
require 'more_core_extensions/core_ext/digest'
|
6
7
|
require 'more_core_extensions/core_ext/hash'
|
7
8
|
require 'more_core_extensions/core_ext/math'
|
8
9
|
require 'more_core_extensions/core_ext/module'
|
9
10
|
require 'more_core_extensions/core_ext/numeric'
|
10
11
|
require 'more_core_extensions/core_ext/object'
|
12
|
+
require 'more_core_extensions/core_ext/process'
|
11
13
|
require 'more_core_extensions/core_ext/range'
|
12
14
|
require 'more_core_extensions/core_ext/string'
|
13
15
|
require 'more_core_extensions/core_ext/symbol'
|
@@ -6,14 +6,23 @@ module MoreCoreExtensions
|
|
6
6
|
#
|
7
7
|
# [1, [], nil].delete_nils # => [1, []]
|
8
8
|
def delete_nils
|
9
|
-
delete_if
|
9
|
+
delete_if(&:nil?)
|
10
10
|
end
|
11
11
|
|
12
12
|
# Deletes all items where the value is blank
|
13
13
|
#
|
14
14
|
# [1, [], nil].delete_blanks # => [1]
|
15
15
|
def delete_blanks
|
16
|
-
delete_if
|
16
|
+
delete_if(&:blank?)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Deletes all keys and subkeys that match +key+.
|
20
|
+
#
|
21
|
+
# [{:a => {:b => 2, :c => 3}}].deep_delete(:b) # => [{:a => {:c => 3}}]
|
22
|
+
#
|
23
|
+
def deep_delete(key)
|
24
|
+
each { |i| i.deep_delete(key) if i.respond_to?(:deep_delete) }
|
25
|
+
self
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
@@ -53,6 +53,9 @@ module MoreCoreExtensions
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
+
ANSI_ESCAPE_SEQUENCE = /\e\[[^m]+m/.freeze
|
57
|
+
ANSI_RESET = "\e[0m".freeze
|
58
|
+
|
56
59
|
def tableize_hashes
|
57
60
|
# Convert the target to an Array of Arrays
|
58
61
|
keys = options[:columns] || columns_from_hash_keys
|
@@ -102,7 +105,7 @@ module MoreCoreExtensions
|
|
102
105
|
end
|
103
106
|
|
104
107
|
def apply_width!(widths, field, field_i)
|
105
|
-
widths[field_i] = [widths[field_i].to_i, field.to_s.length].max
|
108
|
+
widths[field_i] = [widths[field_i].to_i, ansi_strip(field.to_s).length].max
|
106
109
|
widths[field_i] = [options[:max_width], widths[field_i].to_i].min if options[:max_width]
|
107
110
|
end
|
108
111
|
|
@@ -118,13 +121,45 @@ module MoreCoreExtensions
|
|
118
121
|
end
|
119
122
|
|
120
123
|
def format_field(field, width, justification)
|
121
|
-
field = field.to_s.gsub(/\n|\r/, '')
|
124
|
+
field = field.to_s.gsub(/\n|\r/, '')
|
125
|
+
field = ansi_truncate(field, width)
|
126
|
+
width += ansi_escapes(field).sum { |f| f.to_s.size }
|
122
127
|
"%0#{justification}#{width}s" % field
|
123
128
|
end
|
124
129
|
|
130
|
+
def ansi_escapes?(field)
|
131
|
+
!!field.match(ANSI_ESCAPE_SEQUENCE)
|
132
|
+
end
|
133
|
+
|
134
|
+
def ansi_escapes(field)
|
135
|
+
field.to_enum(:scan, ANSI_ESCAPE_SEQUENCE).map { Regexp.last_match }
|
136
|
+
end
|
137
|
+
|
138
|
+
def ansi_strip(field)
|
139
|
+
field.gsub(ANSI_ESCAPE_SEQUENCE, '')
|
140
|
+
end
|
141
|
+
|
142
|
+
def ansi_truncate(field, width)
|
143
|
+
escapes = ansi_escapes(field)
|
144
|
+
if escapes.none?
|
145
|
+
field.slice(0, width)
|
146
|
+
else
|
147
|
+
escape_widths = 0
|
148
|
+
escapes.each do |e|
|
149
|
+
break if e.offset(0).first - escape_widths >= width
|
150
|
+
|
151
|
+
escape_widths += e[0].size
|
152
|
+
end
|
153
|
+
|
154
|
+
field = field.slice(0, width + escape_widths)
|
155
|
+
field << ANSI_RESET if ansi_escapes?(field) && !field.end_with?(ANSI_RESET)
|
156
|
+
field
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
125
160
|
def format_table(table, widths)
|
126
161
|
if options[:header] && table.size > 1
|
127
|
-
header_separator = widths.collect { |w| "-" * (w + 2) }.join("
|
162
|
+
header_separator = widths.collect { |w| "-" * (w + 2) }.join("|")
|
128
163
|
table.insert(1, header_separator)
|
129
164
|
end
|
130
165
|
table.join("\n") << "\n"
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'more_core_extensions/core_ext/digest/uuid'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/core_ext/digest/uuid'
|
2
|
+
|
3
|
+
module Digest
|
4
|
+
module UUID
|
5
|
+
UUID_REGEX_FORMAT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.freeze
|
6
|
+
|
7
|
+
# Takes a UUID string of varying formats and cleans it. It will strip invalid characters,
|
8
|
+
# such as leading and trailing brackets as well as whitespace. The result is a lowercased,
|
9
|
+
# canonical UUID string.
|
10
|
+
#
|
11
|
+
# If the +guid+ argument is nil or blank, then nil is returned. If the +guid+ is already
|
12
|
+
# clean, then no additional cleaning occurs, and it is returned as-is.
|
13
|
+
#
|
14
|
+
# @param guid [String] A string that should more or less represent a UUID.
|
15
|
+
# @return [String] A lowercase v4 UUID string stripped of any extraneous characters.
|
16
|
+
#
|
17
|
+
def self.clean(guid)
|
18
|
+
return nil if guid.nil?
|
19
|
+
g = guid.to_s.downcase
|
20
|
+
return nil if g.strip.empty?
|
21
|
+
return g if g.length == 36 && g =~ UUID_REGEX_FORMAT
|
22
|
+
g.delete!('^0-9a-f')
|
23
|
+
g.sub!(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/, '\1-\2-\3-\4-\5')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -15,6 +15,16 @@ module MoreCoreExtensions
|
|
15
15
|
def delete_blanks
|
16
16
|
delete_if { |k, v| v.blank? }
|
17
17
|
end
|
18
|
+
|
19
|
+
# Deletes all keys and subkeys that match +key+.
|
20
|
+
#
|
21
|
+
# {:a => {:b => 2, :c => 3}}.deep_delete(:b) # => {:a => {:c => 3}}
|
22
|
+
#
|
23
|
+
def deep_delete(key)
|
24
|
+
key = [key] unless key.kind_of?(Array)
|
25
|
+
key.each { |k| delete(k) }
|
26
|
+
each_value { |v| v.deep_delete(key) if v.respond_to?(:deep_delete) }
|
27
|
+
end
|
18
28
|
end
|
19
29
|
end
|
20
30
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MoreCoreExtensions
|
2
|
+
module ObjectDeepSend
|
3
|
+
#
|
4
|
+
# Invokes the specified methods continuously, unless encountering a nil value.
|
5
|
+
#
|
6
|
+
# 10.deep_send("to_s.length") # => 2
|
7
|
+
# 10.deep_send("to_s", "length") # => 2
|
8
|
+
# 10.deep_send(:to_s, :length) # => 2
|
9
|
+
# 10.deep_send(["to_s", "length"]) # => 2
|
10
|
+
# [].deep_send("first.length") # => nil
|
11
|
+
#
|
12
|
+
def deep_send(*args)
|
13
|
+
args = args.first.dup if args.length == 1 && args.first.kind_of?(Array)
|
14
|
+
args = args.shift.to_s.strip.split('.') + args
|
15
|
+
|
16
|
+
arg = args.shift
|
17
|
+
raise ArgumentError if arg.nil?
|
18
|
+
|
19
|
+
result = send(arg)
|
20
|
+
return nil if result.nil?
|
21
|
+
return result if args.empty?
|
22
|
+
|
23
|
+
result.deep_send(args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Object.send(:include, MoreCoreExtensions::ObjectDeepSend)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'more_core_extensions/core_ext/process/pause_resume'
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module MoreCoreExtensions
|
2
|
+
module ProcessPauseResume
|
3
|
+
if Gem.win_platform?
|
4
|
+
require 'fiddle'
|
5
|
+
ntdll = Fiddle.dlopen('ntdll')
|
6
|
+
kernel32 = Fiddle.dlopen('kernel32')
|
7
|
+
|
8
|
+
NtSuspendProcess = Fiddle::Function.new(
|
9
|
+
ntdll['NtSuspendProcess'],
|
10
|
+
[Fiddle::TYPE_UINTPTR_T],
|
11
|
+
Fiddle::TYPE_INT
|
12
|
+
)
|
13
|
+
|
14
|
+
private_constant :NtSuspendProcess
|
15
|
+
|
16
|
+
NtResumeProcess = Fiddle::Function.new(
|
17
|
+
ntdll['NtResumeProcess'],
|
18
|
+
[Fiddle::TYPE_UINTPTR_T],
|
19
|
+
Fiddle::TYPE_INT
|
20
|
+
)
|
21
|
+
|
22
|
+
private_constant :NtResumeProcess
|
23
|
+
|
24
|
+
OpenProcess = Fiddle::Function.new(
|
25
|
+
kernel32['OpenProcess'],
|
26
|
+
[Fiddle::TYPE_LONG, Fiddle::TYPE_INT, Fiddle::TYPE_LONG],
|
27
|
+
Fiddle::TYPE_UINTPTR_T
|
28
|
+
)
|
29
|
+
|
30
|
+
private_constant :OpenProcess
|
31
|
+
|
32
|
+
CloseHandle = Fiddle::Function.new(
|
33
|
+
kernel32['CloseHandle'],
|
34
|
+
[Fiddle::TYPE_UINTPTR_T],
|
35
|
+
Fiddle::TYPE_INT
|
36
|
+
)
|
37
|
+
|
38
|
+
private_constant :CloseHandle
|
39
|
+
|
40
|
+
PROCESS_SUSPEND_RESUME = 0x00000800
|
41
|
+
|
42
|
+
private_constant :PROCESS_SUSPEND_RESUME
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns whether or not the given process is running.
|
46
|
+
#
|
47
|
+
def alive?(pid)
|
48
|
+
Process.kill(0, pid)
|
49
|
+
true
|
50
|
+
rescue Errno::ESRCH
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
# Suspend the process +pid+. If the process isn't running then this is no-op.
|
55
|
+
#
|
56
|
+
if Gem.win_platform?
|
57
|
+
def pause(pid)
|
58
|
+
return unless alive?(pid)
|
59
|
+
|
60
|
+
begin
|
61
|
+
handle = OpenProcess.call(PROCESS_SUSPEND_RESUME, 0, pid)
|
62
|
+
|
63
|
+
if handle == 0
|
64
|
+
raise SystemCallError, Fiddle.win32_last_error, "OpenProcess"
|
65
|
+
end
|
66
|
+
|
67
|
+
if NtSuspendProcess.call(handle) != 0
|
68
|
+
raise SystemCallError, Fiddle.win32_last_error, "NtSuspendProcess"
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
CloseHandle.call(handle) if handle
|
72
|
+
end
|
73
|
+
1 # For cross-platform compatibility
|
74
|
+
end
|
75
|
+
else
|
76
|
+
def pause(pid)
|
77
|
+
Process.kill('STOP', pid) if alive?(pid)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Resume the process +pid+. If the process isn't running then this is a no-op.
|
82
|
+
#
|
83
|
+
if Gem.win_platform?
|
84
|
+
def resume(pid)
|
85
|
+
return unless alive?(pid)
|
86
|
+
|
87
|
+
begin
|
88
|
+
handle = OpenProcess.call(PROCESS_SUSPEND_RESUME, 0, pid)
|
89
|
+
|
90
|
+
if handle == 0
|
91
|
+
raise SystemCallError, Fiddle.win32_last_error, "OpenProcess"
|
92
|
+
end
|
93
|
+
|
94
|
+
if NtResumeProcess.call(handle) != 0
|
95
|
+
raise SystemCallError, Fiddle.win32_last_error, "NtResumeProcess"
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
CloseHandle.call(handle) if handle
|
99
|
+
end
|
100
|
+
1 # For cross-platform compatibility
|
101
|
+
end
|
102
|
+
else
|
103
|
+
def resume(pid)
|
104
|
+
Process.kill('CONT', pid) if alive?(pid)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
Process.send(:extend, MoreCoreExtensions::ProcessPauseResume)
|
@@ -100,6 +100,21 @@ module MoreCoreExtensions
|
|
100
100
|
end
|
101
101
|
[]
|
102
102
|
end
|
103
|
+
|
104
|
+
# Create a deep clone of the object. This is similar to deep_dup
|
105
|
+
# but uses a Marshal based approach instead.
|
106
|
+
#
|
107
|
+
# h1 = {:a => "hello"}
|
108
|
+
# h2 = h1.deep_clone
|
109
|
+
#
|
110
|
+
# h1[:a] << " world"
|
111
|
+
#
|
112
|
+
# h1[:a] # "hello world"
|
113
|
+
# h2[:a] # "hello"
|
114
|
+
#
|
115
|
+
def deep_clone
|
116
|
+
Marshal.load(Marshal.dump(self))
|
117
|
+
end
|
103
118
|
end
|
104
119
|
end
|
105
120
|
end
|
@@ -2,3 +2,4 @@ require 'more_core_extensions/core_ext/string/formats'
|
|
2
2
|
require 'more_core_extensions/core_ext/string/hex_dump'
|
3
3
|
require 'more_core_extensions/core_ext/string/iec60027_2'
|
4
4
|
require 'more_core_extensions/core_ext/string/decimal_suffix'
|
5
|
+
require 'more_core_extensions/core_ext/string/to_i_with_method'
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module MoreCoreExtensions
|
2
|
+
module StringToIWithMethod
|
3
|
+
NUMBER_WITH_METHOD_REGEX = /^([0-9\.,]+)\.([a-z]+)$/.freeze
|
4
|
+
|
5
|
+
# Converts to an Integer while also evaluating a method invocation
|
6
|
+
#
|
7
|
+
# This method is similar to #to_i, but does not support extraneous characters
|
8
|
+
# nor bases other than 10.
|
9
|
+
#
|
10
|
+
# "20".to_i_with_method # => 20
|
11
|
+
# "20.percent".to_i_with_method # => 20
|
12
|
+
# "20.megabytes".to_i_with_method # => 20_971_520
|
13
|
+
#
|
14
|
+
# "20.0".to_i_with_method # => 20
|
15
|
+
# "20.0.percent".to_i_with_method # => 20
|
16
|
+
# "20.0.megabytes".to_i_with_method # => 20_971_520
|
17
|
+
#
|
18
|
+
# 20.to_i_with_method # => 20
|
19
|
+
# 20.0.to_i_with_method # => 20
|
20
|
+
# nil.to_i_with_method # => 0
|
21
|
+
#
|
22
|
+
def to_i_with_method
|
23
|
+
to_x_with_method.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
# Converts to a Float while also evaluating a method invocation
|
27
|
+
#
|
28
|
+
# This method is similar to #to_f, but does not support extraneous characters.
|
29
|
+
#
|
30
|
+
# "20".to_f_with_method # => 20.0
|
31
|
+
# "20.percent".to_f_with_method # => 20.0
|
32
|
+
# "20.megabytes".to_f_with_method # => 20_971_520.0
|
33
|
+
#
|
34
|
+
# "20.1".to_f_with_method # => 20.1
|
35
|
+
# "20.1.percent".to_f_with_method # => 20.1
|
36
|
+
# "20.1.megabytes".to_f_with_method # => 21_076_377.6
|
37
|
+
#
|
38
|
+
# 20.to_f_with_method # => 20.0
|
39
|
+
# 20.1.to_f_with_method # => 20.1
|
40
|
+
# nil.to_f_with_method # => 0.0
|
41
|
+
#
|
42
|
+
def to_f_with_method
|
43
|
+
to_x_with_method.to_f
|
44
|
+
end
|
45
|
+
|
46
|
+
private def to_x_with_method
|
47
|
+
n = delete(',')
|
48
|
+
return n unless n =~ NUMBER_WITH_METHOD_REGEX && $2 != "percent"
|
49
|
+
|
50
|
+
n = $1.include?('.') ? $1.to_f : $1.to_i
|
51
|
+
n.public_send($2)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Determines if the object contains a number with a method invocation
|
55
|
+
#
|
56
|
+
# "20".number_with_method? # => false
|
57
|
+
# "20.percent".number_with_method? # => true
|
58
|
+
# "20.0.percent".number_with_method? # => true
|
59
|
+
def number_with_method?
|
60
|
+
self =~ NUMBER_WITH_METHOD_REGEX
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module NumericAndNilToIWithMethod
|
65
|
+
# See String#to_i_with_method
|
66
|
+
def to_i_with_method
|
67
|
+
to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
# See String#to_f_with_method
|
71
|
+
def to_f_with_method
|
72
|
+
to_f
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module ObjectToIWithMethod
|
77
|
+
# See String#number_with_method?
|
78
|
+
def number_with_method?
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
String.send(:prepend, MoreCoreExtensions::StringToIWithMethod)
|
85
|
+
Numeric.send(:prepend, MoreCoreExtensions::NumericAndNilToIWithMethod)
|
86
|
+
NilClass.send(:prepend, MoreCoreExtensions::NumericAndNilToIWithMethod)
|
87
|
+
Object.send(:prepend, MoreCoreExtensions::ObjectToIWithMethod)
|
@@ -24,10 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler"
|
26
26
|
spec.add_development_dependency "codeclimate-test-reporter"
|
27
|
+
spec.add_development_dependency "manageiq-style"
|
27
28
|
spec.add_development_dependency "rake"
|
28
29
|
spec.add_development_dependency "rspec", ">= 3.0"
|
29
30
|
spec.add_development_dependency "simplecov"
|
30
31
|
spec.add_development_dependency "timecop"
|
31
32
|
|
32
33
|
spec.add_runtime_dependency "activesupport"
|
34
|
+
spec.add_runtime_dependency "sync"
|
33
35
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: more_core_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Frey
|
8
8
|
- Brandon Dunne
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: manageiq-style
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: rake
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,6 +123,20 @@ dependencies:
|
|
109
123
|
- - ">="
|
110
124
|
- !ruby/object:Gem::Version
|
111
125
|
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sync
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :runtime
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
112
140
|
description: MoreCoreExtensions are a set of core extensions beyond those provided
|
113
141
|
by ActiveSupport.
|
114
142
|
email:
|
@@ -118,9 +146,11 @@ executables: []
|
|
118
146
|
extensions: []
|
119
147
|
extra_rdoc_files: []
|
120
148
|
files:
|
149
|
+
- ".codeclimate.yml"
|
121
150
|
- ".gitignore"
|
122
151
|
- ".rspec"
|
123
152
|
- ".rubocop.yml"
|
153
|
+
- ".rubocop_cc.yml"
|
124
154
|
- ".rubocop_local.yml"
|
125
155
|
- ".travis.yml"
|
126
156
|
- CHANGELOG.md
|
@@ -148,6 +178,8 @@ files:
|
|
148
178
|
- lib/more_core_extensions/core_ext/benchmark/realtime_store.rb
|
149
179
|
- lib/more_core_extensions/core_ext/class.rb
|
150
180
|
- lib/more_core_extensions/core_ext/class/hierarchy.rb
|
181
|
+
- lib/more_core_extensions/core_ext/digest.rb
|
182
|
+
- lib/more_core_extensions/core_ext/digest/uuid.rb
|
151
183
|
- lib/more_core_extensions/core_ext/hash.rb
|
152
184
|
- lib/more_core_extensions/core_ext/hash/deletes.rb
|
153
185
|
- lib/more_core_extensions/core_ext/hash/nested.rb
|
@@ -162,7 +194,10 @@ files:
|
|
162
194
|
- lib/more_core_extensions/core_ext/numeric/math.rb
|
163
195
|
- lib/more_core_extensions/core_ext/numeric/rounding.rb
|
164
196
|
- lib/more_core_extensions/core_ext/object.rb
|
197
|
+
- lib/more_core_extensions/core_ext/object/deep_send.rb
|
165
198
|
- lib/more_core_extensions/core_ext/object/namespace.rb
|
199
|
+
- lib/more_core_extensions/core_ext/process.rb
|
200
|
+
- lib/more_core_extensions/core_ext/process/pause_resume.rb
|
166
201
|
- lib/more_core_extensions/core_ext/range.rb
|
167
202
|
- lib/more_core_extensions/core_ext/range/step_value.rb
|
168
203
|
- lib/more_core_extensions/core_ext/shared/nested.rb
|
@@ -171,6 +206,7 @@ files:
|
|
171
206
|
- lib/more_core_extensions/core_ext/string/formats.rb
|
172
207
|
- lib/more_core_extensions/core_ext/string/hex_dump.rb
|
173
208
|
- lib/more_core_extensions/core_ext/string/iec60027_2.rb
|
209
|
+
- lib/more_core_extensions/core_ext/string/to_i_with_method.rb
|
174
210
|
- lib/more_core_extensions/core_ext/symbol.rb
|
175
211
|
- lib/more_core_extensions/core_ext/symbol/to_i.rb
|
176
212
|
- lib/more_core_extensions/version.rb
|
@@ -179,7 +215,7 @@ homepage: http://github.com/ManageIQ/more_core_extensions
|
|
179
215
|
licenses:
|
180
216
|
- MIT
|
181
217
|
metadata: {}
|
182
|
-
post_install_message:
|
218
|
+
post_install_message:
|
183
219
|
rdoc_options: []
|
184
220
|
require_paths:
|
185
221
|
- lib
|
@@ -194,8 +230,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
230
|
- !ruby/object:Gem::Version
|
195
231
|
version: '0'
|
196
232
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
198
|
-
signing_key:
|
233
|
+
rubygems_version: 3.1.4
|
234
|
+
signing_key:
|
199
235
|
specification_version: 4
|
200
236
|
summary: MoreCoreExtensions are a set of core extensions beyond those provided by
|
201
237
|
ActiveSupport.
|