bakker 1.0.0
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/COPYING.txt +676 -0
- data/History.txt +6 -0
- data/Manifest.txt +8 -0
- data/README.txt +136 -0
- data/Rakefile +15 -0
- data/bin/bakker +139 -0
- data/lib/bakker.rb +69 -0
- data/spec/bakker_spec.rb +466 -0
- data.tar.gz.sig +3 -0
- metadata +114 -0
- metadata.gz.sig +2 -0
data/Manifest.txt
ADDED
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
|