regren 0.0.3 → 0.0.4

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
  SHA1:
3
- metadata.gz: a26b9baec5b659d3278b45d2acc2caecbc8bda43
4
- data.tar.gz: 64cd2f64e3de3f2713af1e5775353611a9ce2ecf
3
+ metadata.gz: b37b7b976a4778f6d1bd4c6a4e400f596c7ddb0b
4
+ data.tar.gz: d3574cf7d20b64e468f0db47acf5033f228ec1cf
5
5
  SHA512:
6
- metadata.gz: 18639dd14b1249adaa9cdb54c584f18e2afd1f2f722092211016626c9cf5e3b062cfc86f51d7e5c93467d43423c4c86eb6194fb4d239d2eb7fcf85d597bfee0d
7
- data.tar.gz: 11be53f33fd9e4d99af1a2df2f9b036787a1c0a3a319466232718f02866d52dd683364901368a29c28766ae4b78655eede050faa7378cce8949abba60a4f39e2
6
+ metadata.gz: f6553b71b3311525b6699cc5b31f94cd231a43939346b386489962d6036fcc77f47deba2b4c118514f4cc76222454182af289b9186bfd8eadb566a0c7a18d82b
7
+ data.tar.gz: f723d1200a3be1e993aef3c7c8e75f8d0ade430352a987a1e72bd615d95c7d653221c905963abe9fc4abb275af9afbef86459b62decd1bf9967587612fbfecf4
data/bin/regren CHANGED
@@ -1,94 +1,99 @@
1
- #!/bin/env ruby
2
-
3
- $:.unshift(File.expand_path('../../lib', __FILE__))
4
-
5
- require 'optparse'
6
- require 'folder_contents_history'
7
- require 'filename_history'
8
-
9
- def string_prompt(prompt = '>')
10
- begin
11
- print("#{prompt} ")
12
- gets.chomp
13
- rescue Interrupt
14
- exit 130
15
- end
16
- end
17
-
18
- def prompt?(text, options = {})
19
- begin
20
- default = options[:yes]
21
- return default if options[:quiet]
22
- opts = default ? "[Y/n]" : "[y/N]"
23
- while true
24
- print "#{text} #{opts} "
25
- c = STDIN.gets.chomp!
26
- if c.downcase == 'y' or (default and c =='')
27
- return true
28
- elsif c.downcase == 'n' or (not default and c =='')
29
- return false
30
- end
31
- end
32
- rescue Interrupt
33
- exit 130
34
- end
35
- end
36
-
37
- options = { mode: :rename }
38
- optparse = OptionParser.new do |opts|
39
- opts.on('-b','--backup','Make backup') { options[:backup] = true }
40
- opts.on('-B','--new-backup','Start backups anew, implies --backup') do
41
- options[:new_backup] = true
42
- options[:backup] = true
43
- end
44
- opts.on('-n','--dry-run','Simulate') { options[:dry_run] = true }
45
- opts.on('-y','--yes','Assume yes as default') { options[:yes] = true }
46
- opts.on('-q','--quiet','Do not print anything') { options[:quiet] = true }
47
- opts.on('-r','--restore','Restore backup') { options[:mode] = :restore }
48
- opts.on('-R','--reapply','Reapply history') { options[:mode] = :reapply }
49
- opts.on('-f','--file FILE', "File for backup/restore") { |file| options[:history_file] = file }
50
- opts.on('-H','--history', "Show history for file") { options[:mode] = :history }
51
- opts.on('-h','--help', "Print help") do
52
- puts opts
53
- exit
54
- end
55
- end
56
- optparse.parse!
57
- options[:history_file] ||= '.backup'
58
-
59
- if options[:mode] == :rename
60
- if ARGV.length != 2
61
- options[:regexp] = Regexp.compile(string_prompt)
62
- options[:replacement] = string_prompt
63
- else
64
- options[:regexp] = Regexp.compile(ARGV[0])
65
- options[:replacement] = ARGV[1]
66
- end
67
- end
68
-
69
- if File.exists?(options[:history_file]) && !options[:new_backup]
70
- history = FolderContentsHistory.new_from_history(options[:history_file])
71
- else
72
- history = FolderContentsHistory.new
73
- end
74
-
75
- history.load_entries
76
-
77
- case options[:mode]
78
- when :history
79
- history.show_history(ARGV.empty? ? Dir["*"] : ARGV)
80
- when :restore
81
- history.plan_rollbacks
82
- when :rename
83
- history.plan_renames(options[:regexp], options[:replacement])
84
- require 'pry'; binding.pry
85
- when :reapply
86
- history.plan_reapplication('.')
87
- end
88
- history.log unless options[:quiet]
89
- unless options[:dry_run] || options[:mode] == :history
90
- if !history.changed.empty? && prompt?("Execute the rename?", options)
91
- history.log_backup(options[:history_file]) if options[:backup]
92
- history.execute
93
- end
94
- end
1
+ #!/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
+
5
+ require 'optparse'
6
+ require 'folder_contents_history'
7
+ require 'filename_history'
8
+
9
+ def string_prompt(prompt = '>')
10
+ begin
11
+ print("#{prompt} ")
12
+ gets.chomp
13
+ rescue Interrupt
14
+ exit 130
15
+ end
16
+ end
17
+
18
+ def prompt?(text, options = {})
19
+ begin
20
+ default = options[:yes]
21
+ return default if options[:quiet]
22
+ opts = default ? '[Y/n]' : '[y/N]'
23
+ loop do
24
+ print "#{text} #{opts} "
25
+ c = STDIN.gets.chomp!
26
+ if c.downcase == 'y' || (default && c == '')
27
+ return true
28
+ elsif c.downcase == 'n' || (!default && c == '')
29
+ return false
30
+ end
31
+ end
32
+ rescue Interrupt
33
+ exit 130
34
+ end
35
+ end
36
+
37
+ options = { mode: :rename }
38
+ optparse = OptionParser.new do |opts|
39
+ opts.on('-b', '--backup', 'Make backup') { options[:backup] = true }
40
+ opts.on('-B', '--new-backup', 'Start backups anew, implies --backup') do
41
+ options[:new_backup] = true
42
+ options[:backup] = true
43
+ end
44
+ opts.on('-n', '--dry-run', 'Simulate') { options[:dry_run] = true }
45
+ opts.on('-y', '--yes', 'Assume yes as default') { options[:yes] = true }
46
+ opts.on('-q', '--quiet', 'Do not print anything') { options[:quiet] = true }
47
+ opts.on('-r', '--restore', 'Restore backup') { options[:mode] = :restore }
48
+ opts.on('-R', '--reapply', 'Reapply history') do
49
+ options[:mode] = :reapply
50
+ end
51
+ opts.on('-f', '--file FILE', 'File for backup/restore') do |file|
52
+ options[:history_file] = file
53
+ end
54
+ opts.on('-H', '--history', 'Show history for file') do
55
+ options[:mode] = :history
56
+ end
57
+ opts.on('-h', '--help', 'Print help') do
58
+ puts opts
59
+ exit
60
+ end
61
+ end
62
+ optparse.parse!
63
+ options[:history_file] ||= '.backup'
64
+
65
+ if options[:mode] == :rename
66
+ if ARGV.length != 2
67
+ options[:regexp] = Regexp.compile(string_prompt)
68
+ options[:replacement] = string_prompt
69
+ else
70
+ options[:regexp] = Regexp.compile(ARGV[0])
71
+ options[:replacement] = ARGV[1]
72
+ end
73
+ end
74
+
75
+ if File.exist?(options[:history_file]) && !options[:new_backup]
76
+ history = FolderContentsHistory.new_from_history(options[:history_file])
77
+ else
78
+ history = FolderContentsHistory.new
79
+ end
80
+
81
+ history.load_entries
82
+
83
+ case options[:mode]
84
+ when :history
85
+ history.show_history(ARGV.empty? ? Dir['*'] : ARGV)
86
+ when :restore
87
+ history.plan_rollbacks
88
+ when :rename
89
+ history.plan_renames(options[:regexp], options[:replacement])
90
+ when :reapply
91
+ history.plan_reapplication('.')
92
+ end
93
+ history.log unless options[:quiet]
94
+ unless options[:dry_run] || options[:mode] == :history
95
+ if !history.changed.empty? && prompt?('Execute the rename?', options)
96
+ history.log_backup(options[:history_file]) if options[:backup]
97
+ history.execute
98
+ end
99
+ end
@@ -1,75 +1,68 @@
1
- class FileNameHistory
2
- def initialize(name, history = [])
3
- @history = history.empty? ? [name] : history
4
- @current = name
5
- end
6
-
7
- def to_hash
8
- {
9
- @history.last => @history
10
- }
11
- end
12
-
13
- def self.new_from_history(history)
14
- return FileNameHistory.new(history.last,
15
- history)
16
- end
17
-
18
- def present?
19
- File.exists?(@current)
20
- end
21
-
22
- def original
23
- @history.first
24
- end
25
-
26
- def history
27
- @history
28
- end
29
-
30
- def last_name
31
- @history.last
32
- end
33
-
34
- def plan_rename(regexp, replacement)
35
- new_name = @current.gsub(regexp, replacement)
36
- @history << new_name if new_name != current
37
- end
38
-
39
- def plan_rollback
40
- @history << original
41
- end
42
-
43
- def was_named?(name)
44
- @history.include? name
45
- end
46
-
47
- def plan_reapplication(name)
48
- @current = name
49
- end
50
-
51
- def changed?
52
- @history.last != @current
53
- end
54
-
55
- def rename
56
- File.rename("#{@current}", "#{@history.last}")
57
- @current = @history.last
58
- end
59
-
60
- def print_history(where = $stdout)
61
- where.puts(@current)
62
- where.print "-> #{@history.join("\n-> ")}\n\n"
63
- end
64
-
65
- def log(where = $stdout)
66
- return unless changed?
67
- where.puts(@current)
68
- where.puts("-> #{@history.last}")
69
- end
70
-
71
- def current
72
- @current
73
- end
74
-
75
- end
1
+ class FileNameHistory
2
+ attr_reader :history, :current
3
+
4
+ def initialize(name, history = [])
5
+ @history = history.empty? ? [name] : history
6
+ @current = name
7
+ end
8
+
9
+ def to_hash
10
+ {
11
+ @history.last => @history
12
+ }
13
+ end
14
+
15
+ def self.new_from_history(history)
16
+ FileNameHistory.new(history.last,
17
+ history)
18
+ end
19
+
20
+ def present?
21
+ File.exist?(@current)
22
+ end
23
+
24
+ def original
25
+ @history.first
26
+ end
27
+
28
+ def last_name
29
+ @history.last
30
+ end
31
+
32
+ def plan_rename(regexp, replacement)
33
+ new_name = @current.gsub(regexp, replacement)
34
+ @history << new_name if new_name != current
35
+ end
36
+
37
+ def plan_rollback
38
+ @history << original
39
+ end
40
+
41
+ def was_named?(name)
42
+ @history.include? name
43
+ end
44
+
45
+ def plan_reapplication(name)
46
+ @current = name
47
+ end
48
+
49
+ def changed?
50
+ @history.last != @current
51
+ end
52
+
53
+ def rename
54
+ File.rename("#{@current}", "#{@history.last}")
55
+ @current = @history.last
56
+ end
57
+
58
+ def print_history(where = $stdout)
59
+ where.puts(@current)
60
+ where.print "-> #{@history.join("\n-> ")}\n\n"
61
+ end
62
+
63
+ def log(where = $stdout)
64
+ return unless changed?
65
+ where.puts(@current)
66
+ where.puts("-> #{@history.last}")
67
+ end
68
+ end
@@ -1,100 +1,106 @@
1
- class FolderContentsHistory
2
-
3
- require 'json'
4
-
5
- def initialize(entries = {})
6
- @entries = entries
7
- end
8
-
9
- def load_entries(path = '.')
10
- entries = Dir["#{path}/*"].inject({}) do |hash, item|
11
- pathless = item.gsub(/#{path}\//,'')
12
- hash.update(pathless => FileNameHistory.new(pathless))
13
- end
14
- @entries.merge!(entries) do |key, old_hash, new_hash|
15
- old_hash.history.length > new_hash.history.length ? old_hash : new_hash
16
- end
17
- end
18
-
19
- def plan_renames(regexp, replacement)
20
- @entries.select { |key, value| key[regexp] }.each_pair do |key, value|
21
- value.plan_rename(regexp, replacement)
22
- end
23
- end
24
-
25
- def plan_rollbacks
26
- @entries.each_value do |file_history|
27
- file_history.plan_rollback
28
- end
29
- end
30
-
31
- def plan_reapplication(path)
32
- entries = Dir["#{path}/*"].map { |file| file.gsub(/#{path}\//,'') }
33
- histories = @entries.values
34
- @entries = entries.inject({}) do |hash, item|
35
- hash.tap do |obj|
36
- new_history = histories.select { |history| history.was_named? item }.first
37
- obj.update(item => new_history.clone) unless new_history.nil?
38
- end
39
- end
40
- @entries.select! { |name, history| history }
41
- @entries.each { |name, history| history.plan_reapplication(name) }
42
- end
43
-
44
- def execute
45
- changed.each_pair do |key, value|
46
- value.rename
47
- @entries[value.current] = @entries.delete(key)
48
- end
49
- end
50
-
51
- def log
52
- if conflicts?
53
- puts <<-NOTE.gsub(/^.*\|/, '')
54
- |==================================================
55
- |!!! Some files would be lost by this operation !!!
56
- |==================================================
57
- NOTE
58
- end
59
- changed.each_value do |file_history|
60
- file_history.log
61
- end
62
- end
63
-
64
- def log_backup(where)
65
- with_history = @entries.select { |name, history| history.history.length > 1 }
66
- backup = with_history.inject({}) do |hash, item|
67
- hash.update(item.last.to_hash)
68
- end
69
- File.write(where, JSON.pretty_generate(backup))
70
- end
71
-
72
- def to_hash(input_hash = @entries)
73
- input_hash.inject({}) do |hash, entry|
74
- hash.update(entry[0] => entry[1].to_hash)
75
- end
76
- end
77
-
78
- def changed
79
- @entries.select { |_key, value| value.changed? && value.present? }
80
- end
81
-
82
- def show_history(files)
83
- files.each do |file|
84
- @entries[file] = FileNameHistory.new(file) unless @entries[file]
85
- @entries[file].print_history
86
- end
87
- end
88
-
89
- def conflicts?
90
- #changed.map { |entry| entry.last }.compact.uniq.length < changed.length
91
- @entries.map { |entry| entry.last.last_name }.compact.uniq.length < @entries.length
92
- end
93
-
94
- def self.new_from_history(history_file)
95
- entries = JSON.parse(File.read(history_file)).inject({}) do |hash, item|
96
- hash.update(item.first => FileNameHistory.new_from_history(item.last))
97
- end
98
- FolderContentsHistory.new(entries)
99
- end
100
- end
1
+ class FolderContentsHistory
2
+ require 'json'
3
+
4
+ def initialize(entries = {})
5
+ @entries = entries
6
+ end
7
+
8
+ def load_entries(path = '.')
9
+ entries = Dir["#{path}/*"].reduce({}) do |hash, item|
10
+ pathless = item.gsub(/#{path}\//, '')
11
+ hash.update(pathless => FileNameHistory.new(pathless))
12
+ end
13
+ @entries.merge!(entries) do |_key, old_hash, new_hash|
14
+ old_hash.history.length > new_hash.history.length ? old_hash : new_hash
15
+ end
16
+ end
17
+
18
+ def plan_renames(regexp, replacement)
19
+ @entries.select { |key, _value| key[regexp] }.each_pair do |_key, value|
20
+ value.plan_rename(regexp, replacement)
21
+ end
22
+ end
23
+
24
+ def plan_rollbacks
25
+ @entries.each_value do |file_history|
26
+ file_history.plan_rollback
27
+ end
28
+ end
29
+
30
+ def plan_reapplication(path)
31
+ entries = Dir["#{path}/*"].map { |file| file.gsub(/#{path}\//, '') }
32
+ histories = @entries.values
33
+ @entries = merge_histories(histories, entries)
34
+ @entries.select! { |_name, history| history }
35
+ @entries.each { |name, history| history.plan_reapplication(name) }
36
+ end
37
+
38
+ def merge_histories(old, new)
39
+ new.reduce({}) do |hash, item|
40
+ hash.tap do |obj|
41
+ new_history = old.select { |history| history.was_named? item }.first
42
+ obj.update(item => new_history.clone) unless new_history.nil?
43
+ end
44
+ end
45
+ end
46
+
47
+ def execute
48
+ changed.each_pair do |key, value|
49
+ value.rename
50
+ @entries[value.current] = @entries.delete(key)
51
+ end
52
+ end
53
+
54
+ def log
55
+ if conflicts?
56
+ puts <<-NOTE.gsub(/^.*\|/, '')
57
+ |==================================================
58
+ |!!! Some files would be lost by this operation !!!
59
+ |==================================================
60
+ NOTE
61
+ end
62
+ changed.each_value do |file_history|
63
+ file_history.log
64
+ end
65
+ end
66
+
67
+ def log_backup(where)
68
+ with_history = @entries
69
+ .select { |_name, history| history.history.length > 1 }
70
+ backup = with_history.reduce({}) do |hash, item|
71
+ hash.update(item.last.to_hash)
72
+ end
73
+ File.write(where, JSON.pretty_generate(backup))
74
+ end
75
+
76
+ def to_hash(input_hash = @entries)
77
+ input_hash.reduce({}) do |hash, entry|
78
+ hash.update(entry[0] => entry[1].to_hash)
79
+ end
80
+ end
81
+
82
+ def changed
83
+ @entries.select { |_key, value| value.changed? && value.present? }
84
+ end
85
+
86
+ def show_history(files)
87
+ files.each do |file|
88
+ @entries[file] = FileNameHistory.new(file) unless @entries[file]
89
+ @entries[file].print_history
90
+ end
91
+ end
92
+
93
+ def conflicts?
94
+ # changed.map { |entry| entry.last }.compact.uniq.length < changed.length
95
+ @entries.map do |entry|
96
+ entry.last.last_name
97
+ end.compact.uniq.length < @entries.length
98
+ end
99
+
100
+ def self.new_from_history(history_file)
101
+ entries = JSON.parse(File.read(history_file)).reduce({}) do |hash, item|
102
+ hash.update(item.first => FileNameHistory.new_from_history(item.last))
103
+ end
104
+ FolderContentsHistory.new(entries)
105
+ end
106
+ end
File without changes
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: regren
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Ruzicka
@@ -31,7 +31,7 @@ dependencies:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.3'
34
- - - ! '>='
34
+ - - '>='
35
35
  - !ruby/object:Gem::Version
36
36
  version: 4.7.3
37
37
  type: :development
@@ -41,7 +41,7 @@ dependencies:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
43
  version: '1.3'
44
- - - ! '>='
44
+ - - '>='
45
45
  - !ruby/object:Gem::Version
46
46
  version: 4.7.3
47
47
  description: A simple gem for batch renaming files
@@ -52,8 +52,8 @@ extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
54
  - bin/regren
55
- - lib/filename_history.rb
56
55
  - lib/folder_contents_history.rb
56
+ - lib/filename_history.rb
57
57
  - test/filename_history_test.rb
58
58
  - test/folder_contents_history_test.rb
59
59
  homepage: https://github.com/adamruzicka/regren
@@ -66,17 +66,17 @@ require_paths:
66
66
  - lib
67
67
  required_ruby_version: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - ! '>='
69
+ - - '>='
70
70
  - !ruby/object:Gem::Version
71
71
  version: 1.9.2
72
72
  required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - ! '>='
74
+ - - '>='
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
78
  rubyforge_project:
79
- rubygems_version: 2.3.0
79
+ rubygems_version: 2.1.11
80
80
  signing_key:
81
81
  specification_version: 4
82
82
  summary: regren