pleasant_path 1.2.0 → 1.3.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 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