bakker 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ COPYING.txt
5
+ Rakefile
6
+ bin/bakker
7
+ lib/bakker.rb
8
+ spec/bakker_spec.rb
data/README.txt ADDED
@@ -0,0 +1,136 @@
1
+ = Bakker
2
+
3
+ * Project: https://rubyforge.org/projects/aef/
4
+ * RDoc: http://aef.rubyforge.org/bakker/
5
+
6
+ == DESCRIPTION:
7
+
8
+ Bakker was created to help with simple task of renaming or copying files for
9
+ quick backup purposes. For instance by creating a copy of a list of files
10
+ while adding .bak to the copies filenames. Bakker gives you control over the
11
+ extension to be added to or removed from the file and whether it should be
12
+ moved or copied.
13
+
14
+ == FEATURES/PROBLEMS:
15
+
16
+ * Usable as library and commandline tool
17
+ * Tested and fully working on:
18
+ * Ubuntu Linux 8.10 i386_64 (Ruby 1.8.7 and 1.9.1p0)
19
+ * On Windows XP i386 (Ruby 1.8.6)
20
+ * On Windows XP i386 (Ruby 1.8.6) there were some problems testing the
21
+ environment variable choices. Two tests are failing but the programs seems
22
+ to work correctly. If anyone finds the problem, please contact me.
23
+ * The commandline tool doesn't work with Ruby 1.9.x because the user-choices gem
24
+ is not yet updated. A patch is available here:
25
+ https://rubyforge.org/tracker/index.php?func=detail&aid=24307&group_id=4192&atid=16176
26
+
27
+ == SYNOPSIS:
28
+
29
+ === Commandline
30
+
31
+ The following command renames config.ini to config.ini.bak. You can type the
32
+ same command a second time to revert the action:
33
+
34
+ bakker config.ini
35
+
36
+ Instead of renaming you can create a copy of config.xml by using the following
37
+ command:
38
+
39
+ bakker -a copy config.ini
40
+
41
+ To change the extension which will be appended or removed from the filename use
42
+ the following command:
43
+
44
+ bakker -e .backup
45
+
46
+ In a directory with the follwing contents:
47
+
48
+ demo1
49
+ demo2.bak
50
+ demo3.bak
51
+
52
+ if you use the command:
53
+
54
+ bakker *
55
+
56
+ you get the following list of files (because by default Bakker toggles the
57
+ extension):
58
+
59
+ demo1.bak
60
+ demo2
61
+ demo3
62
+
63
+ if you now want every file in the folder to have a .bak extension use the
64
+ following command:
65
+
66
+ bakker -m add *
67
+
68
+ the result will look like this:
69
+
70
+ demo1.bak
71
+ demo2.bak
72
+ demo3.bak
73
+
74
+ Instead of using the add-mode you could have used the remove-mode like this:
75
+
76
+ bakker -m remove *
77
+
78
+ Then the result would have looked like this:
79
+
80
+ demo1
81
+ demo2
82
+ demo3
83
+
84
+ Bakker also includes a verbose mode which will inform you of any file transfer
85
+ in the console:
86
+
87
+ bakker -v config.ini
88
+
89
+ You can specify default values for extension, action, mode and even for the
90
+ verbose mode by using environment variables. Notice that you can still override
91
+ these by using commandline switches. A list of the variables:
92
+
93
+ * BAKKER_MODE
94
+ * BAKKER_ACTION
95
+ * BAKKER_EXTENSION
96
+ * BAKKER_VERBOSE
97
+
98
+ === Library
99
+
100
+ Load the gem:
101
+
102
+ require 'bakker'
103
+
104
+ Call Bakker:
105
+
106
+ Bakker.process('config.ini', '.backup', :add, :copy)
107
+
108
+ == REQUIREMENTS:
109
+
110
+ * user-choices (for commandline tool only)
111
+ * rspec (for testing only)
112
+ * sys-uname (for testing only)
113
+
114
+ == INSTALL:
115
+
116
+ * gem install bakker
117
+ * gem install user-choices (only for commandline tool)
118
+
119
+ == LICENSE:
120
+
121
+ Copyright 2009 Alexander E. Fischer <aef@raxys.net>
122
+
123
+ This file is part of Bakker.
124
+
125
+ Bakker is free software: you can redistribute it and/or modify
126
+ it under the terms of the GNU General Public License as published by
127
+ the Free Software Foundation, either version 3 of the License, or
128
+ (at your option) any later version.
129
+
130
+ This program is distributed in the hope that it will be useful,
131
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
132
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
133
+ GNU General Public License for more details.
134
+
135
+ You should have received a copy of the GNU General Public License
136
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/bakker.rb'
6
+
7
+ Hoe.new('bakker', 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 sys-uname}
11
+ p.testlib = 'spec'
12
+ p.test_globs = ['spec/**/*_spec.rb']
13
+ end
14
+
15
+ # vim: syntax=Ruby
data/bin/bakker ADDED
@@ -0,0 +1,139 @@
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 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 (#{Bakker::MODES.join(', ')}. Default: #{Bakker::MODES.first})",
49
+ "BAKKER_ACTION (#{Bakker::ACTIONS.join(', ')}. Default: #{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 => Bakker::MODES.map{|item| item.to_s}, :default => Bakker::MODES.first.to_s) do |cli|
68
+ cli.uses_option('-m', '--mode MODE',
69
+ "Processing mode. Can be one of: #{Bakker::MODES.join(', ')}. " +
70
+ "Default: #{Bakker::MODES.first}")
71
+ end
72
+
73
+ builder.add_choice(:action, :type => Bakker::ACTIONS.map{|item| item.to_s}, :default => Bakker::ACTIONS.first.to_s) do |cli|
74
+ cli.uses_option('-a', '--action ACTION',
75
+ "Filesystem action. Can be one of: #{Bakker::ACTIONS.join(', ')}. " +
76
+ "Default: #{Bakker::ACTIONS.first}")
77
+ end
78
+
79
+ builder.add_choice(:extension, :default => 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
+ # Main program
97
+ def execute
98
+ if @user_choices[:version]
99
+ klass = Bakker
100
+ puts "\n#{klass.name} #{klass::VERSION}"
101
+ puts DATA.read; exit
102
+ end
103
+
104
+ if @user_choices[:filenames].empty?
105
+ warn 'No files given'; exit false
106
+ else
107
+ @user_choices[:filenames].each do |filename|
108
+ begin
109
+ Bakker.process(filename, @user_choices[:extension], @user_choices[:mode].to_sym,
110
+ @user_choices[:action].to_sym, { :verbose => @user_choices[:verbose] })
111
+ rescue BakkerWarning
112
+ warn "Ignoring #{filename}: #$!"
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ S4tUtils.with_pleasant_exceptions {Bakker::Application.new.execute}
120
+
121
+ __END__
122
+
123
+ Project: https://rubyforge.org/projects/aef/
124
+ RDoc: http://aef.rubyforge.org/bakker/
125
+
126
+ Copyright 2009 Alexander E. Fischer <aef@raxys.net>
127
+
128
+ Bakker is free software: you can redistribute it and/or modify
129
+ it under the terms of the GNU General Public License as published by
130
+ the Free Software Foundation, either version 3 of the License, or
131
+ (at your option) any later version.
132
+
133
+ This program is distributed in the hope that it will be useful,
134
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
135
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
136
+ GNU General Public License for more details.
137
+
138
+ You should have received a copy of the GNU General Public License
139
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/lib/bakker.rb ADDED
@@ -0,0 +1,69 @@
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 BakkerWarning < StandardError; end
21
+
22
+ module Bakker
23
+ VERSION = '1.0.0'
24
+ DEFAULT_EXTENSION = '.bak'
25
+ MODES = [:toggle, :add, :remove]
26
+ ACTIONS = [:move, :copy]
27
+
28
+ # For possible options see FileUtils methods cp() and mv()
29
+ def self.process(filename, extension = DEFAULT_EXTENSION, mode = MODES.first, action = ACTIONS.first, options = {})
30
+ raise ArgumentError, 'Action can only be :copy or :move.' unless ACTIONS.include?(action)
31
+ raise ArgumentError, 'Mode can only be :toggle, :add or :remove.' unless MODES.include?(mode)
32
+
33
+ # Regex used for determining if an extension should be added or removed
34
+ regexp = /#{Regexp.escape(extension)}$/
35
+
36
+ # Find out both the basic file name and the extended file name for every
37
+ # situation possible
38
+ filename_without_extension = filename.gsub(regexp, '')
39
+ filename_with_extension = filename_without_extension + extension
40
+
41
+ # Check both cases for existence for further processing
42
+ without_exists = File.exists?(filename_without_extension)
43
+ with_exists = File.exists?(filename_with_extension)
44
+
45
+ # Error if both unextended and extended files or none of them exist
46
+ #
47
+ # The mode variable contains symbols :copy or :move which correspond to
48
+ # methods of class FileUtils which are invoked through the send() method.
49
+ if without_exists and with_exists
50
+ raise BakkerWarning, "Both #{filename_without_extension} and #{filename_with_extension} already exist."
51
+ elsif without_exists and not with_exists
52
+ if [:toggle, :add].include?(mode)
53
+ FileUtils.send(action, filename_without_extension, filename_with_extension, options)
54
+ filename_with_extension
55
+ else
56
+ filename_without_extension
57
+ end
58
+ elsif not without_exists and with_exists
59
+ if [:toggle, :remove].include?(mode)
60
+ FileUtils.send(action, filename_with_extension, filename_without_extension, options)
61
+ filename_without_extension
62
+ else
63
+ filename_with_extension
64
+ end
65
+ else
66
+ raise BakkerWarning, "Neither #{filename_without_extension} nor #{filename_with_extension} found."
67
+ end
68
+ end
69
+ end