reenrb 0.1.1 → 0.2.2
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/CHANGELOG.md +14 -1
- data/Gemfile.lock +1 -1
- data/README.md +3 -1
- data/bin/reen +1 -1
- data/lib/reenrb/actions/delete.rb +20 -0
- data/lib/reenrb/actions/file_rename.rb +20 -0
- data/lib/reenrb/actions/nothing.rb +17 -0
- data/lib/reenrb/change.rb +119 -0
- data/lib/reenrb/changes.rb +71 -0
- data/lib/{changes_file.rb → reenrb/changes_file.rb} +0 -0
- data/lib/reenrb/reen.rb +48 -0
- data/lib/reenrb/version.rb +1 -1
- data/lib/reenrb.rb +4 -41
- metadata +8 -4
- data/lib/change.rb +0 -100
- data/lib/changes.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2253d4b2aa304bfac8b7e4659fee9ca3b514a22d4a0bb323be9619883b9448c0
|
4
|
+
data.tar.gz: 3f82b6afbbe84b70878d153b56f6f75a72c2570df3b2b292c0d42a4a0057e973
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 331ad4055d5abc194ec73fb0be6ac7479d3d2d8c41fb37980edc9c772f998a7b469da386e6b8e9c9dfe594802f9f1e39daa0081f0e109a1278fa41b1fb666a24
|
7
|
+
data.tar.gz: 39d3af74b266effdb9ad82c513412539edd75b2573e97a36f41850027822c4a22029fa0b1fe6b298de177f9d794c86e80c88349dcb05b2b19541c998a572e2c2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
1
8
|
## [Unreleased]
|
2
9
|
|
10
|
+
## [0.2.1] - 2022-11-05
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
- Simplified API for passing block to request/execute
|
15
|
+
|
3
16
|
## [0.1.0] - 2022-11-05
|
4
17
|
|
5
|
-
- Initial release
|
18
|
+
- Initial release: CLI and API working
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -43,7 +43,7 @@ Use programmatically using the `reenrb` gem. In the example below, we specify th
|
|
43
43
|
require 'reenrb'
|
44
44
|
|
45
45
|
glob = Dir.glob("*")
|
46
|
-
reen = Reenrb::Reen.new(
|
46
|
+
reen = Reenrb::Reen.new(editor: nil)
|
47
47
|
|
48
48
|
reen.execute(glob) do |tmpfile_path|
|
49
49
|
lines = File.read(tmpfile_path).split("\n")
|
@@ -55,6 +55,8 @@ reen.execute(glob) do |tmpfile_path|
|
|
55
55
|
end
|
56
56
|
```
|
57
57
|
|
58
|
+
You may also pass a block with an editor specified, in which case the block is run after the editor has finished.
|
59
|
+
|
58
60
|
## Development
|
59
61
|
|
60
62
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/bin/reen
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reenrb
|
4
|
+
module Actions
|
5
|
+
# Deletes a file
|
6
|
+
class FileDelete
|
7
|
+
def initialize(old_name, new_name)
|
8
|
+
@old_name = old_name
|
9
|
+
@new_name = new_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
File.delete(@old_name)
|
14
|
+
nil
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
"Could not delete"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reenrb
|
4
|
+
module Actions
|
5
|
+
# Renames files
|
6
|
+
class FileRename
|
7
|
+
def initialize(old_name, new_name)
|
8
|
+
@old_name = old_name
|
9
|
+
@new_name = new_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
File.rename(@old_name, @new_name)
|
14
|
+
nil
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
"No such target file or directory"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reenrb
|
4
|
+
module Actions
|
5
|
+
# Does nothing to items
|
6
|
+
class DoNothing
|
7
|
+
def initialize(old_name, new_name)
|
8
|
+
@old_name = old_name
|
9
|
+
@new_name = new_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "actions/delete"
|
4
|
+
require_relative "actions/file_rename"
|
5
|
+
require_relative "actions/nothing"
|
6
|
+
|
7
|
+
module Reenrb
|
8
|
+
# Change to an orignal file
|
9
|
+
class Change
|
10
|
+
attr_reader :original, :requested, :change, :status
|
11
|
+
|
12
|
+
module STATUS
|
13
|
+
ACCEPTED = :accepted
|
14
|
+
REJECTED = :rejected
|
15
|
+
EXECUTED = :executed
|
16
|
+
FAILED = :failed
|
17
|
+
end
|
18
|
+
|
19
|
+
module CHANGE
|
20
|
+
NONE = :none
|
21
|
+
DELETE = :delete
|
22
|
+
RENAME = :rename
|
23
|
+
end
|
24
|
+
|
25
|
+
ACTION_HANDLER = {
|
26
|
+
CHANGE::NONE => Actions::DoNothing,
|
27
|
+
CHANGE::DELETE => Actions::FileDelete,
|
28
|
+
CHANGE::RENAME => Actions::FileRename
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
CHANGES_DESC = {
|
32
|
+
CHANGE::NONE => "Nothing",
|
33
|
+
CHANGE::DELETE => "Deleting",
|
34
|
+
CHANGE::RENAME => "Renaming"
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
def initialize(original, requested)
|
38
|
+
@original = original
|
39
|
+
@requested = requested
|
40
|
+
@change = compare
|
41
|
+
consider
|
42
|
+
end
|
43
|
+
|
44
|
+
def compare
|
45
|
+
if original == requested
|
46
|
+
CHANGE::NONE
|
47
|
+
elsif requested.start_with? "-"
|
48
|
+
CHANGE::DELETE
|
49
|
+
else
|
50
|
+
CHANGE::RENAME
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def consider
|
55
|
+
if request_full_dir? && request_delete?
|
56
|
+
@status = STATUS::REJECTED
|
57
|
+
@reason = "Directories with files cannot be changed"
|
58
|
+
else
|
59
|
+
@status = STATUS::ACCEPTED
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def execute
|
64
|
+
return(self) if not_accepted?
|
65
|
+
|
66
|
+
@status = STATUS::EXECUTED
|
67
|
+
error = ACTION_HANDLER[@change].new(original, requested).call
|
68
|
+
|
69
|
+
if error
|
70
|
+
@status = STATUS::FAILED
|
71
|
+
@reason = error
|
72
|
+
end
|
73
|
+
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
# Predicates
|
78
|
+
|
79
|
+
def request_dir? = Dir.exist?(@original)
|
80
|
+
|
81
|
+
def request_nothing? = @change == CHANGE::NONE
|
82
|
+
|
83
|
+
def request_rename? = @change == CHANGE::RENAME
|
84
|
+
|
85
|
+
def request_delete? = @change == CHANGE::DELETE
|
86
|
+
|
87
|
+
def request_empty_dir? = Dir.empty?(@original)
|
88
|
+
|
89
|
+
def accepted? = @status == STATUS::ACCEPTED
|
90
|
+
|
91
|
+
def not_accepted? = !accepted?
|
92
|
+
|
93
|
+
def executed? = @status == STATUS::EXECUTED
|
94
|
+
|
95
|
+
def rejected? = @status == STATUS::REJECTED
|
96
|
+
|
97
|
+
def failed? = @status == STATUS::FAILED
|
98
|
+
|
99
|
+
def request_full_dir? = request_dir? && !request_empty_dir?
|
100
|
+
|
101
|
+
def executed_or_rejected? = %i[executed rejected].include?(@status)
|
102
|
+
|
103
|
+
# Decoration
|
104
|
+
|
105
|
+
def to_s
|
106
|
+
file_desc =
|
107
|
+
case @change
|
108
|
+
when CHANGE::RENAME
|
109
|
+
"#{@original} -> #{@requested}"
|
110
|
+
else
|
111
|
+
@original
|
112
|
+
end
|
113
|
+
|
114
|
+
reason_desc = rejected? || failed? ? " (failed: #{@reason})" : ""
|
115
|
+
|
116
|
+
"#{CHANGES_DESC[@change]}: #{file_desc}#{reason_desc}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "change"
|
4
|
+
|
5
|
+
module Reenrb
|
6
|
+
# Change to an orignal file
|
7
|
+
class Changes
|
8
|
+
attr_reader :list
|
9
|
+
|
10
|
+
def initialize(changes_list)
|
11
|
+
@list = changes_list
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute!
|
15
|
+
@list.map(&:execute)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Queries
|
20
|
+
|
21
|
+
def rename_requested
|
22
|
+
Changes.new(@list.select(&:request_rename?))
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_requested
|
26
|
+
Changes.new(@list.select(&:request_delete?))
|
27
|
+
end
|
28
|
+
|
29
|
+
def change_requested
|
30
|
+
Changes.new(@list.reject(&:request_nothing?))
|
31
|
+
end
|
32
|
+
|
33
|
+
def rejected
|
34
|
+
Changes.new(@list.select(&:rejected?))
|
35
|
+
end
|
36
|
+
|
37
|
+
def accepted
|
38
|
+
Changes.new(@list.select(&:accepted?))
|
39
|
+
end
|
40
|
+
|
41
|
+
def executed
|
42
|
+
Changes.new(@list.select(&:executed?))
|
43
|
+
end
|
44
|
+
|
45
|
+
def count
|
46
|
+
@list.size
|
47
|
+
end
|
48
|
+
|
49
|
+
# Decoration
|
50
|
+
|
51
|
+
def summarize
|
52
|
+
return "Nothing changed" if @list.empty?
|
53
|
+
|
54
|
+
@list.map(&:to_s).join("\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Predicates
|
58
|
+
|
59
|
+
def no_changes_requested?
|
60
|
+
list.map(&:change).all? Change::CHANGE::NONE
|
61
|
+
end
|
62
|
+
|
63
|
+
def changes_requested?
|
64
|
+
!no_changes_requested?
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_executed?
|
68
|
+
@list.all?(&:executed?)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
File without changes
|
data/lib/reenrb/reen.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Reenrb
|
4
|
+
# Renames pattern of files with given editor
|
5
|
+
# Examples:
|
6
|
+
# Reenrb::Reen.new(editor: "code -w").call("spec/fixtures/example/*")
|
7
|
+
# Reenrb::Reen.new(editor: nil).call("spec/fixtures/example/*") { ... }
|
8
|
+
class Reen
|
9
|
+
DEL_ERROR = "Do not delete any file/folder names"
|
10
|
+
|
11
|
+
attr_reader :changes
|
12
|
+
|
13
|
+
def initialize(editor: "emacs", options: {})
|
14
|
+
@editor = editor
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
def request(original_list, &block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
19
|
+
changed_list = ChangesFile.new(original_list).allow_changes do |file|
|
20
|
+
file.blocking_edit(@editor) if @editor
|
21
|
+
|
22
|
+
if block
|
23
|
+
lines = File.read(file.path).split("\n")
|
24
|
+
new_lines = block.call(lines) || lines
|
25
|
+
File.write(file.path, new_lines.join("\n"))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
raise(Error, DEL_ERROR) if changed_list.size != original_list.size
|
30
|
+
|
31
|
+
@changes = compare_lists(original_list, changed_list)
|
32
|
+
.then { |change_array| Changes.new(change_array) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute(original_list, &block)
|
36
|
+
@changes ||= request(original_list, &block)
|
37
|
+
@changes = @changes.execute!
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def compare_lists(original_list, changed_list)
|
43
|
+
original_list.zip(changed_list).map do |original, revised|
|
44
|
+
Change.new(original, revised)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/reenrb/version.rb
CHANGED
data/lib/reenrb.rb
CHANGED
@@ -1,48 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "reenrb/version"
|
4
|
-
require_relative "changes_file"
|
5
|
-
require_relative "change"
|
6
|
-
require_relative "changes"
|
4
|
+
require_relative "reenrb/changes_file"
|
5
|
+
require_relative "reenrb/change"
|
6
|
+
require_relative "reenrb/changes"
|
7
|
+
require_relative "reenrb/reen"
|
7
8
|
|
8
9
|
module Reenrb
|
9
10
|
class Error < StandardError; end
|
10
|
-
|
11
|
-
# Renames pattern of files with given editor
|
12
|
-
# Example:
|
13
|
-
# Reenrb::Reen.new(editor: "code -w").call("spec/fixtures/example/*")
|
14
|
-
class Reen
|
15
|
-
DEL_ERROR = "Do not delete any file/folder names"
|
16
|
-
|
17
|
-
attr_reader :changes
|
18
|
-
|
19
|
-
def initialize(editor: "emacs", options: {})
|
20
|
-
@editor = editor
|
21
|
-
@options = options
|
22
|
-
end
|
23
|
-
|
24
|
-
def request(original_list, &block)
|
25
|
-
# original_list = Dir.glob(pattern)
|
26
|
-
changed_list = ChangesFile.new(original_list).allow_changes do |file|
|
27
|
-
@options[:mock_editor] ? block.call(file.path) : file.blocking_edit(@editor)
|
28
|
-
end
|
29
|
-
|
30
|
-
raise(Error, DEL_ERROR) if changed_list.size != original_list.size
|
31
|
-
|
32
|
-
@changes = compare_lists(original_list, changed_list)
|
33
|
-
end
|
34
|
-
|
35
|
-
def execute(original_list, &block)
|
36
|
-
@changes ||= request(original_list, &block)
|
37
|
-
@changes = @changes.map(&:execute)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def compare_lists(original_list, changed_list)
|
43
|
-
original_list.zip(changed_list).map do |original, revised|
|
44
|
-
Change.new(original, revised)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
11
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reenrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soumya Ray
|
@@ -110,10 +110,14 @@ files:
|
|
110
110
|
- README.md
|
111
111
|
- Rakefile
|
112
112
|
- bin/reen
|
113
|
-
- lib/change.rb
|
114
|
-
- lib/changes.rb
|
115
|
-
- lib/changes_file.rb
|
116
113
|
- lib/reenrb.rb
|
114
|
+
- lib/reenrb/actions/delete.rb
|
115
|
+
- lib/reenrb/actions/file_rename.rb
|
116
|
+
- lib/reenrb/actions/nothing.rb
|
117
|
+
- lib/reenrb/change.rb
|
118
|
+
- lib/reenrb/changes.rb
|
119
|
+
- lib/reenrb/changes_file.rb
|
120
|
+
- lib/reenrb/reen.rb
|
117
121
|
- lib/reenrb/version.rb
|
118
122
|
- reenrb.gemspec
|
119
123
|
- sig/reenrb.rbs
|
data/lib/change.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Reenrb
|
4
|
-
# Change to an orignal file
|
5
|
-
class Change
|
6
|
-
attr_reader :original, :requested, :change, :status
|
7
|
-
|
8
|
-
module STATUS
|
9
|
-
ACCEPTED = :accepted
|
10
|
-
REJECTED = :rejected
|
11
|
-
EXECUTED = :executed
|
12
|
-
end
|
13
|
-
|
14
|
-
module CHANGE
|
15
|
-
NONE = :none
|
16
|
-
DELETE = :delete
|
17
|
-
RENAME = :rename
|
18
|
-
end
|
19
|
-
|
20
|
-
CHANGES_DESC = {
|
21
|
-
none: "Nothing",
|
22
|
-
delete: "Deleting",
|
23
|
-
rename: "Renaming"
|
24
|
-
}.freeze
|
25
|
-
|
26
|
-
def initialize(original, requested)
|
27
|
-
@original = original
|
28
|
-
@requested = requested
|
29
|
-
@change = compare
|
30
|
-
consider
|
31
|
-
end
|
32
|
-
|
33
|
-
def compare
|
34
|
-
if original == requested
|
35
|
-
:none
|
36
|
-
elsif requested.start_with? "-"
|
37
|
-
:delete
|
38
|
-
else
|
39
|
-
:rename
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def request_directory?
|
44
|
-
Dir.exist? @original
|
45
|
-
end
|
46
|
-
|
47
|
-
def request_delete?
|
48
|
-
@change == CHANGE::DELETE
|
49
|
-
end
|
50
|
-
|
51
|
-
def request_empty_directory?
|
52
|
-
Dir.empty? @original
|
53
|
-
end
|
54
|
-
|
55
|
-
def request_full_directory?
|
56
|
-
request_directory? && !request_empty_directory?
|
57
|
-
end
|
58
|
-
|
59
|
-
def consider
|
60
|
-
if request_full_directory? && request_delete?
|
61
|
-
@status = STATUS::REJECTED
|
62
|
-
@reason = "Directories with files cannot be changed"
|
63
|
-
else
|
64
|
-
@status = STATUS::ACCEPTED
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def executed_or_rejected
|
69
|
-
%i[executed rejected].include? @status
|
70
|
-
end
|
71
|
-
|
72
|
-
def execute
|
73
|
-
return(self) if executed_or_rejected
|
74
|
-
|
75
|
-
case @change
|
76
|
-
when :rename
|
77
|
-
File.rename(@original, @requested)
|
78
|
-
when :delete
|
79
|
-
File.delete(@original)
|
80
|
-
end
|
81
|
-
|
82
|
-
@status = STATUS::EXECUTED
|
83
|
-
self
|
84
|
-
end
|
85
|
-
|
86
|
-
def to_s
|
87
|
-
file_desc =
|
88
|
-
case @change
|
89
|
-
when :rename
|
90
|
-
"#{@original} -> #{@requested}"
|
91
|
-
else
|
92
|
-
@original
|
93
|
-
end
|
94
|
-
|
95
|
-
reason_desc = @status == STATUS::REJECTED ? " (failed: #{@reason})" : ""
|
96
|
-
|
97
|
-
"#{CHANGES_DESC[@change]}: #{file_desc}#{reason_desc}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/lib/changes.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Reenrb
|
4
|
-
# Change to an orignal file
|
5
|
-
class Changes
|
6
|
-
attr_reader :list
|
7
|
-
|
8
|
-
def initialize(changes_list)
|
9
|
-
@list = changes_list
|
10
|
-
end
|
11
|
-
|
12
|
-
def none
|
13
|
-
Changes.new(@list.select { |c| c.change == :none })
|
14
|
-
end
|
15
|
-
|
16
|
-
def rename_requested
|
17
|
-
Changes.new(@list.select { |c| c.change == :rename })
|
18
|
-
end
|
19
|
-
|
20
|
-
def delete_requested
|
21
|
-
Changes.new(@list.select { |c| c.change == :delete })
|
22
|
-
end
|
23
|
-
|
24
|
-
def change_requested
|
25
|
-
Changes.new(@list.reject { |c| c.change == :none })
|
26
|
-
end
|
27
|
-
|
28
|
-
def rejected
|
29
|
-
Changes.new(@list.select { |c| c.status == :rejected })
|
30
|
-
end
|
31
|
-
|
32
|
-
def accepted
|
33
|
-
Changes.new(@list.select { |c| c.status == :accepted })
|
34
|
-
end
|
35
|
-
|
36
|
-
def executed
|
37
|
-
Changes.new(@list.select { |c| c.status == :executed })
|
38
|
-
end
|
39
|
-
|
40
|
-
def summarize
|
41
|
-
return "Nothing changed" if @list.empty?
|
42
|
-
|
43
|
-
@list.map(&:to_s).join("\n")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|