aef-bakker 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,23 @@
1
+ === 1.1.0 / 2009-04-05
2
+
3
+ * 1 major enhancement
4
+
5
+ * Namespaced into module Aef
6
+
7
+ * 5 minor enhancements
8
+
9
+ * Better metadata for gem
10
+ * Test refactoring
11
+ * Minor refactorings
12
+ * Improved documentation
13
+ * Added test for --version command
14
+
15
+ * 1 minor bugfix
16
+
17
+ * Fixed some bugs related to Ruby 1.8.6
18
+
19
+ === 1.0.0 / 2009-03-01
20
+
21
+ * 1 major enhancement
22
+
23
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,9 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ COPYING.txt
5
+ Rakefile
6
+ bin/bakker
7
+ lib/bakker.rb
8
+ lib/bakker/bakker.rb
9
+ spec/bakker_spec.rb
data/README.rdoc ADDED
@@ -0,0 +1,206 @@
1
+ = Bakker
2
+
3
+ * Project: https://rubyforge.org/projects/aef/
4
+ * RDoc: http://aef.rubyforge.org/bakker/
5
+ * Github: http://github.com/aef/bakker/
6
+
7
+ == DESCRIPTION:
8
+
9
+ Bakker is a Ruby library and commandline tool to help with simple task of
10
+ renaming or copying files for quick backup purposes. For instance by creating
11
+ a copy of a list of files while adding .bak to the copies filenames. Bakker
12
+ gives you control over the extension to be added to or removed from the file
13
+ and whether it should be moved or copied.
14
+
15
+ == FEATURES/PROBLEMS:
16
+
17
+ * Usable as library and commandline tool
18
+ * Tested and fully working on:
19
+ * Ubuntu Linux 8.10 i386_64 (Ruby 1.8.7 and 1.9.1p0)
20
+ * Debian GNU/Linux 4.0 i386 (Ruby 1.8.6)
21
+ * On Windows XP i386 (Ruby 1.8.6)
22
+ * On Windows XP i386 (Ruby 1.8.6) there were some problems testing the
23
+ environment variable choices. Two tests are failing but the programs seems
24
+ to work correctly. If anyone finds the problem, please contact me.
25
+ * The commandline tool doesn't work with Ruby 1.9.x because the user-choices gem
26
+ is not yet updated. A patch is available here:
27
+ https://rubyforge.org/tracker/index.php?func=detail&aid=24307&group_id=4192&atid=16176
28
+
29
+ == SYNOPSIS:
30
+
31
+ === Commandline
32
+
33
+ The following command renames config.ini to config.ini.bak. You can type the
34
+ same command a second time to revert the action:
35
+
36
+ bakker config.ini
37
+
38
+ Instead of renaming you can create a copy of config.xml by using the following
39
+ command:
40
+
41
+ bakker -a copy config.ini
42
+
43
+ To change the extension which will be appended or removed from the filename use
44
+ the following command:
45
+
46
+ bakker -e .backup
47
+
48
+ In a directory with the follwing contents:
49
+
50
+ demo1
51
+ demo2.bak
52
+ demo3.bak
53
+
54
+ if you use the command:
55
+
56
+ bakker *
57
+
58
+ you get the following list of files (because by default Bakker toggles the
59
+ extension):
60
+
61
+ demo1.bak
62
+ demo2
63
+ demo3
64
+
65
+ if you now want every file in the folder to have a .bak extension use the
66
+ following command:
67
+
68
+ bakker -m add *
69
+
70
+ the result will look like this:
71
+
72
+ demo1.bak
73
+ demo2.bak
74
+ demo3.bak
75
+
76
+ Instead of using the add-mode you could have used the remove-mode like this:
77
+
78
+ bakker -m remove *
79
+
80
+ Then the result would have looked like this:
81
+
82
+ demo1
83
+ demo2
84
+ demo3
85
+
86
+ Bakker also includes a verbose mode which will inform you of any file transfer
87
+ in the console:
88
+
89
+ bakker -v config.ini
90
+
91
+ You can specify default values for extension, action, mode and even for the
92
+ verbose mode by using environment variables. Notice that you can still override
93
+ these by using commandline switches. A list of the variables:
94
+
95
+ * BAKKER_MODE
96
+ * BAKKER_ACTION
97
+ * BAKKER_EXTENSION
98
+ * BAKKER_VERBOSE
99
+
100
+ === Library
101
+
102
+ Load the gem:
103
+
104
+ require 'bakker'
105
+
106
+ Call Bakker:
107
+
108
+ Aef::Bakker.process('config.ini', '.backup', :add, :copy)
109
+
110
+ == REQUIREMENTS:
111
+
112
+ * rubygems
113
+
114
+ === Additional for commandline
115
+ * user-choices
116
+
117
+ === Additional for automated testing
118
+ * hoe
119
+ * rspec
120
+ * sys-uname
121
+
122
+ == INSTALL:
123
+
124
+ === Normal
125
+
126
+ gem install bakker
127
+
128
+ Additionally for the commandline tool:
129
+
130
+ gem install user-choices
131
+
132
+ === High security (recommended)
133
+
134
+ There is a high security installation option available through rubygems. It is
135
+ highly recommended over the normal installation, although it may be a bit less
136
+ comfortable. To use the installation method, you will need my public key, which
137
+ I use for cryptographic signatures on all my gems. You can find the public key
138
+ and more detailed verification information in the aef-certificates section of my
139
+ rubyforge project[https://rubyforge.org/frs/?group_id=7890&release_id=31749]
140
+
141
+ Add the key to your rubygems' trusted certificates by the following command:
142
+
143
+ gem cert --add aef.pem
144
+
145
+ Now you can install the gem while automatically verifying it's signature by the
146
+ following command:
147
+
148
+ gem install bakker --ignore-dependencies -P HighSecurity
149
+
150
+ Please notice that you will need other keys for dependent libraries, so you may
151
+ have to install dependencies manually.
152
+
153
+ === Automated testing
154
+
155
+ You can test this package through rspec on your system. First find the path
156
+ where the gem was installed to:
157
+
158
+ gem which bakker
159
+
160
+ Go into the root directory of the installed gem and run the following command
161
+ to start the test runner:
162
+
163
+ rake spec
164
+
165
+ On Windows systems you have to run the following instead:
166
+
167
+ spec spec/**/*_spec.rb
168
+
169
+ If something goes wrong you should be noticed through failing examples.
170
+
171
+ == DEVELOPMENT:
172
+
173
+ This software is developed in the source code management system git hosted
174
+ at github.com. You can download the most recent sourcecode through the following
175
+ command:
176
+
177
+ git clone git://github.com/aef/bakker.git
178
+
179
+ Help on making this software better is always very appreciated. If you want your
180
+ changes to be included in the official release, please send me a patch through
181
+ the project's tracker[https://rubyforge.org/tracker/?group_id=7890] at
182
+ rubyforge.org. You can generate a patch-file by the following command:
183
+
184
+ git diff > patch.diff
185
+
186
+ Please make sure to write tests for your changes and notice that I can't promise
187
+ to include your changes before reviewing them.
188
+
189
+ == LICENSE:
190
+
191
+ Copyright 2009 Alexander E. Fischer <aef@raxys.net>
192
+
193
+ This file is part of Bakker.
194
+
195
+ Bakker is free software: you can redistribute it and/or modify
196
+ it under the terms of the GNU General Public License as published by
197
+ the Free Software Foundation, either version 3 of the License, or
198
+ (at your option) any later version.
199
+
200
+ This program is distributed in the hope that it will be useful,
201
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
202
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
203
+ GNU General Public License for more details.
204
+
205
+ You should have received a copy of the GNU General Public License
206
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/bakker.rb'
6
+
7
+ Hoe.new('bakker', Aef::Bakker::VERSION) do |p|
8
+ p.rubyforge_name = 'aef'
9
+ p.developer('Alexander E. Fischer', 'aef@raxys.net')
10
+ p.extra_dev_deps = %w{user-choices rspec sys-uname}
11
+ p.url = 'https://rubyforge.org/projects/aef/'
12
+ p.readme_file = 'README.rdoc'
13
+ p.extra_rdoc_files = %w{README.rdoc}
14
+ p.spec_extras = {
15
+ :rdoc_options => ['--main', 'README.rdoc', '--inline-source', '--line-numbers', '--title', 'Bakker']
16
+ }
17
+ end
18
+
19
+ # vim: syntax=Ruby
data/bin/bakker ADDED
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright 2009 Alexander E. Fischer <aef@raxys.net>
4
+ #
5
+ # This file is part of Bakker.
6
+ #
7
+ # Bakker is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ # TODO: If user-choices patch gets accepted, use :one_way => true for --version
21
+ # TODO: If user-choices patch gets accepted, use :upcase for environment variables
22
+
23
+ # If library is not locally accessible, use gem to include it.
24
+ begin
25
+ require 'lib/bakker'
26
+ rescue LoadError
27
+ require 'rubygems'
28
+ require 'bakker'
29
+ end
30
+
31
+ # User friendly message if user-choices is not available
32
+ begin
33
+ require 'user-choices'
34
+ rescue LoadError
35
+ warn "This command needs the user-choices gem to be installed.\n\nSolution: gem install user-choices"
36
+ exit false
37
+ end
38
+
39
+ # Application class for commandline interface
40
+ class Aef::Bakker::Application < UserChoices::Command
41
+ include UserChoices
42
+
43
+ # Prepare configuration sources
44
+ def add_sources(builder)
45
+ builder.add_source(CommandLineSource, :usage,
46
+ "Usage: #$PROGRAM_NAME [options] files\n\n",
47
+ "You can set the default behavior through environment variables:\n",
48
+ "BAKKER_MODE (#{Aef::Bakker::MODES.join(', ')}. Default: #{Aef::Bakker::MODES.first})",
49
+ "BAKKER_ACTION (#{Aef::Bakker::ACTIONS.join(', ')}. Default: #{Aef::Bakker::ACTIONS.first})",
50
+ 'BAKKER_EXTENSION (Default: .bak)',
51
+ "BAKKER_VERBOSE (true, false. Default: false)\n"
52
+ )
53
+
54
+ # Hopefully possible with next release of user-choices
55
+ # builder.add_source(ExtendedEnvironmentSource, :upcase, :with_prefix, 'BAKKER_')
56
+
57
+ builder.add_source(EnvironmentSource, :mapping,
58
+ :mode => 'BAKKER_MODE',
59
+ :action => 'BAKKER_ACTION',
60
+ :extension => 'BAKKER_EXTENSION',
61
+ :verbose => 'BAKKER_VERBOSE'
62
+ )
63
+ end
64
+
65
+ # Define configuration options
66
+ def add_choices(builder)
67
+ builder.add_choice(:mode, :type => Aef::Bakker::MODES.map{|item| item.to_s}, :default => Aef::Bakker::MODES.first.to_s) do |cli|
68
+ cli.uses_option('-m', '--mode MODE',
69
+ "Processing mode. Can be one of: #{Aef::Bakker::MODES.join(', ')}. " +
70
+ "Default: #{Aef::Bakker::MODES.first}")
71
+ end
72
+
73
+ builder.add_choice(:action, :type => Aef::Bakker::ACTIONS.map{|item| item.to_s}, :default => Aef::Bakker::ACTIONS.first.to_s) do |cli|
74
+ cli.uses_option('-a', '--action ACTION',
75
+ "Filesystem action. Can be one of: #{Aef::Bakker::ACTIONS.join(', ')}. " +
76
+ "Default: #{Aef::Bakker::ACTIONS.first}")
77
+ end
78
+
79
+ builder.add_choice(:extension, :default => Aef::Bakker::DEFAULT_EXTENSION) do |cli|
80
+ cli.uses_option('-e', '--extension EXTENSION',
81
+ "Suffix to be added/removed"
82
+ )
83
+ end
84
+
85
+ builder.add_choice(:verbose, :type => :boolean, :default => false) do |cli|
86
+ cli.uses_switch('-v', '--verbose', 'Log all actions to console')
87
+ end
88
+
89
+ builder.add_choice(:version, :default => false, :type => :boolean) do |cli|
90
+ cli.uses_switch('--version', 'Display version and licensing information')
91
+ end
92
+
93
+ builder.add_choice(:filenames) {|cli| cli.uses_arglist }
94
+ end
95
+
96
+ # Manual option post processing
97
+ def postprocess_user_choices
98
+ version if @user_choices[:version]
99
+ end
100
+
101
+ # Version and licensing information output
102
+ def version
103
+ name = 'Bakker'
104
+ puts "#{name} #{Aef::Bakker::VERSION}"
105
+ puts
106
+ puts 'Project: https://rubyforge.org/projects/aef/'
107
+ puts "RDoc: http://aef.rubyforge.org/#{name.downcase}/"
108
+ puts "Github: http://github.com/aef/#{name.downcase}/"
109
+ puts
110
+ puts 'Copyright 2009 Alexander E. Fischer <aef@raxys.net>'
111
+ # Read and print licensing information from the top of this file
112
+ if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('1.8.6')
113
+ puts File.read(__FILE__).map{|line| line[2..-1]}[5..17]
114
+ else
115
+ puts File.read(__FILE__).lines.map{|line| line[2..-1]}[5..17]
116
+ end
117
+ exit
118
+ end
119
+
120
+ # Main program
121
+ def execute
122
+ if @user_choices[:filenames].empty?
123
+ warn 'No files given'; exit false
124
+ else
125
+ @user_choices[:filenames].each do |filename|
126
+ begin
127
+ Aef::Bakker.process(filename, @user_choices[:extension], @user_choices[:mode].to_sym,
128
+ @user_choices[:action].to_sym, { :verbose => @user_choices[:verbose] })
129
+ rescue Aef::BakkerWarning
130
+ warn "Ignoring #{filename}: #$!"
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ S4tUtils.with_pleasant_exceptions {Aef::Bakker::Application.new.execute}
data/lib/bakker.rb ADDED
@@ -0,0 +1,29 @@
1
+ # Copyright 2009 Alexander E. Fischer <aef@raxys.net>
2
+ #
3
+ # This file is part of Bakker.
4
+ #
5
+ # Bakker is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ # Namespace for projects of Alexander E. Fischer <aef@raxys.net>
19
+ #
20
+ # If you want to be able to simply type Example instead of Aef::Example to
21
+ # address classes in this namespace simply write the following before using the
22
+ # classes:
23
+ #
24
+ # include Aef
25
+ module Aef
26
+
27
+ end
28
+
29
+ require File.join(File.dirname(__FILE__), 'bakker/bakker')
@@ -0,0 +1,73 @@
1
+ # Copyright 2009 Alexander E. Fischer <aef@raxys.net>
2
+ #
3
+ # This file is part of Bakker.
4
+ #
5
+ # Bakker is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>
17
+
18
+ require 'fileutils'
19
+
20
+ class Aef::BakkerWarning < StandardError; end
21
+
22
+ # Bakker is a Ruby library and commandline tool to help with simple task of
23
+ # renaming or copying files for quick backup purposes.
24
+ module Aef::Bakker
25
+ VERSION = '1.1.0'
26
+ DEFAULT_EXTENSION = '.bak'
27
+ MODES = [:toggle, :add, :remove]
28
+ ACTIONS = [:move, :copy]
29
+
30
+ module_function
31
+
32
+ # For possible options see FileUtils methods cp() and mv()
33
+ def process(filename, extension = DEFAULT_EXTENSION, mode = MODES.first, action = ACTIONS.first, options = {})
34
+ raise ArgumentError, 'Action can only be :copy or :move.' unless ACTIONS.include?(action)
35
+ raise ArgumentError, 'Mode can only be :toggle, :add or :remove.' unless MODES.include?(mode)
36
+
37
+ # Regex used for determining if an extension should be added or removed
38
+ regexp = /#{Regexp.escape(extension)}$/
39
+
40
+ # Find out both the basic file name and the extended file name for every
41
+ # situation possible
42
+ filename_without_extension = filename.gsub(regexp, '')
43
+ filename_with_extension = filename_without_extension + extension
44
+
45
+ # Check both cases for existence for further processing
46
+ without_exists = File.exists?(filename_without_extension)
47
+ with_exists = File.exists?(filename_with_extension)
48
+
49
+ # Error if both unextended and extended files or none of them exist
50
+ #
51
+ # The mode variable contains symbols :copy or :move which correspond to
52
+ # methods of class FileUtils which are invoked through the send() method.
53
+ if without_exists and with_exists
54
+ raise Aef::BakkerWarning, "Both #{filename_without_extension} and #{filename_with_extension} already exist."
55
+ elsif without_exists and not with_exists
56
+ if [:toggle, :add].include?(mode)
57
+ FileUtils.send(action, filename_without_extension, filename_with_extension, options)
58
+ filename_with_extension
59
+ else
60
+ filename_without_extension
61
+ end
62
+ elsif not without_exists and with_exists
63
+ if [:toggle, :remove].include?(mode)
64
+ FileUtils.send(action, filename_with_extension, filename_without_extension, options)
65
+ filename_without_extension
66
+ else
67
+ filename_with_extension
68
+ end
69
+ else
70
+ raise Aef::BakkerWarning, "Neither #{filename_without_extension} nor #{filename_with_extension} found."
71
+ end
72
+ end
73
+ end