simonc-AbsoluteRenamer 0.9.1 → 0.9.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.
- data/AbsoluteRenamer.gemspec +83 -0
- data/VERSION +1 -1
- data/conf/absrenamer/absrenamer.conf +34 -0
- data/lib/absolute_renamer.rb +122 -0
- data/lib/absolute_renamer/config.rb +40 -0
- data/lib/absolute_renamer/external.rb +56 -0
- data/lib/absolute_renamer/external/modules/core/case/module.rb +31 -0
- data/lib/absolute_renamer/external/modules/core/general/module.rb +126 -0
- data/lib/absolute_renamer/external/parsers/core/general/parser.rb +74 -0
- data/lib/absolute_renamer/external/parsers/interactive/parser.rb +20 -0
- data/lib/absolute_renamer/external/parsers/listing/parser.rb +9 -0
- data/lib/absolute_renamer/external/plugins/interactive/plugin.rb +35 -0
- data/lib/absolute_renamer/external/plugins/listing/plugin.rb +14 -0
- data/lib/absolute_renamer/file_info.rb +102 -0
- data/lib/absolute_renamer/imodule.rb +68 -0
- data/lib/absolute_renamer/iparser.rb +8 -0
- data/lib/absolute_renamer/iplugin.rb +11 -0
- data/lib/absolute_renamer/libs/file.rb +11 -0
- data/lib/absolute_renamer/libs/string.rb +27 -0
- data/lib/absolute_renamer/parser.rb +91 -0
- data/lib/absolute_renamer/use_config.rb +11 -0
- data/lib/absolute_renamer/with_children.rb +22 -0
- data/test/absolute_renamer_test.rb +2 -2
- data/test/config_test.rb +45 -0
- data/test/file_info_test.rb +71 -0
- data/test/file_test.rb +33 -0
- metadata +31 -2
@@ -0,0 +1,83 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{AbsoluteRenamer}
|
8
|
+
s.version = "0.9.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Simon COURTOIS"]
|
12
|
+
s.date = %q{2009-09-22}
|
13
|
+
s.default_executable = %q{absrenamer}
|
14
|
+
s.description = %q{Unlike many batch renaming tools, AbsoluteRenamer is able to rename folders.
|
15
|
+
AbsoluteRenamer is modular and can be extended to adapt itself to any kind of file
|
16
|
+
or to add new options and features.}
|
17
|
+
s.email = %q{happynoff@free.fr}
|
18
|
+
s.executables = ["absrenamer"]
|
19
|
+
s.extra_rdoc_files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README.rdoc"
|
22
|
+
]
|
23
|
+
s.files = [
|
24
|
+
".document",
|
25
|
+
".gitignore",
|
26
|
+
"AbsoluteRenamer.gemspec",
|
27
|
+
"LICENSE",
|
28
|
+
"README.rdoc",
|
29
|
+
"Rakefile",
|
30
|
+
"VERSION",
|
31
|
+
"bin/absrenamer",
|
32
|
+
"conf/absrenamer/absrenamer.conf",
|
33
|
+
"lib/absolute_renamer.rb",
|
34
|
+
"lib/absolute_renamer/config.rb",
|
35
|
+
"lib/absolute_renamer/external.rb",
|
36
|
+
"lib/absolute_renamer/external/modules/core/case/module.rb",
|
37
|
+
"lib/absolute_renamer/external/modules/core/general/module.rb",
|
38
|
+
"lib/absolute_renamer/external/parsers/core/general/parser.rb",
|
39
|
+
"lib/absolute_renamer/external/parsers/interactive/parser.rb",
|
40
|
+
"lib/absolute_renamer/external/parsers/listing/parser.rb",
|
41
|
+
"lib/absolute_renamer/external/plugins/interactive/plugin.rb",
|
42
|
+
"lib/absolute_renamer/external/plugins/listing/plugin.rb",
|
43
|
+
"lib/absolute_renamer/file_info.rb",
|
44
|
+
"lib/absolute_renamer/imodule.rb",
|
45
|
+
"lib/absolute_renamer/iparser.rb",
|
46
|
+
"lib/absolute_renamer/iplugin.rb",
|
47
|
+
"lib/absolute_renamer/libs/file.rb",
|
48
|
+
"lib/absolute_renamer/libs/string.rb",
|
49
|
+
"lib/absolute_renamer/parser.rb",
|
50
|
+
"lib/absolute_renamer/use_config.rb",
|
51
|
+
"lib/absolute_renamer/with_children.rb",
|
52
|
+
"test/absolute_renamer_test.rb",
|
53
|
+
"test/config_test.rb",
|
54
|
+
"test/file_info_test.rb",
|
55
|
+
"test/file_test.rb",
|
56
|
+
"test/test_helper.rb"
|
57
|
+
]
|
58
|
+
s.homepage = %q{http://github.com/simonc/AbsoluteRenamer}
|
59
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
60
|
+
s.require_paths = ["lib"]
|
61
|
+
s.rubygems_version = %q{1.3.5}
|
62
|
+
s.summary = %q{AbsoluteRenamer is a very powerful tool that helps files and directories renaming using the Krename syntax.}
|
63
|
+
s.test_files = [
|
64
|
+
"test/absolute_renamer_test.rb",
|
65
|
+
"test/config_test.rb",
|
66
|
+
"test/file_info_test.rb",
|
67
|
+
"test/file_test.rb",
|
68
|
+
"test/test_helper.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
79
|
+
end
|
80
|
+
else
|
81
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
82
|
+
end
|
83
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.2
|
@@ -0,0 +1,34 @@
|
|
1
|
+
:debug: false
|
2
|
+
|
3
|
+
:options:
|
4
|
+
# Prompt :never, :once or :always before renaming
|
5
|
+
:interactive: :never
|
6
|
+
:format: '$'
|
7
|
+
:ext_format: '$'
|
8
|
+
|
9
|
+
# Renaming mode: :rename, :copy, :move, :link
|
10
|
+
:mode: :rename
|
11
|
+
:maxdepth: 0
|
12
|
+
|
13
|
+
# used when a value is not available (pdfAuthor for a PNG file, ...)
|
14
|
+
:default_string: '---'
|
15
|
+
|
16
|
+
# Word separator, regular expression statements can be used
|
17
|
+
# default: '\W_'
|
18
|
+
# This string will be used in AbsoluteRenamer just like this :
|
19
|
+
# [^WORD_SEPARATOR]
|
20
|
+
# Then, \W_ => [^\W_]
|
21
|
+
:word_separator: '\W_'
|
22
|
+
|
23
|
+
:path:
|
24
|
+
:modules: absolute_renamer/external/modules
|
25
|
+
:parsers: absolute_renamer/external/parsers
|
26
|
+
:plugins: absolute_renamer/external/plugins
|
27
|
+
|
28
|
+
:parsers:
|
29
|
+
- listing
|
30
|
+
- interactive
|
31
|
+
|
32
|
+
:plugins:
|
33
|
+
- listing
|
34
|
+
- interactive
|
@@ -0,0 +1,122 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'absolute_renamer/config'
|
5
|
+
require 'absolute_renamer/with_children'
|
6
|
+
require 'absolute_renamer/external'
|
7
|
+
require 'absolute_renamer/parser'
|
8
|
+
require 'absolute_renamer/file_info'
|
9
|
+
require 'absolute_renamer/libs/file'
|
10
|
+
require 'absolute_renamer/libs/string'
|
11
|
+
require 'absolute_renamer/use_config'
|
12
|
+
|
13
|
+
# top level module of AbsoluteRenamer.
|
14
|
+
module AbsoluteRenamer
|
15
|
+
VERSION = "0.9.1"
|
16
|
+
|
17
|
+
# The main class of AbsoluteRenamer.
|
18
|
+
#
|
19
|
+
# Organizes the files and directories renaming process.
|
20
|
+
class Processor
|
21
|
+
class << self
|
22
|
+
include AbsoluteRenamer::UseConfig
|
23
|
+
|
24
|
+
# Creates the new names for each file passed to AbsoluteRenamer.
|
25
|
+
#
|
26
|
+
# Asks to each module if he as something to replace
|
27
|
+
# in the name of each file.
|
28
|
+
#
|
29
|
+
# Calls the +before_names_generation+ entry point.
|
30
|
+
def create_names_list
|
31
|
+
call_entry_point(:before_names_generation)
|
32
|
+
return if conf[:files].empty?
|
33
|
+
mods = {}
|
34
|
+
conf[:files].each do |file|
|
35
|
+
name = conf[:options][:format].clone
|
36
|
+
ext = conf[:options][:ext_format].clone
|
37
|
+
do_replacements(file.name, :before)
|
38
|
+
AbsoluteRenamer::IModule.children.each do |mod|
|
39
|
+
mod_sym = mod.symbol
|
40
|
+
mods[mod_sym] ||= mod.new
|
41
|
+
name = mods[mod_sym].process(file, name)
|
42
|
+
ext = mods[mod_sym].process(file, ext, :ext) unless file.dir
|
43
|
+
end
|
44
|
+
do_replacements(name, :after)
|
45
|
+
file.new_name = name
|
46
|
+
file.new_name << '.' << ext unless (file.dir or file.ext.empty?)
|
47
|
+
end
|
48
|
+
if (conf[:options][:dir] and conf[:options][:rec])
|
49
|
+
conf[:files].sort! { |a, b| AbsoluteRenamer::FileInfo.compare_level(a, b) }
|
50
|
+
end
|
51
|
+
mods.clear
|
52
|
+
end
|
53
|
+
|
54
|
+
# For each file/dir replaces his name by his new name.
|
55
|
+
#
|
56
|
+
# Calls the following entry points :
|
57
|
+
# - before_batch_renaming ;
|
58
|
+
# - before_file_renaming ;
|
59
|
+
# - after_file_renaming ;
|
60
|
+
# - after_batch_renaming.
|
61
|
+
def do_renaming
|
62
|
+
if call_entry_point(:before_batch_renaming)
|
63
|
+
conf[:files].each do |file|
|
64
|
+
if call_entry_point(:before_file_renaming, :file => file)
|
65
|
+
if file.respond_to?(conf[:options][:mode])
|
66
|
+
file.send(conf[:options][:mode])
|
67
|
+
end
|
68
|
+
call_entry_point(:after_file_renaming, :file => file)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
call_entry_point(:after_batch_renaming)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Loads the plugins list in the @plugins variable.
|
76
|
+
def load_plugins
|
77
|
+
@plugins = {}
|
78
|
+
AbsoluteRenamer::IPlugin.children.each do |plugin|
|
79
|
+
@plugins[plugin.symbol] = plugin.new
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Calls the given entry point for each plugin available
|
84
|
+
#
|
85
|
+
# Ask to each plugin if it implements the entry point
|
86
|
+
# and calls it with params if it isn't null.
|
87
|
+
# It keeps going will all plugins return true.
|
88
|
+
#
|
89
|
+
# returns true if all plugins returned true
|
90
|
+
def call_entry_point(ep, params = nil)
|
91
|
+
puts "Plugin Entry Point: #{ep}" if conf[:debug]
|
92
|
+
keep_going = true
|
93
|
+
@plugins.each_value do |plugin|
|
94
|
+
if plugin.respond_to?(ep)
|
95
|
+
keep_going &= params.nil? ? plugin.send(ep) : plugin.send(ep, params)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
keep_going
|
99
|
+
end
|
100
|
+
|
101
|
+
# Applies replacements
|
102
|
+
#
|
103
|
+
# The replacements are stored in conf[options][replacements][moment]
|
104
|
+
# and are provided as command line paramters.
|
105
|
+
#
|
106
|
+
# format represents the string in which the replacements are done
|
107
|
+
# moment determines which replacements are done (on old or new name)
|
108
|
+
def do_replacements(format, moment)
|
109
|
+
begin
|
110
|
+
replacements = conf[:options][:replacements][moment]
|
111
|
+
rescue NoMethodError
|
112
|
+
replacements = nil
|
113
|
+
end
|
114
|
+
unless replacements.nil?
|
115
|
+
replacements.each do |repl|
|
116
|
+
format.gsub!(repl[:pattern], repl[:replace])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AbsoluteRenamer
|
4
|
+
# Class handeling the configuration.
|
5
|
+
class Config
|
6
|
+
class << self
|
7
|
+
# Open and load a Yaml file into the +@conf+ variable.
|
8
|
+
# config_path: path of the file to load.
|
9
|
+
def load(config_path)
|
10
|
+
@conf = YAML::load_file(config_path)
|
11
|
+
|
12
|
+
@conf[:options] ||= {}
|
13
|
+
@conf[:options][:format] ||= '$'
|
14
|
+
@conf[:options][:ext_format] ||= '$'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a configuration value identified by +key+.
|
18
|
+
# If +key+ is ignored, returns the +@conf+ hash.
|
19
|
+
def get(key = nil)
|
20
|
+
return @conf[key] if @conf.has_key?(key)
|
21
|
+
return @conf
|
22
|
+
end
|
23
|
+
|
24
|
+
# Sets a configuration value in the +@conf+ variable.
|
25
|
+
def set(key, value = '')
|
26
|
+
@conf[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a configuration value identified by +key+.
|
30
|
+
def [](key)
|
31
|
+
@conf[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sets a configuration value in the +@conf+ variable.
|
35
|
+
def []=(key, value)
|
36
|
+
@conf[key] = value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'absolute_renamer/imodule'
|
2
|
+
require 'absolute_renamer/iplugin'
|
3
|
+
require 'absolute_renamer/use_config'
|
4
|
+
|
5
|
+
module AbsoluteRenamer
|
6
|
+
# Class in charge of loading +modules+ and +plugins+.
|
7
|
+
class External
|
8
|
+
class << self
|
9
|
+
include AbsoluteRenamer::UseConfig
|
10
|
+
|
11
|
+
# Loads the additional and core modules.
|
12
|
+
# The modules list is get from the conf[:modules] variable.
|
13
|
+
# The core modules are loaded after the additional ones.
|
14
|
+
#
|
15
|
+
# See also load
|
16
|
+
def load_modules
|
17
|
+
puts "[Loading modules]" if conf[:debug]
|
18
|
+
|
19
|
+
modules = conf[:modules]
|
20
|
+
load(modules, :modules, 'module.rb') unless modules.nil?
|
21
|
+
|
22
|
+
core_modules = ['case', 'general'].map! { |core_module| File.join('core', core_module) }
|
23
|
+
load(core_modules, :modules, 'module.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Loads the plugins.
|
27
|
+
# The plugins list is get from the conf[:plugins] variable.
|
28
|
+
#
|
29
|
+
# See also load
|
30
|
+
def load_plugins
|
31
|
+
puts "[Loading plugins]" if conf[:debug]
|
32
|
+
|
33
|
+
load(conf[:plugins], :plugins, 'plugin.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Loads an external list (+modules+ or +plugins+)
|
37
|
+
# externals: a list of +externals+ names to load.
|
38
|
+
# type: a symbol defining which type of external to load
|
39
|
+
# file: the filename to require to load the +externals+
|
40
|
+
def load(externals, type, file)
|
41
|
+
ext_dir = conf[:path][type]
|
42
|
+
|
43
|
+
externals.each do |external|
|
44
|
+
ext_to_load = File.join(ext_dir, external, file)
|
45
|
+
begin
|
46
|
+
if require ext_to_load
|
47
|
+
puts "Loaded: #{ext_to_load}" if conf[:debug]
|
48
|
+
end
|
49
|
+
rescue LoadError => e
|
50
|
+
STDERR.puts(e)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module AbsoluteRenamer
|
2
|
+
class CaseModule < AbsoluteRenamer::IModule
|
3
|
+
class << self
|
4
|
+
attr_reader :actions
|
5
|
+
|
6
|
+
def actions
|
7
|
+
@actions ||= {'*' => :camelize,
|
8
|
+
'&' => :upper,
|
9
|
+
'%' => :lower,
|
10
|
+
'$' => :original
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def camelize(str)
|
15
|
+
str.camelize
|
16
|
+
end
|
17
|
+
|
18
|
+
def original(str)
|
19
|
+
str
|
20
|
+
end
|
21
|
+
|
22
|
+
def lower(str)
|
23
|
+
str.downcase
|
24
|
+
end
|
25
|
+
|
26
|
+
def upper(str)
|
27
|
+
str.upcase
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module AbsoluteRenamer
|
2
|
+
class GeneralModule < AbsoluteRenamer::IModule
|
3
|
+
def initialize
|
4
|
+
@actions = {'*' => :file_camelize,
|
5
|
+
'$' => :file_original,
|
6
|
+
'%' => :file_downcase,
|
7
|
+
'&' => :file_upcase,
|
8
|
+
'\\' => :file_strip,
|
9
|
+
'#' => :count
|
10
|
+
}
|
11
|
+
|
12
|
+
@case_filters = ['(\\\\\*)', # \*
|
13
|
+
'(\\\\\$)', # \$
|
14
|
+
'(\\\%)', # \%
|
15
|
+
'(\\\&)', # \&
|
16
|
+
'(\\\\\\\)', # \\
|
17
|
+
'(\*)', # *
|
18
|
+
'(\$)', # $
|
19
|
+
'(%)', # %
|
20
|
+
'(&)', # &
|
21
|
+
'(\\\)' # \
|
22
|
+
]
|
23
|
+
|
24
|
+
# matches strings like [42-43] [42-] [*42-43] [42;43] etc...
|
25
|
+
@part_filters = ['(\[(.)?(\d+)(((-)(\d+)?)|((;)(\d+)))?\])']
|
26
|
+
|
27
|
+
# matches counters like # ### #{2} ##{2;42} or [length-42]
|
28
|
+
@misc_filters = ['(/)', '(#+(\{.*\})?)', '(\[length(--?\d+)?\])']
|
29
|
+
|
30
|
+
@filters = @case_filters + @part_filters + @misc_filters
|
31
|
+
end
|
32
|
+
|
33
|
+
def interpret(file, infos, type)
|
34
|
+
if (infos[0].length == 1)
|
35
|
+
self.method(@actions[infos[0][0].chr]).call(file, infos, type)
|
36
|
+
elsif (infos[0][1..6] == 'length')
|
37
|
+
self.length(file, infos, type)
|
38
|
+
elsif (infos[0][0].chr == '[')
|
39
|
+
self.file_part(file, infos, type)
|
40
|
+
elsif (infos[0][0].chr == '#')
|
41
|
+
self.count(file, infos, type)
|
42
|
+
else
|
43
|
+
infos[0][1].chr
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_camelize(file, infos, type)
|
48
|
+
file.send(type).camelize
|
49
|
+
end
|
50
|
+
|
51
|
+
def file_original(file, infos, type)
|
52
|
+
file.send(type)
|
53
|
+
end
|
54
|
+
|
55
|
+
def file_downcase(file, infos, type)
|
56
|
+
file.send(type).downcase
|
57
|
+
end
|
58
|
+
|
59
|
+
def file_upcase(file, infos, type)
|
60
|
+
file.send(type).upcase
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_strip(file, infos, type)
|
64
|
+
file.send(type).strip
|
65
|
+
end
|
66
|
+
|
67
|
+
def file_part(file, infos, type)
|
68
|
+
matched = infos[0].match(/(\[([^\d])?(\d+)(((;)(\d+))|((-)(\d+)?))?\])/)
|
69
|
+
|
70
|
+
modifier = matched[2]
|
71
|
+
x = matched[3].to_i - 1
|
72
|
+
y = matched[7] || matched[10]
|
73
|
+
y = y.to_i unless y.nil?
|
74
|
+
action = matched[6] || matched[9]
|
75
|
+
|
76
|
+
str = file.send(type)
|
77
|
+
|
78
|
+
if (action == '-')
|
79
|
+
y -= 1 unless y.nil?
|
80
|
+
y ||= str.length
|
81
|
+
val = str[x..y]
|
82
|
+
elsif (action == ';')
|
83
|
+
val = str[x, y]
|
84
|
+
else
|
85
|
+
val = str[x].chr
|
86
|
+
end
|
87
|
+
|
88
|
+
unless modifier.nil?
|
89
|
+
mp = CaseModule.method(CaseModule.actions[modifier])
|
90
|
+
val = mp.call(val)
|
91
|
+
end
|
92
|
+
val
|
93
|
+
end
|
94
|
+
|
95
|
+
def count(file, infos, type)
|
96
|
+
matched = infos[0].match(/(#+)(\{((-?\d+)(;(-?\d+)?)?)?\})?/)
|
97
|
+
@counter ||= []
|
98
|
+
@last ||= nil
|
99
|
+
@current ||= 0
|
100
|
+
|
101
|
+
@current = 0 if @last != file
|
102
|
+
@current += 1 if @last == file
|
103
|
+
|
104
|
+
start = matched[4] || 1
|
105
|
+
step = matched[6] || 1
|
106
|
+
start = start.to_i
|
107
|
+
step = step.to_i
|
108
|
+
|
109
|
+
@counter[@current] ||= {:start => start,
|
110
|
+
:step => step,
|
111
|
+
:current => start - step
|
112
|
+
}
|
113
|
+
|
114
|
+
@counter[@current][:current] += @counter[@current][:step]
|
115
|
+
@last = file
|
116
|
+
val = @counter[@current][:current].to_s.rjust(matched[1].length, '0')
|
117
|
+
val.gsub!(/(0+)-/, '-\1')
|
118
|
+
val
|
119
|
+
end
|
120
|
+
|
121
|
+
def length(file, infos, type)
|
122
|
+
matched = infos[0].match(/\[length(-(-?\d+))?\]/)
|
123
|
+
file.name.length - matched[2].to_i
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# TODO ajouter une option pour la gestion du nombre de points avant l'extension
|
2
|
+
module AbsoluteRenamer
|
3
|
+
class GeneralParser < AbsoluteRenamer::IParser
|
4
|
+
def self.add_options(parser, options)
|
5
|
+
parser.banner << ' [file]...'
|
6
|
+
parser.on_tail('-h', '--help', 'Display this help screen') do
|
7
|
+
puts parser
|
8
|
+
exit 0
|
9
|
+
end
|
10
|
+
|
11
|
+
parser.on('-r', '--replace PATTERN,REPLACEMENT', Array,
|
12
|
+
'String replacement ex:"pattern,replacement" ') do |data|
|
13
|
+
self.add_replacement(data, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
parser.on('-e', '--regexp-replace PATTERN,REPLACEMENT', Array,
|
17
|
+
'String replacement using regexp') do |data|
|
18
|
+
self.add_replacement(data, options, true)
|
19
|
+
end
|
20
|
+
|
21
|
+
parser.on('-f', '--format FORMAT',
|
22
|
+
'Format string used as model') do |format|
|
23
|
+
options[:format] = format
|
24
|
+
@format_given = true
|
25
|
+
end
|
26
|
+
|
27
|
+
parser.on('-x', '--ext-format FORMAT',
|
28
|
+
'Format string used as model for the extension') do |format|
|
29
|
+
options[:ext_format] = format
|
30
|
+
end
|
31
|
+
|
32
|
+
parser.on('-R', '--recursive',
|
33
|
+
'Rename files in subdirectories recursively') do
|
34
|
+
options[:rec] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
parser.on('--maxdepth N', Integer, 'Maximum recursion depth') do |depth|
|
38
|
+
options[:maxdepth] = depth
|
39
|
+
end
|
40
|
+
|
41
|
+
parser.on('-m', '--mode MODE', [:rename, :copy, :move, :link],
|
42
|
+
'Renaming mode. Can be used with --dest DEST.',
|
43
|
+
' rename: simply rename files',
|
44
|
+
' copy: make a copy of each file in DEST with its new name',
|
45
|
+
' move: move each file in DEST with its new name',
|
46
|
+
' link: create a symbolic link to each file in DEST' <<
|
47
|
+
' with its new name') do |mode|
|
48
|
+
options[:mode] = mode
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on('--dest DEST', 'Destination directory' <<
|
52
|
+
' for copy, move and link modes') do |dest|
|
53
|
+
options[:dest] = File.expand_path(dest)
|
54
|
+
end
|
55
|
+
|
56
|
+
parser.on('-d', '--directories', 'Directories handling') do
|
57
|
+
options[:dir] = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.add_replacement(data, options, regexp = false)
|
62
|
+
pattern,replace = data[0..1]
|
63
|
+
replace ||= ''
|
64
|
+
pattern = Regexp.new(pattern) if regexp
|
65
|
+
moment = @format_given.nil? ? :before : :after
|
66
|
+
options[:replacements] ||= {}
|
67
|
+
options[:replacements][moment] ||= []
|
68
|
+
options[:replacements][moment] << {:type => pattern.class,
|
69
|
+
:pattern => pattern,
|
70
|
+
:replace => replace
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module AbsoluteRenamer
|
2
|
+
class InteractiveParser < AbsoluteRenamer::IParser
|
3
|
+
def self.add_options(parser, options)
|
4
|
+
parser.on('-i', 'Prompt before each renamming') do
|
5
|
+
options[:interactive] = :always
|
6
|
+
end
|
7
|
+
|
8
|
+
parser.on('-I', 'Prompt once before batch renamming') do
|
9
|
+
options[:interactive] = :once
|
10
|
+
end
|
11
|
+
|
12
|
+
parser.on('--interactive [WHEN]', [:always, :never, :once],
|
13
|
+
'Prompt according to WHEN: never, once (-I), or always (-i).',
|
14
|
+
'Without WHEN, prompt always') do |w|
|
15
|
+
w = :always if w.nil?
|
16
|
+
options[:interactive] = w
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module AbsoluteRenamer
|
2
|
+
class InteractivePlugin < AbsoluteRenamer::IPlugin
|
3
|
+
def before_batch_renaming
|
4
|
+
if conf[:options][:interactive] == :once
|
5
|
+
conf[:files].each do |file|
|
6
|
+
file.display_change
|
7
|
+
end
|
8
|
+
print "Do you want to rename this files ? [y/N] "
|
9
|
+
begin
|
10
|
+
resp = STDIN.readline.chomp.downcase
|
11
|
+
rescue Exception => e
|
12
|
+
puts "\nExiting renamer"
|
13
|
+
exit(0)
|
14
|
+
end
|
15
|
+
return resp == "y"
|
16
|
+
end
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def before_file_renaming(params)
|
21
|
+
if conf[:options][:interactive] == :always
|
22
|
+
params[:file].display_change
|
23
|
+
print "Do you want to rename this file ? [y/N] "
|
24
|
+
begin
|
25
|
+
resp = STDIN.readline.chomp.downcase
|
26
|
+
rescue Exception => e
|
27
|
+
puts "\nExiting renamer"
|
28
|
+
exit(0)
|
29
|
+
end
|
30
|
+
return resp == "y"
|
31
|
+
end
|
32
|
+
true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module AbsoluteRenamer
|
2
|
+
class ListingPlugin < AbsoluteRenamer::IPlugin
|
3
|
+
def before_batch_renaming
|
4
|
+
listing = conf[:options][:listing] || false
|
5
|
+
if listing
|
6
|
+
conf[:files].each do |file|
|
7
|
+
file.display_change
|
8
|
+
end
|
9
|
+
return false
|
10
|
+
end
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'ftools'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'absolute_renamer/use_config'
|
4
|
+
require 'absolute_renamer/libs/file'
|
5
|
+
|
6
|
+
module AbsoluteRenamer
|
7
|
+
# Class that represents each file to be renamed.
|
8
|
+
# It contains all informations about a file and, in the end,
|
9
|
+
# processes to its renaming.
|
10
|
+
class FileInfo
|
11
|
+
include AbsoluteRenamer::UseConfig
|
12
|
+
|
13
|
+
attr_accessor :name, :new_name,
|
14
|
+
:path, :real_path,
|
15
|
+
:ext, :dir, :dir_path,
|
16
|
+
:level
|
17
|
+
|
18
|
+
# Initializes a FileInfo.
|
19
|
+
# path: the relative or absolute path of the file.
|
20
|
+
def initialize(path)
|
21
|
+
@path = path
|
22
|
+
@real_path = File.expand_path(@path)
|
23
|
+
@dir_path = File.dirname(@real_path)
|
24
|
+
@dir = File.directory?(@real_path)
|
25
|
+
@name = File.basename(@real_path)
|
26
|
+
unless @dir
|
27
|
+
# TODO utiliser une conf :dot
|
28
|
+
@ext = File.extname(@name)
|
29
|
+
@name.gsub!(Regexp.new('.' << @ext << '$'), '') unless @ext.empty?
|
30
|
+
@level = 0
|
31
|
+
else
|
32
|
+
@level = @real_path.split('/').size
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns a description of a FileInfo
|
37
|
+
# some_fileinfo.inspect # => "File: hello_world pdf"
|
38
|
+
def inspect
|
39
|
+
"File: #{@name} #{@ext}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Displays the action that will be done on the file.
|
43
|
+
# some_fileinfo.display_change # => "rename a_file.txt --> A_File.TXT"
|
44
|
+
def display_change
|
45
|
+
puts "#{conf[:options][:mode]} #{@real_path.sub(Dir.pwd+'/', '')} --> #{new_path.sub(Dir.pwd+'/', '')}"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the new path of the file.
|
49
|
+
def new_path
|
50
|
+
if conf[:options][:dest].nil? or conf[:options][:dest].empty?
|
51
|
+
File.join(@dir_path, @new_name)
|
52
|
+
else
|
53
|
+
File.join(conf[:options][:dest], @new_name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Renames the file.
|
58
|
+
def rename
|
59
|
+
display_change
|
60
|
+
File.rename(@real_path, new_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Copies the file.
|
64
|
+
def copy
|
65
|
+
display_change
|
66
|
+
if @dir
|
67
|
+
if @real_path != conf[:options][:dest]
|
68
|
+
FileUtils.cp_r(@real_path, conf[:options][:dest])
|
69
|
+
else
|
70
|
+
puts "#{real_path} ignored"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
File.copy(@real_path, new_path, false)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Moves a file. Moving to the same directories is just like renaming.
|
78
|
+
def move
|
79
|
+
display_change
|
80
|
+
File.move(@real_path, new_path, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Creates a symbolic link to the file.
|
84
|
+
def link
|
85
|
+
display_change
|
86
|
+
begin
|
87
|
+
File.symlink(@real_path, new_path)
|
88
|
+
rescue NotImplemented
|
89
|
+
# TODO trouver mieux
|
90
|
+
puts "Error: cannot create symlinks"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.compare_level(a, b)
|
95
|
+
if (a.level == b.level)
|
96
|
+
return (a.name <= b.name) ? -1 : 1
|
97
|
+
else
|
98
|
+
return (a.level < b.level) ? 1 : -1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'absolute_renamer/with_children'
|
2
|
+
|
3
|
+
module AbsoluteRenamer
|
4
|
+
# Modules parent class.
|
5
|
+
# Modules must inherit of it.
|
6
|
+
class IModule < AbsoluteRenamer::WithChildren
|
7
|
+
def initialize
|
8
|
+
@filters = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the classname symbol
|
12
|
+
def self.symbol
|
13
|
+
name.intern
|
14
|
+
end
|
15
|
+
|
16
|
+
# Process a +file+ by searching for a known pattern in its name
|
17
|
+
# and replacing it by the corresponding value.
|
18
|
+
# The pattern is a regular expression obtained by concatening
|
19
|
+
# the +@filters+ variable with "|".
|
20
|
+
#
|
21
|
+
# file: a FileInfo instance
|
22
|
+
# format: the format string used to rename the file
|
23
|
+
# type: the type of the renaming format (:name or :ext)
|
24
|
+
def process(file, format, type = :name)
|
25
|
+
return format if @filters.empty?
|
26
|
+
|
27
|
+
str = format
|
28
|
+
result = []
|
29
|
+
pattern = Regexp.new(@filters.join('|'))
|
30
|
+
|
31
|
+
idx = str.index(pattern)
|
32
|
+
while idx
|
33
|
+
matched = pattern.match(str).to_a.compact
|
34
|
+
part = str.partition(matched[0])
|
35
|
+
result.push(part[0])
|
36
|
+
val = self.interpret(file, matched, type)
|
37
|
+
result.push(val)
|
38
|
+
str = part[2]
|
39
|
+
idx = str.index(pattern)
|
40
|
+
end
|
41
|
+
result.push(str) unless str.empty?
|
42
|
+
format.replace(result.join)
|
43
|
+
format
|
44
|
+
end
|
45
|
+
|
46
|
+
# Interprets a matched pattern.
|
47
|
+
# Searchs for the corresponding callback
|
48
|
+
# in the current module and call it.
|
49
|
+
#
|
50
|
+
# file: a FileInfo instance
|
51
|
+
# infos: the matched values depending of the pattern
|
52
|
+
# type: the type of the renaming format (:name or :ext)
|
53
|
+
def interpret(file, infos, type)
|
54
|
+
modifier = infos[2]
|
55
|
+
action = infos[3]
|
56
|
+
|
57
|
+
return conf[:options][:default_string] unless self.respond_to?(action.intern)
|
58
|
+
|
59
|
+
ap = self.method(action.intern)
|
60
|
+
val = ap.call(file, infos, type)
|
61
|
+
unless modifier.empty?
|
62
|
+
mp = CaseModule.method(CaseModule.actions[modifier])
|
63
|
+
val = mp.call(val)
|
64
|
+
end
|
65
|
+
val.empty? ? conf[:options][:default_string] : val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Extension of existing File class.
|
2
|
+
class << File
|
3
|
+
# Returns the extension of a file.
|
4
|
+
# path: the path of the file
|
5
|
+
# dot: starting from the end, number of dots to count before cuting extension.
|
6
|
+
def extname(path, dot = 1)
|
7
|
+
pattern = (0...dot).inject('') { |pat,x| pat << '\.[^\.]+' } << '$'
|
8
|
+
ext = File.basename(path).match(pattern).to_s
|
9
|
+
ext.empty? ? "" : ext[1..ext.length]
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Extension of existing String class
|
2
|
+
class String
|
3
|
+
# Returns a camelized version of a string
|
4
|
+
# word_separator: a regular expression used to separate words.
|
5
|
+
# str = "hello.THE world"
|
6
|
+
# str.camelize # => "Hello.The World"
|
7
|
+
# str.camelize(/[\.]/) # => "Hello.The world"
|
8
|
+
# str # => "hello.THE world"
|
9
|
+
def camelize(word_separators = /[\W_]/)
|
10
|
+
self.clone.camelize!(word_separators)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Camelizes a string and returns it.
|
14
|
+
# str = "Hello.THE World"
|
15
|
+
# str.camelize! # => "Hello.The World"
|
16
|
+
# str.camelize!(/[\.]/) # => "Hello.The World"
|
17
|
+
# str # => "Hello.The World"
|
18
|
+
def camelize!(word_separators = /[\W_]/)
|
19
|
+
self.downcase!
|
20
|
+
self.each_char.each_with_index do |c,i|
|
21
|
+
if self[i-1].chr =~ word_separators or i.zero?
|
22
|
+
self[i] = c.upcase if c =~ /[a-z]/
|
23
|
+
end
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'absolute_renamer/iparser'
|
3
|
+
require 'absolute_renamer/use_config'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
module AbsoluteRenamer
|
7
|
+
# Class in charge of the command line parsing.
|
8
|
+
class Parser
|
9
|
+
class << self
|
10
|
+
include AbsoluteRenamer::UseConfig
|
11
|
+
|
12
|
+
# Calls all registred parsers.
|
13
|
+
# The parsers are written in configuration files.
|
14
|
+
# The core parsers are automaticaly added.
|
15
|
+
def parse_cmd_line
|
16
|
+
parsers_dir = conf[:path][:parsers]
|
17
|
+
parsers = conf[:parsers]
|
18
|
+
|
19
|
+
core_parsers = ['general']
|
20
|
+
|
21
|
+
parsers += core_parsers.map! { |core_parser| File.join('core', core_parser) }
|
22
|
+
|
23
|
+
parsers.each do |parser|
|
24
|
+
parser_file = File.join(parsers_dir, parser, 'parser.rb')
|
25
|
+
begin
|
26
|
+
if require parser_file
|
27
|
+
puts "Loaded: #{parser_file}" if conf[:debug]
|
28
|
+
end
|
29
|
+
rescue LoadError => e
|
30
|
+
STDERR.puts(e)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
ARGV.options do |parser|
|
35
|
+
begin
|
36
|
+
list = AbsoluteRenamer::IParser.children
|
37
|
+
list.each do |class_name|
|
38
|
+
class_name.add_options(parser, conf[:options])
|
39
|
+
end
|
40
|
+
parser.parse!
|
41
|
+
rescue RuntimeError => ex
|
42
|
+
STDERR.puts(ex)
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
conf[:files] = self.get_files(ARGV, 0) || []
|
46
|
+
conf[:options][:maxdepth] ||= 0
|
47
|
+
conf[:options][:interactive] ||= :never
|
48
|
+
conf[:options][:mode] ||= :rename
|
49
|
+
pp conf.get if conf[:debug]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Creates a list of all files and directories to rename.
|
54
|
+
# All options that have not been matched are considered as path.
|
55
|
+
# For directories, if the recursive otpion is set to true (conf[:rec] == true),
|
56
|
+
# files are searched in sub directories.
|
57
|
+
#
|
58
|
+
# list: a list of path to explore
|
59
|
+
# depth: maximum recursion depth
|
60
|
+
#
|
61
|
+
# Returns the files/directories list
|
62
|
+
def get_files(list, depth)
|
63
|
+
files = []
|
64
|
+
options = conf[:options]
|
65
|
+
|
66
|
+
list.each do |entry|
|
67
|
+
return files unless File.exists?(entry)
|
68
|
+
is_dir = File.directory?(entry)
|
69
|
+
mod_dir = options[:dir]
|
70
|
+
depth_ok = (depth < options[:maxdepth] or options[:maxdepth].zero?)
|
71
|
+
mod_rec = (options[:rec] and depth_ok)
|
72
|
+
|
73
|
+
add_dir = (is_dir and mod_dir)
|
74
|
+
add_file = (!is_dir and !mod_dir)
|
75
|
+
add_sub = (is_dir and (mod_rec or (!mod_dir and depth < 1)))
|
76
|
+
|
77
|
+
files << FileInfo.new(entry) if (add_dir or add_file)
|
78
|
+
files += self.get_files(self.get_subentries(entry), depth + 1) if (add_sub)
|
79
|
+
end
|
80
|
+
files
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns files and directories contained in +path+.
|
84
|
+
def get_subentries(path)
|
85
|
+
files = Dir.entries(path)
|
86
|
+
files.delete_if { |file| file[0,1] == '.' }
|
87
|
+
files.collect! { |file| path + '/' + file }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'absolute_renamer/use_config'
|
2
|
+
|
3
|
+
module AbsoluteRenamer
|
4
|
+
# Class allowing childs listing.
|
5
|
+
class WithChildren
|
6
|
+
include AbsoluteRenamer::UseConfig
|
7
|
+
|
8
|
+
@children = []
|
9
|
+
class << self
|
10
|
+
attr_reader :children
|
11
|
+
|
12
|
+
# Inheritance callback.
|
13
|
+
# When a class inherit from a WithChildren class, it is added to
|
14
|
+
# the childs list of this class.
|
15
|
+
# This list is available as the +children+ attribute.
|
16
|
+
def inherited(by)
|
17
|
+
@children << by
|
18
|
+
by.instance_variable_set(:@children, [])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class AbsoluterenamerTest < Test::Unit::TestCase
|
4
|
-
should "
|
5
|
-
|
4
|
+
should "be true" do
|
5
|
+
assert true
|
6
6
|
end
|
7
7
|
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConfigTest < Test::Unit::TestCase
|
4
|
+
context "The Config instance" do
|
5
|
+
|
6
|
+
should "exist" do
|
7
|
+
assert_not_nil AbsoluteRenamer::Config
|
8
|
+
end
|
9
|
+
|
10
|
+
should "raise ENOENT if config file not found" do
|
11
|
+
assert_raise(Errno::ENOENT) do
|
12
|
+
AbsoluteRenamer::Config.load('a file that must not be found')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
should "not raise ENOENT if config file is found" do
|
17
|
+
assert_nothing_raised(Errno::ENOENT) do
|
18
|
+
AbsoluteRenamer::Config.load('conf/absrenamer/absrenamer.conf')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with a loaded config file" do
|
23
|
+
setup do
|
24
|
+
AbsoluteRenamer::Config.load('conf/absrenamer/absrenamer.conf')
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to set and get config options" do
|
28
|
+
AbsoluteRenamer::Config.set(:test_key, :test_val)
|
29
|
+
assert_equal(:test_val, AbsoluteRenamer::Config.get(:test_key))
|
30
|
+
end
|
31
|
+
|
32
|
+
should "be able to set and get a config option with the nil key" do
|
33
|
+
AbsoluteRenamer::Config.set(nil, :test_val)
|
34
|
+
assert_equal(:test_val, AbsoluteRenamer::Config.get(nil))
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to set config options using []" do
|
38
|
+
AbsoluteRenamer::Config[:test_key] = :test_val
|
39
|
+
assert_equal(:test_val, AbsoluteRenamer::Config[:test_key])
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FileInfoTest < Test::Unit::TestCase
|
4
|
+
context "A FileInfo instance" do
|
5
|
+
context "loaded with some/path/to/a_file.txt" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@pwd = Dir.pwd
|
9
|
+
@fileinfo = AbsoluteRenamer::FileInfo.new('some/path/to/a_file.txt')
|
10
|
+
end
|
11
|
+
|
12
|
+
should "have as name : a_file" do
|
13
|
+
assert_equal('a_file', @fileinfo.name)
|
14
|
+
end
|
15
|
+
|
16
|
+
should "have as dir_path : pwd/some/path/to" do
|
17
|
+
assert_equal(@pwd + '/some/path/to', @fileinfo.dir_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "have as path : some/path/to/a_file.txt" do
|
21
|
+
assert_equal('some/path/to/a_file.txt', @fileinfo.path)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "have as real_path : pwd/some/path/to/a_file.txt" do
|
25
|
+
assert_equal(@pwd + '/some/path/to/a_file.txt', @fileinfo.real_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
should "have as ext : txt" do
|
29
|
+
assert_equal('txt', @fileinfo.ext)
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have as dir : false" do
|
33
|
+
assert_equal(false, @fileinfo.dir)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "loaded with lib/absolute_renamer" do
|
39
|
+
|
40
|
+
setup do
|
41
|
+
@pwd = Dir.pwd
|
42
|
+
@fileinfo = AbsoluteRenamer::FileInfo.new('lib/absolute_renamer')
|
43
|
+
end
|
44
|
+
|
45
|
+
should "have as name : absolute_renamer" do
|
46
|
+
assert_equal('absolute_renamer', @fileinfo.name)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "have as dir_path : pwd/lib" do
|
50
|
+
assert_equal(@pwd + '/lib', @fileinfo.dir_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
should "have as path : lib/absolute_renamer" do
|
54
|
+
assert_equal('lib/absolute_renamer', @fileinfo.path)
|
55
|
+
end
|
56
|
+
|
57
|
+
should "have as real_path : pwd/lib/absolute_renamer" do
|
58
|
+
assert_equal(@pwd + '/lib/absolute_renamer', @fileinfo.real_path)
|
59
|
+
end
|
60
|
+
|
61
|
+
should "have as ext : nil" do
|
62
|
+
assert_nil @fileinfo.ext
|
63
|
+
end
|
64
|
+
|
65
|
+
should "have as dir : true" do
|
66
|
+
assert_equal(true, @fileinfo.dir)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/test/file_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Called LibFileTest instead of FileTest to avoid ruby errors
|
4
|
+
class LibFileTest < Test::Unit::TestCase
|
5
|
+
context "The File class" do
|
6
|
+
|
7
|
+
should "return txt for a_file.txt when calling extname" do
|
8
|
+
assert_equal("txt", File.extname('a_file.txt'))
|
9
|
+
end
|
10
|
+
|
11
|
+
should "return an empty string for a_file when calling extname" do
|
12
|
+
assert_equal("", File.extname('a_file'))
|
13
|
+
end
|
14
|
+
|
15
|
+
should "return tar.gz for archive.tar.gz when calling extname with 2 dots" do
|
16
|
+
assert_equal("tar.gz", File.extname('archive.tar.gz', 2))
|
17
|
+
end
|
18
|
+
|
19
|
+
should "return gz for archive.tar.gz when calling extname" do
|
20
|
+
assert_equal("gz", File.extname('archive.tar.gz'))
|
21
|
+
end
|
22
|
+
|
23
|
+
should "return an empty string for . and a_file. when calling extname" do
|
24
|
+
assert_equal("", File.extname('.'))
|
25
|
+
assert_equal("", File.extname('fichier.'))
|
26
|
+
end
|
27
|
+
|
28
|
+
should "return test for .test when calling extname" do
|
29
|
+
assert_equal("test", File.extname('.test'))
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simonc-AbsoluteRenamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon COURTOIS
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-22 00:00:00 -07:00
|
13
13
|
default_executable: absrenamer
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -34,10 +34,36 @@ extra_rdoc_files:
|
|
34
34
|
files:
|
35
35
|
- .document
|
36
36
|
- .gitignore
|
37
|
+
- AbsoluteRenamer.gemspec
|
37
38
|
- LICENSE
|
38
39
|
- README.rdoc
|
39
40
|
- Rakefile
|
40
41
|
- VERSION
|
42
|
+
- bin/absrenamer
|
43
|
+
- conf/absrenamer/absrenamer.conf
|
44
|
+
- lib/absolute_renamer.rb
|
45
|
+
- lib/absolute_renamer/config.rb
|
46
|
+
- lib/absolute_renamer/external.rb
|
47
|
+
- lib/absolute_renamer/external/modules/core/case/module.rb
|
48
|
+
- lib/absolute_renamer/external/modules/core/general/module.rb
|
49
|
+
- lib/absolute_renamer/external/parsers/core/general/parser.rb
|
50
|
+
- lib/absolute_renamer/external/parsers/interactive/parser.rb
|
51
|
+
- lib/absolute_renamer/external/parsers/listing/parser.rb
|
52
|
+
- lib/absolute_renamer/external/plugins/interactive/plugin.rb
|
53
|
+
- lib/absolute_renamer/external/plugins/listing/plugin.rb
|
54
|
+
- lib/absolute_renamer/file_info.rb
|
55
|
+
- lib/absolute_renamer/imodule.rb
|
56
|
+
- lib/absolute_renamer/iparser.rb
|
57
|
+
- lib/absolute_renamer/iplugin.rb
|
58
|
+
- lib/absolute_renamer/libs/file.rb
|
59
|
+
- lib/absolute_renamer/libs/string.rb
|
60
|
+
- lib/absolute_renamer/parser.rb
|
61
|
+
- lib/absolute_renamer/use_config.rb
|
62
|
+
- lib/absolute_renamer/with_children.rb
|
63
|
+
- test/absolute_renamer_test.rb
|
64
|
+
- test/config_test.rb
|
65
|
+
- test/file_info_test.rb
|
66
|
+
- test/file_test.rb
|
41
67
|
- test/test_helper.rb
|
42
68
|
has_rdoc: false
|
43
69
|
homepage: http://github.com/simonc/AbsoluteRenamer
|
@@ -68,4 +94,7 @@ specification_version: 3
|
|
68
94
|
summary: AbsoluteRenamer is a very powerful tool that helps files and directories renaming using the Krename syntax.
|
69
95
|
test_files:
|
70
96
|
- test/absolute_renamer_test.rb
|
97
|
+
- test/config_test.rb
|
98
|
+
- test/file_info_test.rb
|
99
|
+
- test/file_test.rb
|
71
100
|
- test/test_helper.rb
|