silo 0.1.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/.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