silo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --files Changelog.md,LICENSE
data/Changelog.md ADDED
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ ## Version 0.1.0
4
+
5
+ **January 30<sup>th</sup>, 2011**
6
+
7
+ * First release
8
+ * Simple saving and restoring
9
+ * Mirroring using Git's built-in remotes
10
+ * Getting simple information from the repository
11
+
12
+ See the [Git history](https://github.com/koraktor/silo/commits/0.1.0) for
13
+ version 0.1.0
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2010-2011, Sebastian Staudt
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the author nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ Silo
2
+ ====
3
+
4
+ Silo is command-line utility and Ruby API for Git-based backups. With Silo you
5
+ can backup arbitrary files into one or more Git repositories and take advantage
6
+ of Git's compression, speed and other features. No Git knowledge needed.
7
+
8
+ ## Concept
9
+
10
+ To backup files into a repository Silo uses the well-known and established
11
+ version control system (VCS) Git. Instead of using Git's frontend commands for
12
+ the end-user, so called *"porcelain"* commands, Silo makes use of the more
13
+ low-level *"plumbing"* commands. These can be used to write directly to the Git
14
+ repository, bypassing the automatisms tailored for source code histories.
15
+
16
+ ## Requirements
17
+
18
+ * Grit &ndash; a Ruby API for Git
19
+ * Rubikon &ndash; a Ruby framework for console applications
20
+ * Git >= 1.6
21
+
22
+ ## Installation
23
+
24
+ You can install Silo using RubyGems. This is the easiest way of installing
25
+ and recommended for most users.
26
+
27
+ $ gem install silo
28
+
29
+ If you want to use the development code you should clone the Git repository:
30
+
31
+ $ git clone git://github.com/koraktor/silo.git
32
+ $ cd silo
33
+ $ rake install
34
+
35
+ ## Basic usage
36
+
37
+ ### Configuration files
38
+
39
+ Silo searches for configuration files (`.silo`) in the current working
40
+ directory, your home directory and your systems global configuration directory
41
+ (i.e. /etc on Unix).
42
+
43
+ They can be used to set Silo-specific options globally or for single
44
+ directories. That way you may have one general Silo repository for common
45
+ backups and another Silo repository for e.g. work-related files.
46
+
47
+ Configuration files are expected in a Git-like format and
48
+ may contain the following sections and variables:
49
+
50
+ * repository
51
+
52
+ * path – The path of the default repository to use
53
+ * prefix – The path inside the repository to store files to per default
54
+
55
+ #### Sample
56
+
57
+ [repository]
58
+ path = /Users/jondoe/backup.git
59
+ prefix = work
60
+
61
+ This would usually save and restore files to and from
62
+ `/Users/jondoe/backup.git` and save files into the directory `work` inside the
63
+ repository.
64
+
65
+ ### Initialize a repository
66
+
67
+ $ silo init [repository path]
68
+
69
+ ### Add files or directories to the repository
70
+
71
+ $ silo add file [file ...] [--prefix <prefix>]
72
+
73
+ The prefix allows to organize the files inside the repository.
74
+
75
+ ### Restore files or directories from the repository
76
+
77
+ $ silo restore file [file ...] [--prefix <prefix>]
78
+
79
+ The prefix is the directory inside your file system where the restored files
80
+ will be saved.
81
+
82
+ ### Remove files or directories from the repository
83
+
84
+ $ silo remove file [file ...]
85
+ $ silo rm file [file ...]
86
+
87
+ ### Completely purge files or directories from the repository
88
+
89
+ $ silo purge file [file ...] [--no-clean]
90
+
91
+ This will completely remove the specified files from the repository and thus
92
+ reduce the required disk space.
93
+
94
+ **WARNING**: There's no method built-in to Silo or Git to recover files after
95
+ purging.
96
+
97
+ The `--no-clean` flag will cause Git commits to persist even after their
98
+ contents have been purged.
99
+
100
+ ### Manage remote repositories for mirrored backups
101
+
102
+ $ silo remote [-v]
103
+ $ silo remote add name url
104
+ $ silo remote rm name
105
+
106
+ Add or remove a remote repository with the specified name. When adding a remote
107
+ repository the specified location may be given as any location Git understands
108
+ – including file system paths.
109
+
110
+ ### Distribute the state of your repository to all mirror repositories
111
+
112
+ $ silo distribute
113
+
114
+ ### List repository contents
115
+
116
+ $ silo list [file ...] [-l] [-r]
117
+
118
+ The `-l` flag will list each directory and file in a separate line, `-r` will
119
+ reverse the listing.
120
+
121
+ ### Display info about repository contents
122
+
123
+ $ silo info [file ...] [-v]
124
+
125
+ ## Using the Ruby API
126
+
127
+ The documentation of the Ruby API can be seen at [RubyDoc.info][1]. The API
128
+ documentation of the current development version is also available [there][5].
129
+
130
+ ## License
131
+
132
+ This code is free software; you can redistribute it and/or modify it under the
133
+ terms of the new BSD License. A copy of this license can be found in the
134
+ LICENSE file.
135
+
136
+ ## Credits
137
+
138
+ * Sebastian Staudt – koraktor(at)gmail.com
139
+
140
+ ## See Also
141
+
142
+ * [API documentation][1]
143
+ * [Silo's homepage][2]
144
+ * [GitHub project page][3]
145
+ * [GitHub issue tracker][4]
146
+
147
+ Follow Silo on Twitter [@silorb](http://twitter.com/silorb).
148
+
149
+ [1]: http://rubydoc.info/gems/silo/frames
150
+ [2]: http://koraktor.github.com/silo
151
+ [3]: http://github.com/koraktor/silo
152
+ [4]: http://github.com/koraktor/silo/issues
153
+ [5]: http://rubydoc.info/github/koraktor/silo/master/frames
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ require 'rake/testtask'
7
+
8
+ task :default => :test
9
+
10
+ # Test task
11
+ Rake::TestTask.new do |t|
12
+ t.libs << 'lib' << 'test'
13
+ t.pattern = 'test/**/test_*.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ begin
18
+ require 'ore/tasks'
19
+ Ore::Tasks.new
20
+ rescue LoadError
21
+ $stderr.puts 'You need ore-tasks to build the gem. Install it using `gem install ore-tasks`.'
22
+ end
23
+
24
+ begin
25
+ require 'yard'
26
+
27
+ # Create a rake task +:doc+ to build the documentation using YARD
28
+ YARD::Rake::YardocTask.new do |yardoc|
29
+ yardoc.name = 'doc'
30
+ yardoc.files = ['lib/**/*.rb', 'LICENSE', 'README.md']
31
+ yardoc.options = ['--private', '--title', 'Silo &mdash; API Documentation']
32
+ end
33
+ rescue LoadError
34
+ desc 'Generate YARD Documentation (not available)'
35
+ task :doc do
36
+ $stderr.puts 'You need YARD to build the documentation. Install it using `gem install yard`.'
37
+ end
38
+ end
39
+
40
+ # Task for cleaning documentation and package directories
41
+ desc 'Clean documentation and package directories'
42
+ task :clean do
43
+ FileUtils.rm_rf 'doc'
44
+ FileUtils.rm_rf 'pkg'
45
+ end
data/bin/silo ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This code is free software; you can redistribute it and/or modify it under
4
+ # the terms of the new BSD License.
5
+ #
6
+ # Copyright (c) 2010, Sebastian Staudt
7
+
8
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'silo.rb')
9
+ require 'silo/cli.rb'
data/gemspec.yml ADDED
@@ -0,0 +1,29 @@
1
+ name: silo
2
+ summary: A command-line utility and API for Git-based backups
3
+ description: With Silo you can backup arbitrary files into one or more Git
4
+ repositories and take advantage of Git's compression, speed and
5
+ other features. No Git knowledge needed.
6
+
7
+ license: BSD
8
+ authors: Sebastian Staudt
9
+ email: koraktor@gmail.com
10
+ homepage: http://koraktor.de/silo
11
+ has_yard: true
12
+
13
+ extra_doc_files:
14
+ - Changelog.md
15
+ - LICENSE
16
+ require_paths: lib
17
+ test_files: test/**/test_*.rb
18
+
19
+ dependencies:
20
+ grit: ~> 2.4.1
21
+ rubikon: ~> 0.6.0
22
+
23
+ development_dependencies:
24
+ ore-tasks: ~> 0.3.0
25
+ shoulda: ~> 2.11.3
26
+ yard: ~> 0.6.4
27
+
28
+ requirements:
29
+ - git >= 1.6
@@ -0,0 +1,20 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'pathname'
7
+
8
+ # Provides extensions to the Pathname class provided by Ruby's standard
9
+ # Library
10
+ class Pathname
11
+
12
+ # Appends a path to this path and expands it
13
+ #
14
+ # @param [#to_s] path The path to append
15
+ # @return [Pathname] The generated path
16
+ def /(path)
17
+ (self + path).expand_path
18
+ end
19
+
20
+ end
data/lib/silo.rb ADDED
@@ -0,0 +1,20 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ libdir = File.dirname(__FILE__)
7
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
8
+
9
+ require 'silo/errors'
10
+ require 'silo/repository'
11
+ require 'silo/remote/git'
12
+ require 'silo/version'
13
+
14
+ # A command-line utility and API for Git-based backups
15
+ #
16
+ # With Silo you can backup arbitrary files into one or more Git repositories
17
+ # and take advantage of Git's compression, speed and other features. No Git
18
+ # knowledge needed.
19
+ module Silo
20
+ end
data/lib/silo/cli.rb ADDED
@@ -0,0 +1,167 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010-2011, Sebastian Staudt
5
+
6
+ require 'rubygems'
7
+ require 'rubikon'
8
+
9
+ module Silo
10
+
11
+ # This class is a Rubikon application that implements the command-line
12
+ # interface for Silo
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @since 0.1.0
16
+ class CLI < Rubikon::Application::Base
17
+
18
+ # Changes the current repository
19
+ #
20
+ # @see #repo
21
+ attr_writer :repo
22
+
23
+ set :config_file, '.silo'
24
+ set :config_format, :ini
25
+ set :help_banner, 'Usage: silo'
26
+
27
+ global_option :repository, :repo_path do
28
+ self.repo = Repository.new repo_path
29
+ end
30
+
31
+ pre_execute do
32
+ if config.empty?
33
+ puts "y{Warning:} Configuration file(s) could not be loaded.\n\n"
34
+ else
35
+ @prefix = config['repository']['prefix']
36
+ self.repo = Repository.new config['repository']['path']
37
+ end
38
+ end
39
+
40
+ default '<hidden>' do
41
+ puts "This is Silo. A Git-based backup utility.\n\n"
42
+ call :help
43
+ end
44
+
45
+ option :prefix, 'The prefix path inside the repository to store the files to', :path
46
+ command :add, 'Store one or more files in the repository', :files => :remainder do
47
+ files.uniq.each do |file|
48
+ repo.add file, prefix.path || @prefix
49
+ end
50
+ end
51
+
52
+ command :distribute, 'Push repository contents to remote repositories' do
53
+ repo.distribute
54
+ end
55
+
56
+ command :info, 'Get information about repository contents', :files => :remainder do
57
+ files.uniq.each do |path|
58
+ info = repo.info path
59
+ puts '' unless path == args.first
60
+ puts "#{info[:type] == :blob ? 'File' : 'Directory'}: #{info[:path]}"
61
+ if info[:type] == :blob
62
+ puts " Size: #{info[:size].to_s.
63
+ gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")} bytes"
64
+ puts " MIME-Type: #{info[:mime]}"
65
+ end
66
+ puts " Created at: #{info[:created]}"
67
+ puts " Last modified at: #{info[:modified]}"
68
+
69
+ if $VERBOSE
70
+ puts " Initial commit: #{info[:history].last.id}"
71
+ puts " Last commit: #{info[:history].first.id}"
72
+ puts " Mode: #{info[:mode]}"
73
+ puts " #{info[:type].to_s.capitalize}-ID: #{info[:sha]}"
74
+ end
75
+ end
76
+ end
77
+
78
+ command :init, 'Initialize a Silo repository', :path => :optional do
79
+ path = File.expand_path(path || '.')
80
+ puts "Initializing Silo repository in #{path}..."
81
+ Repository.new path
82
+ end
83
+
84
+ flag :l, 'List each object in a separate line'
85
+ flag :r, 'Reverse list order'
86
+ command :list, 'List the contents of a repository', :paths => [ :remainder, :optional ] do
87
+ paths = self.paths || [nil]
88
+ contents = []
89
+ paths.each do |path|
90
+ new_contents = repo.contents path
91
+ puts "y{Warning:} File '#{path}' does not exist in the repository." if new_contents.empty?
92
+ contents |= new_contents
93
+ end
94
+
95
+ contents.reverse! if r.given?
96
+
97
+ unless l.given?
98
+ col_size = contents.max_by { |path| path.size }.size + 1
99
+ contents.each { |path| put path.ljust(col_size) }
100
+ puts ''
101
+ else
102
+ contents.each { |path| puts path }
103
+ end
104
+ end
105
+
106
+ command :remote, 'Add or remove remote repositories', { :action => ['add', 'rm', :optional], :name => :optional, :url => :optional } do
107
+ usage = lambda do
108
+ puts 'usage: silo remote add <name> <url>'
109
+ puts ' or: silo remote rm <name>'
110
+ end
111
+ case action
112
+ when nil
113
+ repo.remotes.each_value do |remote|
114
+ info = remote.name
115
+ info += " #{remote.url}" if $VERBOSE
116
+ puts info
117
+ end
118
+ when 'add'
119
+ if url.nil?
120
+ repo.add_remote name, url
121
+ else
122
+ usage.call
123
+ end
124
+ when 'rm'
125
+ unless url.nil?
126
+ repo.remove_remote name
127
+ else
128
+ usage.call
129
+ end
130
+ else
131
+ usage.call
132
+ end
133
+ end
134
+
135
+ option :prefix, 'The prefix path to store the files to', :path
136
+ command :restore, 'Restore one or more files or directories from the repository', :files => :remainder do
137
+ files.uniq.each do |file|
138
+ repo.restore file, prefix.path || '.'
139
+ end
140
+ end
141
+
142
+ flag :'no-clean', "Don't remove empty commits from the Git history"
143
+ command :purge, 'Permanently remove one or more files or directories from the repository', :files => :remainder do
144
+ files.uniq.each do |file|
145
+ repo.purge file, !given?(:'no-clean')
146
+ end
147
+ end
148
+
149
+ command :rm => :remove
150
+ command :remove, 'Remove one or more files or directories from the repository', :files => :remainder do
151
+ files.uniq.each do |file|
152
+ repo.remove file
153
+ end
154
+ end
155
+
156
+ # Returns the current repository
157
+ #
158
+ # @return [Repository] The currently configured Silo repository
159
+ # @raise [RuntimeError] if no repository is configured
160
+ def repo
161
+ raise 'No repository configured.' if @repo.nil?
162
+ @repo
163
+ end
164
+
165
+ end
166
+
167
+ end