renmov 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/renmov CHANGED
@@ -8,5 +8,5 @@ rescue LoadError
8
8
  end
9
9
 
10
10
  cli = Renmov::CLI.new
11
- cli.parse_options
12
- cli.run
11
+ exit_status = cli.run
12
+ exit exit_status
@@ -67,3 +67,39 @@ Feature: Options
67
67
 
68
68
  Usage: renmov [options] filename...
69
69
  """
70
+
71
+ Scenario: no arguments/options
72
+ Given a blank slate
73
+ When I run `renmov`
74
+ Then the exit status should be 1
75
+ And the stderr should contain:
76
+ """
77
+ renmov: no filename(s) provided
78
+ Rename video files to a consistent format.
79
+
80
+ Usage: renmov [options] filename...
81
+ """
82
+
83
+ Scenario: invalid option (short)
84
+ Given a blank slate
85
+ When I run `renmov -i`
86
+ Then the exit status should be 1
87
+ And the stderr should contain:
88
+ """
89
+ renmov: invalid option: -i
90
+ Rename video files to a consistent format.
91
+
92
+ Usage: renmov [options] filename...
93
+ """
94
+
95
+ Scenario: invalid option (long)
96
+ Given a blank slate
97
+ When I run `renmov --invalid`
98
+ Then the exit status should be 1
99
+ And the stderr should contain:
100
+ """
101
+ renmov: invalid option: --invalid
102
+ Rename video files to a consistent format.
103
+
104
+ Usage: renmov [options] filename...
105
+ """
@@ -14,3 +14,8 @@ Feature: Rename Files
14
14
  | TV.Show.S01E02.HDTV.x264-LOL.[VTV].mp4 | tv.show.s01e02.mp4 |
15
15
  | The.TV.Show.S01E02.[VTV].avi | tv.show.s01e02.avi |
16
16
  | TV.Show.2012.S01E02.x264-LOL.mp4 | tv.show.s01e02.mp4 |
17
+
18
+ Scenario: same file name
19
+ Given an empty file named "tv.show.s01e01.mp4"
20
+ When I successfully run `renmov tv.show.s01e01.mp4`
21
+ Then a file named "tv.show.s01e01.mp4" should exist
data/lib/renmov.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'renmov/basic_renamer'
2
2
  require 'renmov/cli'
3
+ require 'renmov/errors'
3
4
  require 'renmov/version'
4
5
 
5
6
  module Renmov
@@ -1,6 +1,7 @@
1
1
  module Renmov
2
2
  class BasicRenamer
3
3
  attr_reader :filename
4
+
4
5
  def initialize(filename)
5
6
  @filename = filename.downcase
6
7
  end
@@ -38,7 +39,7 @@ module Renmov
38
39
 
39
40
  def get_format
40
41
  format = filename.dup
41
- format.gsub!(/.*\.(...)\z/, '\1')
42
+ format.gsub!(/.*\.(.*)\z/, '\1')
42
43
 
43
44
  format
44
45
  end
data/lib/renmov/cli.rb CHANGED
@@ -1,65 +1,92 @@
1
1
  require 'optparse'
2
2
  require 'fileutils'
3
3
  require 'renmov/basic_renamer'
4
+ require 'renmov/errors'
4
5
 
5
6
  module Renmov
6
7
  class CLI
7
- attr_reader :args
8
- attr_accessor :options
9
- attr_accessor :filenames
10
- attr_accessor :renamer
8
+ attr_reader :executable_name, :args, :options, :optparse
9
+ attr_accessor :filenames, :renamer
11
10
 
12
11
  def initialize(args = ARGV, renamer = BasicRenamer)
12
+ @executable_name = File.basename($PROGRAM_NAME, '.rb')
13
13
  @args = args
14
- @filenames = []
15
14
  @options = { verbose: false, noop: false }
15
+ @optparse = OptionParser.new
16
+ @filenames = []
16
17
  @renamer = renamer
17
18
  end
18
19
 
19
- def parse_options
20
- optparse = OptionParser.new do |opts|
21
- executable_name = File.basename($PROGRAM_NAME, '.rb')
22
- opts.banner = <<EOL
23
- Rename video files to a consistent format.
20
+ def run
21
+ exit_status = 0
24
22
 
25
- Usage: #{executable_name} [options] filename...
26
- EOL
23
+ begin
24
+ parse_options
25
+ raise NoFilenameError if filenames.empty?
27
26
 
28
- opts.on('-v', '--verbose', 'Output more information') do
29
- options[:verbose] = true
30
- end
27
+ filenames.each do |filename|
28
+ dirname = "#{File.dirname(filename)}/"
29
+ dirname.gsub!(/\A\.\/\z/, '')
30
+
31
+ basename = File.basename(filename)
32
+ renamer_i = renamer.new(basename)
33
+ newname = "#{dirname}#{renamer_i.rename}"
31
34
 
32
- opts.on('-n', '--noop', 'Output actions without invoking them') do
33
- options[:noop] = true
34
- options[:verbose] = true
35
+ rename_file(filename, newname)
35
36
  end
37
+ rescue OptionParser::InvalidOption => e
38
+ output_error_message(e)
39
+ exit_status = 1
40
+ rescue NoFilenameError => e
41
+ output_error_message(e)
42
+ exit_status = 1
43
+ end
36
44
 
37
- opts.on_tail('-h', '--help', 'Show this message') do
38
- puts opts
39
- exit
40
- end
45
+ exit_status
46
+ end
41
47
 
42
- opts.on_tail('--version', 'Show version') do
43
- puts Renmov::VERSION
44
- exit
45
- end
48
+ def parse_options
49
+ optparse.banner =
50
+ ['Rename video files to a consistent format.', '',
51
+ "Usage: #{executable_name} [options] filename..."].join("\n")
52
+
53
+ optparse.on('-v', '--verbose',
54
+ 'Output more information') do
55
+ options[:verbose] = true
56
+ end
57
+
58
+ optparse.on('-n', '--noop',
59
+ 'Output actions without invoking them') do
60
+ options[:noop] = true
61
+ options[:verbose] = true
62
+ end
63
+
64
+ optparse.on_tail('-h', '--help',
65
+ 'Show this message') do
66
+ puts optparse
67
+ exit
68
+ end
69
+
70
+ optparse.on_tail('--version',
71
+ 'Show version') do
72
+ puts Renmov::VERSION
73
+ exit
46
74
  end
47
75
 
48
76
  self.filenames = optparse.parse! args
49
77
  end
50
78
 
51
- def run
52
- filenames.each do |filename|
53
- dirname = "#{File.dirname(filename)}/"
54
- dirname.gsub!(/\A\.\/\z/, '')
55
-
56
- basename = File.basename(filename)
57
- renamer_i = renamer.new(basename)
58
- newname = "#{dirname}#{renamer_i.rename}"
59
- FileUtils.mv(filename,
60
- newname,
79
+ def output_error_message(msg)
80
+ $stderr.puts "#{executable_name}: #{msg}"
81
+ $stderr.puts optparse
82
+ end
83
+
84
+ def rename_file(old, new)
85
+ unless old == new
86
+ FileUtils.mv(old,
87
+ new,
61
88
  verbose: options[:verbose],
62
- noop: options[:noop])
89
+ noop: options[:noop])
63
90
  end
64
91
  end
65
92
  end
@@ -0,0 +1,7 @@
1
+ module Renmov
2
+ class NoFilenameError < StandardError
3
+ def to_s
4
+ 'no filename(s) provided'
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Renmov
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -3,22 +3,107 @@ require 'fileutils'
3
3
 
4
4
  module Renmov
5
5
  describe CLI do
6
- describe '#parse_options' do
7
- let(:default_options) { { verbose: false, noop: false } }
6
+ describe '#run' do
7
+ let(:tmpdir) { File.expand_path('../../../tmp', __FILE__) }
8
8
 
9
+ before(:each) do
10
+ filenames.each { |f| FileUtils.rm(f) if File.exists?(f) }
11
+ newnames.each { |f| FileUtils.rm(f) if File.exists?(f) }
12
+
13
+ FileUtils.touch(filenames) unless filenames.empty?
14
+ cli = CLI.new(filenames)
15
+ @exit_status = cli.run
16
+ end
17
+
18
+ context 'no filename provided' do
19
+ let(:filenames) { [] }
20
+ let(:newnames) { [] }
21
+
22
+ it 'exits with a status of 1' do
23
+ @exit_status.should == 1
24
+ end
25
+ end
26
+
27
+ context 'one filename provided' do
28
+ context 'filename different than newname' do
29
+ let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4"] }
30
+ let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
31
+
32
+ it 'properly renames file' do
33
+ File.should_not exist(filenames[0])
34
+ File.should exist(newnames[0])
35
+ end
36
+
37
+ it 'exits with a status of 0' do
38
+ @exit_status.should == 0
39
+ end
40
+ end
41
+
42
+ context 'filename same as newname' do
43
+ let(:filenames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
44
+ let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
45
+
46
+ it 'does not rename file' do
47
+ File.should exist(newnames[0])
48
+ end
49
+
50
+ it 'exits with a status of 0' do
51
+ @exit_status.should == 0
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'multiple filenames provided' do
57
+ context 'filenames different than newnames' do
58
+ let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
59
+ "#{tmpdir}/The.TV.Show.S02E03.LOL.avi"] }
60
+ let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
61
+ "#{tmpdir}/tv.show.s02e03.avi"] }
62
+
63
+ it 'properly renames all files' do
64
+ filenames.each { |f| File.should_not exist(f) }
65
+ newnames.each { |n| File.should exist(n) }
66
+ end
67
+
68
+ it 'exits with a status of 0' do
69
+ @exit_status.should == 0
70
+ end
71
+ end
72
+
73
+ context 'one filename same as and one filename different than newnames' do
74
+ let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
75
+ "#{tmpdir}/tv.show.s02e03.avi"] }
76
+ let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
77
+ "#{tmpdir}/tv.show.s02e03.avi"] }
78
+
79
+ it 'properly renames first file and not second file' do
80
+ File.should_not exist(filenames[0])
81
+ File.should exist(filenames[1])
82
+ newnames.each { |n| File.should exist(n) }
83
+ end
84
+
85
+ it 'exits with a status of 0' do
86
+ @exit_status.should == 0
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '#parse_options' do
9
93
  before(:each) do
10
94
  @cli = CLI.new(options + filenames)
95
+ @default_options = @cli.options
11
96
  @cli.parse_options
12
97
  end
13
98
 
14
- context 'with no options provided' do
99
+ context 'no options provided' do
15
100
  let(:options) { [] }
16
101
 
17
- context 'with no filenames provided' do
102
+ context 'no filenames provided' do
18
103
  let(:filenames) { [] }
19
104
 
20
105
  it 'keeps default options' do
21
- @cli.options.should == default_options
106
+ @cli.options.should == @default_options
22
107
  end
23
108
 
24
109
  it 'sets filenames to []' do
@@ -26,11 +111,11 @@ module Renmov
26
111
  end
27
112
  end
28
113
 
29
- context 'with one filename provided' do
114
+ context 'one filename provided' do
30
115
  let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
31
116
 
32
117
  it 'keeps default options' do
33
- @cli.options.should == default_options
118
+ @cli.options.should == @default_options
34
119
  end
35
120
 
36
121
  it 'sets filenames to filename provided' do
@@ -39,14 +124,14 @@ module Renmov
39
124
  end
40
125
  end
41
126
 
42
- context 'with verbose option provided' do
127
+ context 'verbose option provided' do
43
128
  let(:options) { ['-v'] }
44
129
 
45
- context 'with no filenames provided' do
130
+ context 'no filenames provided' do
46
131
  let(:filenames) { [] }
47
132
 
48
133
  it 'merges verbose with default options' do
49
- @cli.options.should == default_options.merge(verbose: true)
134
+ @cli.options.should == @default_options.merge(verbose: true)
50
135
  end
51
136
 
52
137
  it 'sets filenames to []' do
@@ -54,11 +139,11 @@ module Renmov
54
139
  end
55
140
  end
56
141
 
57
- context 'with one filename provided' do
142
+ context 'one filename provided' do
58
143
  let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
59
144
 
60
145
  it 'merges verbose with default options' do
61
- @cli.options.should == default_options.merge(verbose: true)
146
+ @cli.options.should == @default_options.merge(verbose: true)
62
147
  end
63
148
 
64
149
  it 'sets filenames to filename provided' do
@@ -67,14 +152,14 @@ module Renmov
67
152
  end
68
153
  end
69
154
 
70
- context 'with noop option provided' do
155
+ context 'noop option provided' do
71
156
  let(:options) { ['-n'] }
72
157
 
73
- context 'with no filenames provided' do
158
+ context 'no filenames provided' do
74
159
  let(:filenames) { [] }
75
160
 
76
161
  it 'merges verbose and noop with default options' do
77
- @cli.options.should == default_options.merge(verbose: true,
162
+ @cli.options.should == @default_options.merge(verbose: true,
78
163
  noop: true)
79
164
  end
80
165
 
@@ -83,11 +168,11 @@ module Renmov
83
168
  end
84
169
  end
85
170
 
86
- context 'with one filename provided' do
171
+ context 'one filename provided' do
87
172
  let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
88
173
 
89
174
  it 'merges verbose and noop with default options' do
90
- @cli.options.should == default_options.merge(verbose: true,
175
+ @cli.options.should == @default_options.merge(verbose: true,
91
176
  noop: true)
92
177
  end
93
178
 
@@ -97,45 +182,5 @@ module Renmov
97
182
  end
98
183
  end
99
184
  end
100
-
101
- describe '#run' do
102
- let(:tmpdir) { File.expand_path('../../../tmp', __FILE__) }
103
-
104
- before(:each) do
105
- filenames.each do |filename|
106
- FileUtils.rm(filename) if File.exists?(filename)
107
- end
108
- newnames.each do |newname|
109
- FileUtils.rm(newname) if File.exists?(newname)
110
- end
111
-
112
- FileUtils.touch(filenames)
113
- cli = CLI.new(filenames)
114
- cli.parse_options
115
- cli.run
116
- end
117
-
118
- context 'with one filename provided' do
119
- let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4"] }
120
- let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
121
-
122
- it 'properly renames file' do
123
- File.exists?(filenames[0]).should_not be_true
124
- File.exists?(newnames[0]).should be_true
125
- end
126
- end
127
-
128
- context 'with multiple filenames provided' do
129
- let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
130
- "#{tmpdir}/The.TV.Show.S02E03.LOL.avi"] }
131
- let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
132
- "#{tmpdir}/tv.show.s02e03.avi"] }
133
-
134
- it 'properly renames all files' do
135
- filenames.each { |f| File.exists?(f).should_not be_true }
136
- newnames.each { |n| File.exists?(n).should be_true }
137
- end
138
- end
139
- end
140
185
  end
141
186
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renmov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -75,6 +75,7 @@ files:
75
75
  - lib/renmov.rb
76
76
  - lib/renmov/basic_renamer.rb
77
77
  - lib/renmov/cli.rb
78
+ - lib/renmov/errors.rb
78
79
  - lib/renmov/version.rb
79
80
  - renmov.gemspec
80
81
  - spec/renmov/basic_renamer_spec.rb
@@ -104,7 +105,7 @@ rubyforge_project:
104
105
  rubygems_version: 1.8.24
105
106
  signing_key:
106
107
  specification_version: 3
107
- summary: renmov-0.0.3
108
+ summary: renmov-0.1.0
108
109
  test_files:
109
110
  - features/options.feature
110
111
  - features/rename_files.feature