pleasant_path 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56365c199042c351833d072a2e26985b4aceea7cb37fdd4fe8f21c038bdee6ed
4
- data.tar.gz: dea582a2684edab33b60b3f4e3e624ff610d0a23a78fe17c62fbc71476e4c88e
3
+ metadata.gz: b6e3e6a96f3381618fe73ebb4d09a95cd607f22939398eb4352da162fed9581e
4
+ data.tar.gz: 995c964b867b1632d22bf58da748afadcb0a2d3824680a1c8fdcbf69fd494d1e
5
5
  SHA512:
6
- metadata.gz: 9242bc111208a89cad99db62ab0d1b01290ee9d9e59e63e2fe9a15a96fc736b67aea03b0f972cdceac46a0e95680b755db5524033357b711b128a38f0497be84
7
- data.tar.gz: 8ee6d00eb11286b9d1e0fce25e69ced19c73e8135d2db58f24c4562184ca5a4baa56e3866f29fe522c1e3c032046e6805095f1717564f5e5beacc51d0f00da9e
6
+ metadata.gz: 3c0d567cbb4c9579685a4f1923b74787321d03f4118d46af4c863272ec1ef63af48e42c0cd17a6b431043bc43a32d621c810bbae9c05ca9a4933e2d8feecff31
7
+ data.tar.gz: 10d3683e71e7dc881dde05622bdb1d7d53c83ce853f6376f9dc48bb53cc1150a1f67bf412bb80d7ff8717f1aaf03693c78c64d865c4c8820861b5149ae9fcdad
@@ -1,17 +1,34 @@
1
+ ## 1.3.0
2
+
3
+ * Add `Pathname#find_dirs`
4
+ * Add `Pathname#find_files`
5
+ * Add `Pathname#make_file`
6
+ * Add `Pathname#available_name`
7
+ * Add `Pathname#move_as`
8
+ * Add `Pathname#copy_as`
9
+ * Add `eol` parameter to line-oriented methods (`Pathname#read_lines`,
10
+ `Pathname#write_lines`, `Pathname#append_lines`, etc)
11
+ * Move Array methods to Enumerable
12
+ * Use `JSON.dump_default_options` and `JSON.load_default_options` in
13
+ JSON-related API
14
+
15
+
1
16
  ## 1.2.0
2
17
 
3
- * Added `Pathname#existence`.
4
- * Added `Pathname#chdir`.
5
- * Fixed `Object#write_to_yaml` to make parent directories as necessary.
18
+ * Add `Pathname#existence`
19
+ * Add `Pathname#chdir`
20
+ * Fix `Object#write_to_yaml` to make parent directories as necessary
21
+
6
22
 
7
23
  ## 1.1.0
8
24
 
9
- * Added `Pathname#copy` and `Pathname#copy_into`.
10
- * Added `Pathname#rename_basename` and `Pathname#rename_extname`.
11
- * Added `File.common_path` and `Pathname#common_path`.
12
- * Added `Pathname::NULL`.
13
- * Added JSON-related and YAML-related APIs.
14
- * Fixed `File.edit_text` and `File.edit_lines` to properly truncate.
25
+ * Add `Pathname#copy` and `Pathname#copy_into`
26
+ * Add `Pathname#rename_basename` and `Pathname#rename_extname`
27
+ * Add `File.common_path` and `Pathname#common_path`
28
+ * Add `Pathname::NULL`
29
+ * Add JSON-related and YAML-related APIs
30
+ * Fix `File.edit_text` and `File.edit_lines` to properly truncate
31
+
15
32
 
16
33
  ## 1.0.0
17
34
 
data/README.md CHANGED
@@ -10,10 +10,8 @@ objects. See API listing below, or browse the [full documentation].
10
10
  ## Examples
11
11
 
12
12
  ```ruby
13
- # Filter lines across multiple files
14
- "logs/*.txt".glob.each do |log|
15
- log.read_lines.grep(/^ERROR /).append_to_file("errors.txt")
16
- end
13
+ # Pluck lines from a file
14
+ "log.txt".path.read_lines.grep(/^ERROR /).append_to_file("errors.txt")
17
15
 
18
16
  # Dedup lines in a file
19
17
  "names.txt".path.edit_lines(&:uniq)
@@ -30,13 +28,14 @@ The following methods are available:
30
28
  - [#append_file](http://www.rubydoc.info/gems/pleasant_path/Pathname:append_file)
31
29
  - [#append_lines](http://www.rubydoc.info/gems/pleasant_path/Pathname:append_lines)
32
30
  - [#append_text](http://www.rubydoc.info/gems/pleasant_path/Pathname:append_text)
31
+ - [#available_name](http://www.rubydoc.info/gems/pleasant_path/Pathname:available_name)
33
32
  - [#chdir](http://www.rubydoc.info/gems/pleasant_path/Pathname:chdir)
34
33
  - [#common_path](http://www.rubydoc.info/gems/pleasant_path/Pathname:common_path)
35
34
  - [#copy](http://www.rubydoc.info/gems/pleasant_path/Pathname:copy)
35
+ - [#copy_as](http://www.rubydoc.info/gems/pleasant_path/Pathname:copy_as)
36
36
  - [#copy_into](http://www.rubydoc.info/gems/pleasant_path/Pathname:copy_into)
37
37
  - [#delete!](http://www.rubydoc.info/gems/pleasant_path/Pathname:delete%21)
38
38
  - [#dir?](http://www.rubydoc.info/gems/pleasant_path/Pathname:dir%3F)
39
- - [#dir_empty?](http://www.rubydoc.info/gems/pleasant_path/Pathname:dir_empty%3F)
40
39
  - [#dirs](http://www.rubydoc.info/gems/pleasant_path/Pathname:dirs)
41
40
  - [#dirs_r](http://www.rubydoc.info/gems/pleasant_path/Pathname:dirs_r)
42
41
  - [#edit_lines](http://www.rubydoc.info/gems/pleasant_path/Pathname:edit_lines)
@@ -44,29 +43,30 @@ The following methods are available:
44
43
  - [#existence](http://www.rubydoc.info/gems/pleasant_path/Pathname:existence)
45
44
  - [#files](http://www.rubydoc.info/gems/pleasant_path/Pathname:files)
46
45
  - [#files_r](http://www.rubydoc.info/gems/pleasant_path/Pathname:files_r)
46
+ - [#find_dirs](http://www.rubydoc.info/gems/pleasant_path/Pathname:find_dirs)
47
+ - [#find_files](http://www.rubydoc.info/gems/pleasant_path/Pathname:find_files)
47
48
  - [#make_dir](http://www.rubydoc.info/gems/pleasant_path/Pathname:make_dir)
48
49
  - [#make_dirname](http://www.rubydoc.info/gems/pleasant_path/Pathname:make_dirname)
50
+ - [#make_file](http://www.rubydoc.info/gems/pleasant_path/Pathname:make_file)
49
51
  - [#move](http://www.rubydoc.info/gems/pleasant_path/Pathname:move)
52
+ - [#move_as](http://www.rubydoc.info/gems/pleasant_path/Pathname:move_as)
50
53
  - [#move_into](http://www.rubydoc.info/gems/pleasant_path/Pathname:move_into)
51
54
  - [#parentname](http://www.rubydoc.info/gems/pleasant_path/Pathname:parentname)
52
55
  - [#read_lines](http://www.rubydoc.info/gems/pleasant_path/Pathname:read_lines)
53
56
  - [#rename_basename](http://www.rubydoc.info/gems/pleasant_path/Pathname:rename_basename)
54
57
  - [#rename_extname](http://www.rubydoc.info/gems/pleasant_path/Pathname:rename_extname)
55
58
  - [#to_pathname](http://www.rubydoc.info/gems/pleasant_path/Pathname:to_pathname)
56
- - [#touch_file](http://www.rubydoc.info/gems/pleasant_path/Pathname:touch_file)
57
59
  - [#write_lines](http://www.rubydoc.info/gems/pleasant_path/Pathname:write_lines)
58
60
  - [#write_text](http://www.rubydoc.info/gems/pleasant_path/Pathname:write_text)
59
61
  - [String](http://www.rubydoc.info/gems/pleasant_path/String)
60
62
  - [#/](http://www.rubydoc.info/gems/pleasant_path/String:%2F)
61
- - [#^](http://www.rubydoc.info/gems/pleasant_path/String:%5E)
62
63
  - [#append_to_file](http://www.rubydoc.info/gems/pleasant_path/String:append_to_file)
63
- - [#glob](http://www.rubydoc.info/gems/pleasant_path/String:glob)
64
64
  - [#path](http://www.rubydoc.info/gems/pleasant_path/String:path)
65
65
  - [#to_pathname](http://www.rubydoc.info/gems/pleasant_path/String:to_pathname)
66
66
  - [#write_to_file](http://www.rubydoc.info/gems/pleasant_path/String:write_to_file)
67
- - [Array](http://www.rubydoc.info/gems/pleasant_path/Array)
68
- - [#append_to_file](http://www.rubydoc.info/gems/pleasant_path/Array:append_to_file)
69
- - [#write_to_file](http://www.rubydoc.info/gems/pleasant_path/Array:write_to_file)
67
+ - [Enumerable](http://www.rubydoc.info/gems/pleasant_path/Enumerable)
68
+ - [#append_to_file](http://www.rubydoc.info/gems/pleasant_path/Enumerable:append_to_file)
69
+ - [#write_to_file](http://www.rubydoc.info/gems/pleasant_path/Enumerable:write_to_file)
70
70
  - [File](http://www.rubydoc.info/gems/pleasant_path/File)
71
71
  - [.common_path](http://www.rubydoc.info/gems/pleasant_path/File.common_path)
72
72
  - [.edit_lines](http://www.rubydoc.info/gems/pleasant_path/File.edit_lines)
@@ -1,6 +1,6 @@
1
1
  require "pathname"
2
2
  require_relative "pleasant_path/version"
3
- require_relative "pleasant_path/array"
3
+ require_relative "pleasant_path/enumerable"
4
4
  require_relative "pleasant_path/file"
5
5
  require_relative "pleasant_path/io"
6
6
  require_relative "pleasant_path/pathname"
@@ -0,0 +1,43 @@
1
+ module Enumerable
2
+
3
+ # Writes each object in the Enumerable as a string plus end-of-line
4
+ # (EOL) characters to the specified +file+, overwriting the file if it
5
+ # exists. Creates the file if it does not exist, including any
6
+ # necessary parent directories. Returns the Enumerable.
7
+ #
8
+ # @see Pathname#write_lines
9
+ #
10
+ # @example
11
+ # [:one, :two].write_to_file("out.txt") # == [:one, :two]
12
+ # File.read("out.txt") # == "one\ntwo\n"
13
+ #
14
+ # @param file [String, Pathname]
15
+ # @param eol [String]
16
+ # @return [self]
17
+ def write_to_file(file, eol: $/)
18
+ file.to_pathname.write_lines(self, eol: eol)
19
+ self
20
+ end
21
+
22
+ # Appends each object in the Enumerable as a string plus end-of-line
23
+ # (EOL) characters to the specified +file+. Creates the file if it
24
+ # does not exist, including any necessary parent directories. Returns
25
+ # the Enumerable.
26
+ #
27
+ # @see Pathname#append_lines
28
+ #
29
+ # @example
30
+ # [:one, :two].append_to_file("out.txt") # == [:one, :two]
31
+ # File.read("out.txt") # == "one\ntwo\n"
32
+ # [:three, :four].append_to_file("out.txt") # == [:three, :four]
33
+ # File.read("out.txt") # == "one\ntwo\nthree\nfour\n"
34
+ #
35
+ # @param file [String, Pathname]
36
+ # @param eol [String]
37
+ # @return [self]
38
+ def append_to_file(file, eol: $/)
39
+ file.to_pathname.append_lines(self, eol: eol)
40
+ self
41
+ end
42
+
43
+ end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class File
2
4
 
3
- # Computes the longest path that every path in a list has in common.
5
+ # Returns the longest path that all of +paths+ have in common.
4
6
  #
5
7
  # @example
6
8
  # File.common_path(["a/b/x", "a/b/y", "a/b/z"]) # == "a/b/"
7
- # File.common_path(["a/b/x", "a/b/y", "a/z"]) # == "a/"
8
- # File.common_path(["a/b/x", "a/b/y", "a"]) # == "a"
9
+ # File.common_path(["a/bx", "a/by", "a/bz"]) # == "a/"
10
+ # File.common_path(["a/b/x", "a/b", "a"]) # == "a"
9
11
  #
10
12
  # @param paths [Enumerable<String>]
11
13
  # @return [String]
@@ -15,18 +17,18 @@ class File
15
17
  i = 0
16
18
  last = -1
17
19
  while i < short.length && short[i] == long[i]
18
- last = i if short[i] == "/".freeze
20
+ last = i if short[i] == "/"
19
21
  i += 1
20
22
  end
21
23
  short[0, i == short.length ? i : (last + 1)]
22
24
  end
23
25
 
24
- # Reads from the specified file its contents as a string, and yields
25
- # the string to the given block for editing. Writes the return value
26
- # of the block back to the file, overwriting previous contents.
27
- # Returns the file's new contents.
26
+ # Reads the entire contents of the file indicated by +filename+ as a
27
+ # string, and yields that string to the given block for editing.
28
+ # Writes the return value of the block back to the file, overwriting
29
+ # previous contents. Returns the return value of the block.
28
30
  #
29
- # @example update JSON data file
31
+ # @example Update JSON data file
30
32
  # File.read("data.json") # == '{"nested":{"key":"value"}}'
31
33
  #
32
34
  # File.edit_text("data.json") do |text|
@@ -38,9 +40,9 @@ class File
38
40
  # File.read("data.json") # == '{"nested":{"key":"new value"}}'
39
41
  #
40
42
  # @param filename [String, Pathname]
41
- # @yield [text] edits current file contents
42
- # @yieldparam text [String] current contents
43
- # @yieldreturn [String] new contents
43
+ # @yield [text]
44
+ # @yieldparam text [String]
45
+ # @yieldreturn [String]
44
46
  # @return [String]
45
47
  def self.edit_text(filename)
46
48
  self.open(filename, "r+") do |f|
@@ -52,14 +54,14 @@ class File
52
54
  end
53
55
  end
54
56
 
55
- # Reads from the specified file its contents as an array of lines, and
56
- # yields the array to the given block for editing. Writes the return
57
- # value of the block back to the file, overwriting previous contents.
58
- # The <code>$/</code> global string specifies what end-of-line
59
- # characters to use for both reading and writing. Returns the array
60
- # of lines that comprises the file's new contents.
57
+ # Reads the entire contents of the file indicated by +filename+ as an
58
+ # array of lines, and yields that array to the given block for
59
+ # editing. Writes the return value of the block back to the file,
60
+ # overwriting previous contents. End-of-line (EOL) characters are
61
+ # stripped when reading, and appended after each line when writing.
62
+ # Returns the return value of the block.
61
63
  #
62
- # @example dedup lines of file
64
+ # @example Dedup lines of file
63
65
  # File.read("entries.txt") # == "AAA\nBBB\nBBB\nCCC\nAAA\n"
64
66
  #
65
67
  # File.edit_lines("entries.txt", &:uniq)
@@ -68,15 +70,16 @@ class File
68
70
  # File.read("entries.txt") # == "AAA\nBBB\nCCC\n"
69
71
  #
70
72
  # @param filename [String, Pathname]
71
- # @yield [lines] edits current file contents
72
- # @yieldparam lines [Array<String>] current contents
73
- # @yieldreturn [Array<String>] new contents
73
+ # @param eol [String]
74
+ # @yield [lines]
75
+ # @yieldparam lines [Array<String>]
76
+ # @yieldreturn [Array<String>]
74
77
  # @return [Array<String>]
75
- def self.edit_lines(filename)
78
+ def self.edit_lines(filename, eol: $/)
76
79
  self.open(filename, "r+") do |f|
77
- lines = yield f.read_lines
80
+ lines = yield f.read_lines(eol: eol)
78
81
  f.seek(0, IO::SEEK_SET)
79
- f.write_lines(lines)
82
+ f.write_lines(lines, eol: eol)
80
83
  f.truncate(f.pos)
81
84
  lines
82
85
  end
@@ -1,45 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class IO
2
4
 
3
- # Writes each object as a string plus a succeeding new line character
4
- # (<code>$/</code>) to the IO. Returns the objects unmodified.
5
+ # Writes each object in +lines+ as a string plus end-of-line (EOL)
6
+ # characters to the IO. Returns +lines+, unmodified.
5
7
  #
6
8
  # @example
7
- # # NOTE File inherits from IO
8
- # File.open("out.txt") do |file|
9
- # file.write_lines([:one, :two]) # == [:one, :two]
10
- # end # == [:one, :two]
9
+ # File.open("out.txt") do |io|
10
+ # io.write_lines([:one, :two]) # == [:one, :two]
11
+ # end # == [:one, :two]
11
12
  #
12
- # File.read("out.txt") # == "one\ntwo\n"
13
+ # File.read("out.txt") # == "one\ntwo\n"
13
14
  #
14
15
  # @param lines [Enumerable<#to_s>]
16
+ # @param eol [String]
15
17
  # @return [Enumerable<#to_s>]
16
- def write_lines(lines)
18
+ def write_lines(lines, eol: $/)
17
19
  lines.each do |line|
18
20
  self.write(line)
19
- self.write($/)
21
+ self.write(eol)
20
22
  end
21
23
  self.write("") # write something even if no lines
22
24
  lines
23
25
  end
24
26
 
25
- # Reads from the IO all lines, and returns them as an array,
26
- # end-of-line characters excluded. The <code>$/</code> global string
27
- # specifies what end-of-line characters to exclude.
27
+ # Reads all lines from the IO, and returns them with all end-of-line
28
+ # (EOL) characters stripped.
28
29
  #
29
- # (Not to be confused with +IO#readlines+ which retains end-of-line
30
- # characters in every string it returns.)
30
+ # @note Not to be confused with +IO#readlines+, which retains
31
+ # end-of-line (EOL) characters.
31
32
  #
32
33
  # @example
33
- # # NOTE File inherits from IO
34
- # File.read("in.txt") # == "one\ntwo\n"
34
+ # File.read("in.txt") # == "one\ntwo\n"
35
35
  #
36
- # File.open("in.txt") do |file|
37
- # file.read_lines # == ["one", "two"]
38
- # end # == ["one", "two"]
36
+ # File.open("in.txt") do |io|
37
+ # io.read_lines # == ["one", "two"]
38
+ # end # == ["one", "two"]
39
39
  #
40
+ # @param eol [String]
40
41
  # @return [Array<String>]
41
- def read_lines
42
- self.readlines.each(&:chomp!)
42
+ def read_lines(eol: $/)
43
+ self.readlines(eol, chomp: true)
43
44
  end
44
45
 
45
46
  end
@@ -1,26 +1,26 @@
1
1
  class Object
2
2
 
3
- # Dumps the Object as JSON, and writes the JSON to the specified file.
4
- # Returns the Object unmodified.
3
+ # Writes the Object serialized as JSON to the specified +file+,
4
+ # overwriting the file if it exists. Creates the file if it does not
5
+ # exist, including any necessary parent directories. Returns the
6
+ # Object, unmodified.
5
7
  #
6
- # For information about available options see
7
- # {http://ruby-doc.org/stdlib/libdoc/json/rdoc/JSON.html#method-i-generate
8
- # +JSON.generate+}.
8
+ # For information about +options+ see
9
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#method-i-generate
10
+ # +JSON.generate+}. By default, this method uses
11
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#attribute-c-dump_default_options
12
+ # +JSON.dump_default_options+}.
9
13
  #
10
14
  # @example
11
15
  # { "key" => "value" }.write_to_json("out.json") # == { "key" => "value" }
12
16
  # File.read("out.json") # == '{"key":"value"}'
13
17
  #
14
18
  # @param file [String, Pathname]
15
- # @param options [Hash]
19
+ # @param options [Hash<Symbol, Object>]
16
20
  # @return [self]
17
21
  def write_to_json(file, options = {})
18
- options = {
19
- quirks_mode: true,
20
- allow_nan: true,
21
- }.merge(options)
22
-
23
- file.to_pathname.write_text(JSON.generate(self, options))
22
+ options = JSON.dump_default_options.merge(options)
23
+ file.to_pathname.write_text(self.to_json(options))
24
24
  self
25
25
  end
26
26
 
@@ -1,41 +1,38 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pathname
2
4
 
3
- # Reads the contents of the file indicated by the Pathname, and parses
4
- # it as JSON. The returned result will be a basic Ruby data
5
- # structure, namely, one of: +nil+, +true+, +false+, a +Numeric+, a
6
- # +String+, an +Array+, or a +Hash+.
5
+ # Parses the contents of the file indicated by the Pathname as JSON.
6
+ # The returned result will composed of only basic data types, e.g.
7
+ # +nil+, +true+, +false+, +Numeric+, +String+, +Array+, and +Hash+.
7
8
  #
8
- # For information about available options, see
9
- # {http://ruby-doc.org/stdlib/libdoc/json/rdoc/JSON.html#method-i-parse
10
- # +JSON.parse+}.
9
+ # For information about +options+, see
10
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#method-i-parse
11
+ # +JSON.parse+}. By default, this method uses
12
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#attribute-c-load_default_options
13
+ # +JSON.load_default_options+} plus +create_additions: false+.
11
14
  #
12
15
  # @example
13
16
  # File.write("in.json", '{"key": "value"}')
14
17
  #
15
18
  # Pathname.new("in.json").read_json # == { "key" => "value" }
16
19
  #
17
- # @param options [Hash]
20
+ # @param options [Hash<Symbol, Object>]
18
21
  # @return [nil, true, false, Numeric, String, Symbol, Array, Hash]
19
22
  def read_json(options = {})
20
- options = {
21
- quirks_mode: true,
22
- allow_nan: true,
23
- max_nesting: false,
24
- create_additions: false,
25
- }.merge(options)
26
-
27
- JSON.parse(self.read_text, options)
23
+ JSON.load(self, nil, { create_additions: false, **options })
28
24
  end
29
25
 
30
- # Reads the contents of the file indicated by the Pathname, and parses
31
- # it as JSON. The parser will use type information embedded in the
32
- # JSON to deserialize custom types. This is *UNSAFE* for JSON from
33
- # an untrusted source. To consume untrusted JSON, use
34
- # {Pathname#read_json} instead.
26
+ # Parses the contents of the file indicated by the Pathname as JSON,
27
+ # deserializing arbitrary data types via type information embedded in
28
+ # the JSON. This is *UNSAFE* for JSON from an untrusted source. To
29
+ # consume untrusted JSON, use {Pathname#read_json} instead.
35
30
  #
36
- # For information about available options, see
37
- # {http://ruby-doc.org/stdlib/libdoc/json/rdoc/JSON.html#method-i-parse
38
- # +JSON.parse+}.
31
+ # For information about +options+, see
32
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#method-i-parse
33
+ # +JSON.parse+}. By default, this method uses
34
+ # {https://docs.ruby-lang.org/en/trunk/JSON.html#attribute-c-load_default_options
35
+ # +JSON.load_default_options+}.
39
36
  #
40
37
  # For information about serializing custom types to JSON, see the
41
38
  # {https://github.com/flori/json/blob/master/README.md#more-examples
@@ -49,10 +46,10 @@ class Pathname
49
46
  #
50
47
  # Pathname.new("in.json").load_json # == Point.new(10, 20)
51
48
  #
52
- # @param options [Hash]
53
- # @return deserialized object
49
+ # @param options [Hash<Symbol, Object>]
50
+ # @return [Object]
54
51
  def load_json(options = {})
55
- self.open("r"){|f| JSON.load(f, nil, options) }
52
+ JSON.load(self, nil, options)
56
53
  end
57
54
 
58
55
  end