sugar_utils 0.4.2 → 0.4.3
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/.gitignore +1 -0
- data/.rspec +0 -1
- data/.rubocop.yml +3 -7
- data/.travis.yml +10 -2
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/Rakefile +3 -2
- data/lib/sugar_utils.rb +2 -1
- data/lib/sugar_utils/file.rb +43 -17
- data/lib/sugar_utils/version.rb +3 -2
- data/spec/spec_helper.rb +12 -1
- data/spec/sugar_utils/file_spec.rb +18 -9
- data/spec/sugar_utils_spec.rb +2 -1
- data/sugar_utils.gemspec +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36772577f62b9ff9bf97a43c288103e1b653f580
|
4
|
+
data.tar.gz: '089ef8678c5b4bd1c3dd82bd2c31dd5a9cde3f72'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27010891b94741f46f21632a5b335115d65534745bf374a3a9d78d9c8125a2b355d0b8b8d5dd9cca2ee9eaf6fcab75f11d7efa73bd332ea6a85aae7dddd4aba4
|
7
|
+
data.tar.gz: 694e4ffec92625ef4154ab9cbfb71ed795c7816ecd090e09f866608a358911dee1c69d98fbdb66aa2f17fd2be6c08f6a1acc0dbb34d6cdd56c4cdf84db4099c6
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
@@ -2,13 +2,9 @@ Documentation:
|
|
2
2
|
Enabled: false
|
3
3
|
|
4
4
|
Metrics/LineLength:
|
5
|
-
Max:
|
6
|
-
|
7
|
-
|
8
|
-
Max: 20
|
9
|
-
|
10
|
-
Metrics/AbcSize:
|
11
|
-
Max: 19
|
5
|
+
Max: 150
|
6
|
+
Include:
|
7
|
+
- 'spec/**/*'
|
12
8
|
|
13
9
|
# Because of the way that blocks are used in RSpecs can end up being long when
|
14
10
|
# example groups are nested or many examples are checked.
|
data/.travis.yml
CHANGED
@@ -3,12 +3,20 @@ rvm:
|
|
3
3
|
- 2.0
|
4
4
|
- 2.1
|
5
5
|
- 2.2
|
6
|
-
- 2.3
|
7
|
-
- 2.4
|
6
|
+
- 2.3
|
7
|
+
- 2.4
|
8
8
|
- ruby-head
|
9
9
|
matrix:
|
10
10
|
allow_failures:
|
11
11
|
- rvm: ruby-head
|
12
|
+
exclude:
|
13
|
+
- rvm: 2.4
|
14
|
+
os: osx
|
15
|
+
- rvm: ruby-head
|
16
|
+
os: osx
|
17
|
+
os:
|
18
|
+
- linux
|
19
|
+
- osx
|
12
20
|
sudo: false
|
13
21
|
addons:
|
14
22
|
code_climate:
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
|
5
|
+
## [0.4.3] - 2017-08-25
|
6
|
+
### Added
|
7
|
+
- option to scrub character encoding in SugarUtils::File.read
|
8
|
+
- option to set mtime in SugarUtils::File.touch
|
9
|
+
|
5
10
|
## [0.4.2] - 2017-08-01
|
6
11
|
### Changed
|
7
12
|
- default file creation permissions from 666 to 644.
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'bundler/gem_tasks'
|
4
5
|
require 'rspec/core/rake_task'
|
@@ -25,4 +26,4 @@ end
|
|
25
26
|
|
26
27
|
task quality: %i[rubocop yardstick_measure]
|
27
28
|
|
28
|
-
task default: [
|
29
|
+
task default: %i[spec]
|
data/lib/sugar_utils.rb
CHANGED
data/lib/sugar_utils/file.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding : utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'solid_assert'
|
4
5
|
require 'fileutils'
|
@@ -39,17 +40,40 @@ module SugarUtils
|
|
39
40
|
# @option options [Boolean] :raise_on_missing (true)
|
40
41
|
# @option options [String] :value_on_missing ('') which specifies the
|
41
42
|
# value to return if the file is missing and raise_on_missing is false
|
43
|
+
# @option options [Boolean, String] :scrub_encoding scrub incorrectly
|
44
|
+
# encoded characters with this value, or with '' if the value is true
|
42
45
|
#
|
43
46
|
# @raise [SugarUtils::File::Error]
|
44
47
|
#
|
45
48
|
# @return [String]
|
46
|
-
def self.read(filename, options = {})
|
49
|
+
def self.read(filename, options = {}) # rubocop:disable MethodLength, AbcSize, CyclomaticComplexity, PerceivedComplexity
|
47
50
|
options[:value_on_missing] ||= ''
|
48
51
|
options[:raise_on_missing] = true if options[:raise_on_missing].nil?
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
+
result =
|
54
|
+
::File.open(filename, ::File::RDONLY) do |file|
|
55
|
+
flock_shared(file, options)
|
56
|
+
file.read
|
57
|
+
end
|
58
|
+
|
59
|
+
return result unless options[:scrub_encoding]
|
60
|
+
|
61
|
+
replacement_character =
|
62
|
+
if options[:scrub_encoding].is_a?(String)
|
63
|
+
options[:scrub_encoding]
|
64
|
+
else
|
65
|
+
''
|
66
|
+
end
|
67
|
+
if result.respond_to?(:scrub)
|
68
|
+
result.scrub(replacement_character)
|
69
|
+
else
|
70
|
+
result.encode(
|
71
|
+
result.encoding,
|
72
|
+
'binary',
|
73
|
+
invalid: :replace,
|
74
|
+
undef: :replace,
|
75
|
+
replace: replacement_character
|
76
|
+
)
|
53
77
|
end
|
54
78
|
rescue SystemCallError, IOError
|
55
79
|
raise(Error, "Cannot read #{filename}") if options[:raise_on_missing]
|
@@ -79,17 +103,19 @@ module SugarUtils
|
|
79
103
|
# @option options [String, Integer] :group
|
80
104
|
# @option options [Integer] :mode
|
81
105
|
# @option options [Integer] :perm @deprecated
|
106
|
+
# @option options [Integer] :mtime
|
82
107
|
#
|
83
108
|
# @return [void]
|
84
109
|
def self.touch(filename, options = {})
|
85
|
-
owner
|
86
|
-
group
|
87
|
-
mode
|
110
|
+
owner = options[:owner]
|
111
|
+
group = options[:group]
|
112
|
+
mode = options[:mode] || options[:perm]
|
113
|
+
touch_options = options.select { |k| %i[mtime].include?(k) }
|
88
114
|
|
89
|
-
deprecate_option(:touch, :perm, :mode, 2017, 8) if options.
|
115
|
+
deprecate_option(:touch, :perm, :mode, 2017, 8) if options.key?(:perm)
|
90
116
|
|
91
117
|
FileUtils.mkdir_p(::File.dirname(filename))
|
92
|
-
FileUtils.touch(filename)
|
118
|
+
FileUtils.touch(filename, touch_options)
|
93
119
|
FileUtils.chown(owner, group, filename)
|
94
120
|
FileUtils.chmod(mode, filename) if mode
|
95
121
|
end
|
@@ -107,13 +133,13 @@ module SugarUtils
|
|
107
133
|
# @raise [SugarUtils::File::Error]
|
108
134
|
#
|
109
135
|
# @return [void]
|
110
|
-
def self.write(filename, data, options = {})
|
136
|
+
def self.write(filename, data, options = {}) # rubocop:disable MethodLength, AbcSize, CyclomaticComplexity
|
111
137
|
flush = options[:flush] || false
|
112
138
|
owner = options[:owner]
|
113
139
|
group = options[:group]
|
114
140
|
mode = options[:mode] || options[:perm] || 0o644
|
115
141
|
|
116
|
-
deprecate_option(:touch, :perm, :mode, 2017, 8) if options.
|
142
|
+
deprecate_option(:touch, :perm, :mode, 2017, 8) if options.key?(:perm)
|
117
143
|
|
118
144
|
FileUtils.mkdir_p(::File.dirname(filename))
|
119
145
|
::File.open(filename, ::File::RDWR | ::File::CREAT, mode) do |file|
|
@@ -160,23 +186,23 @@ module SugarUtils
|
|
160
186
|
# Following the same pattern as the existing stdlib method deprecation
|
161
187
|
# module.
|
162
188
|
# @see http://ruby-doc.org/stdlib-2.0.0/libdoc/rubygems/rdoc/Gem/Deprecate.html
|
163
|
-
def self.deprecate_option(_method, option_name, option_repl, year, month)
|
189
|
+
def self.deprecate_option(_method, option_name, option_repl, year, month) # rubocop:disable MethodLength, AbcSize
|
164
190
|
return if Gem::Deprecate.skip
|
165
191
|
|
166
|
-
klass =
|
192
|
+
klass = is_a?(Module)
|
167
193
|
target = klass ? "#{self}." : "#{self.class}#"
|
168
194
|
|
169
195
|
# Determine the method
|
170
|
-
method = caller_locations(1,1).first.label
|
196
|
+
method = caller_locations(1, 1).first.label
|
171
197
|
|
172
198
|
# Determine the caller
|
173
|
-
external_caller = caller_locations(2,1).first
|
199
|
+
external_caller = caller_locations(2, 1).first
|
174
200
|
location_of_external_caller = "#{external_caller.absolute_path}:#{external_caller.lineno}"
|
175
201
|
|
176
202
|
msg = [
|
177
203
|
"NOTE: #{target}#{method} option :#{option_name} is deprecated",
|
178
204
|
option_repl == :none ? ' with no replacement' : "; use :#{option_repl} instead",
|
179
|
-
|
205
|
+
format('. It will be removed on or after %4d-%02d-01.', year, month),
|
180
206
|
"\n#{target}#{method} called from #{location_of_external_caller}"
|
181
207
|
]
|
182
208
|
warn("#{msg.join}.")
|
data/lib/sugar_utils/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding : utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
4
5
|
require 'sugar_utils'
|
@@ -72,3 +73,13 @@ RSpec::Matchers.define :have_group do |expected|
|
|
72
73
|
values_match?(@expected, @actual)
|
73
74
|
end
|
74
75
|
end
|
76
|
+
|
77
|
+
RSpec::Matchers.define :have_mtime do |expected|
|
78
|
+
match do |actual|
|
79
|
+
next false unless File.exist?(actual)
|
80
|
+
|
81
|
+
@actual = File.stat(actual).mtime
|
82
|
+
@expected = expected
|
83
|
+
values_match?(@expected, @actual)
|
84
|
+
end
|
85
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding : utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'spec_helper'
|
4
5
|
|
@@ -35,7 +36,6 @@ describe SugarUtils::File do
|
|
35
36
|
subject { described_class.read('filename', options) }
|
36
37
|
|
37
38
|
shared_examples_for 'handles the missing file error' do
|
38
|
-
# rubocop:disable Metrics/LineLength
|
39
39
|
inputs :options
|
40
40
|
raise_error_with Hash[], described_class::Error
|
41
41
|
raise_error_with Hash[], 'Cannot read filename'
|
@@ -43,7 +43,6 @@ describe SugarUtils::File do
|
|
43
43
|
raise_error_with Hash[raise_on_missing: true], 'Cannot read filename'
|
44
44
|
it_with Hash[raise_on_missing: false], ''
|
45
45
|
it_with Hash[raise_on_missing: false, value_on_missing: 'hi'], 'hi'
|
46
|
-
# rubocop:enable all
|
47
46
|
end
|
48
47
|
|
49
48
|
context 'missing file' do
|
@@ -56,10 +55,10 @@ describe SugarUtils::File do
|
|
56
55
|
end
|
57
56
|
|
58
57
|
context 'file present' do
|
59
|
-
|
60
|
-
before { write('filename', 'content') }
|
58
|
+
before { write('filename', "foo\x92bar") }
|
61
59
|
|
62
60
|
context 'and locked' do
|
61
|
+
let(:options) { { key: :value } }
|
63
62
|
before do
|
64
63
|
expect(described_class).to receive(:flock_shared)
|
65
64
|
.with(kind_of(File), options)
|
@@ -69,11 +68,19 @@ describe SugarUtils::File do
|
|
69
68
|
end
|
70
69
|
|
71
70
|
context 'and unlocked' do
|
71
|
+
let(:options) { { key: :value, scrub_encoding: scrub_encoding } }
|
72
72
|
before do
|
73
73
|
expect(described_class).to receive(:flock_shared)
|
74
74
|
.with(kind_of(File), options)
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
|
+
inputs :scrub_encoding
|
78
|
+
it_with nil, "foo\x92bar"
|
79
|
+
it_with false, "foo\x92bar"
|
80
|
+
it_with true, 'foobar'
|
81
|
+
it_with '', 'foobar'
|
82
|
+
it_with 'x', 'fooxbar'
|
83
|
+
it_with 'xxx', 'fooxxxbar'
|
77
84
|
end
|
78
85
|
end
|
79
86
|
end
|
@@ -104,16 +111,18 @@ describe SugarUtils::File do
|
|
104
111
|
|
105
112
|
before { subject }
|
106
113
|
|
107
|
-
inputs :options
|
114
|
+
inputs :options # rubocop:disable ExtraSpacing, SpaceBeforeFirstArg
|
108
115
|
specify_with([]) { expect(File.exist?(filename)).to eq(true) }
|
109
116
|
specify_with([{ owner: 'nobody' }]) { expect(filename).to have_owner('nobody') }
|
110
117
|
specify_with([{ group: 'nogroup' }]) { expect(filename).to have_group('nogroup') }
|
111
118
|
specify_with([{ mode: 0o600 }]) { expect(filename).to have_file_permission(0o100600) }
|
112
119
|
specify_with([{ perm: 0o600 }]) { expect(filename).to have_file_permission(0o100600) }
|
113
|
-
specify_with([{
|
120
|
+
specify_with([{ mtime: 0 }]) { expect(filename).to have_mtime(0) }
|
121
|
+
specify_with([{ owner: 'nobody', group: 'nogroup', mode: 0o600, mtime: 0 }]) do
|
114
122
|
expect(filename).to have_owner('nobody')
|
115
123
|
expect(filename).to have_group('nogroup')
|
116
124
|
expect(filename).to have_file_permission(0o100600)
|
125
|
+
expect(filename).to have_mtime(0)
|
117
126
|
end
|
118
127
|
end
|
119
128
|
|
@@ -167,7 +176,7 @@ describe SugarUtils::File do
|
|
167
176
|
specify { expect(filename).to have_file_permission(0o100600) }
|
168
177
|
end
|
169
178
|
|
170
|
-
context '
|
179
|
+
context 'without deprecated options' do
|
171
180
|
let(:options) do
|
172
181
|
{ flush: true, owner: 'nobody', group: 'nogroup', mode: 0o600 }
|
173
182
|
end
|
data/spec/sugar_utils_spec.rb
CHANGED
data/sugar_utils.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sugar_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Sullivan Cant
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -223,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
223
|
version: '0'
|
224
224
|
requirements: []
|
225
225
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.6.
|
226
|
+
rubygems_version: 2.6.11
|
227
227
|
signing_key:
|
228
228
|
specification_version: 4
|
229
229
|
summary: Utility methods extracted from SugarCRM Ruby projects.
|