oldtime 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /rfrom/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gem "thor"
4
+ gem "optimism", :path => "/home/guten/dev/one/optimism"
5
+ gem "pa", :path => "/home/guten/dev/one/pa"
6
+ gem "tagen", :path => "/home/guten/dev/one/tagen", :require => "tagen/core"
7
+
8
+ group :development do
9
+ gem "rspec"
10
+ gem "watchr"
11
+ #gem "rag"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: /home/guten/dev/one/optimism
3
+ specs:
4
+ optimism (3.0.4)
5
+ hike (~> 1.2.0)
6
+
7
+ PATH
8
+ remote: /home/guten/dev/one/pa
9
+ specs:
10
+ pa (1.1.4)
11
+
12
+ PATH
13
+ remote: /home/guten/dev/one/tagen
14
+ specs:
15
+ tagen (1.1.2)
16
+ activesupport (~> 3.1.0)
17
+
18
+ GEM
19
+ remote: http://rubygems.org/
20
+ specs:
21
+ activesupport (3.1.3)
22
+ multi_json (~> 1.0)
23
+ diff-lcs (1.1.3)
24
+ hike (1.2.1)
25
+ multi_json (1.0.4)
26
+ rspec (2.8.0)
27
+ rspec-core (~> 2.8.0)
28
+ rspec-expectations (~> 2.8.0)
29
+ rspec-mocks (~> 2.8.0)
30
+ rspec-core (2.8.0)
31
+ rspec-expectations (2.8.0)
32
+ diff-lcs (~> 1.1.2)
33
+ rspec-mocks (2.8.0)
34
+ thor (0.14.6)
35
+ watchr (0.7)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ optimism!
42
+ pa!
43
+ rspec
44
+ tagen!
45
+ thor
46
+ watchr
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ Oldtime, a highly customize configurable backup & restore system.
2
+ =================================================================
3
+
4
+ | Homepage: | https://github.com/GutenYe/oldtime |
5
+ |----------------|------------------------------------------------------ |
6
+ | Author: | Guten |
7
+ | License: | MIT-LICENSE |
8
+ | Documentation: | http://rubydoc.info/gems/oldtime/frames |
9
+ | Issue Tracker: | https://github.com/GutenYe/oldtime/issues |
10
+
11
+ Overview
12
+ --------
13
+
14
+ WARNING: THIS PROJECT IS UNDER HEAV DEVELOPMENT, NOT READY FOR PRODUCTION.
15
+
16
+ Features
17
+ --------
18
+
19
+ a clearly list of features.
20
+
21
+ Usage
22
+ -----
23
+
24
+ how to use
25
+
26
+ Install
27
+ ----------
28
+
29
+ gem install oldtime
30
+
31
+ Contributing
32
+ -------------
33
+
34
+ * Feel free to join the project and make contributions (by submitting a pull request)
35
+ * Submit any bugs/features/ideas to issue tracker
36
+ * Coding Style Guide: https://gist.github.com/1105334
37
+
38
+ Credits
39
+ --------
40
+
41
+ * [Contributors](https://github.com/GutenYe/oldtime/contributors)
42
+
43
+ Resources
44
+ ---------
45
+
46
+ some related resources to help each other.
47
+
48
+ Copyright
49
+ ---------
50
+
51
+ (the MIT License)
52
+
53
+ Copyright (c) 2011 Guten
54
+
55
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
56
+
57
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
58
+
59
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Ragfile ADDED
@@ -0,0 +1,5 @@
1
+ # add your own task in Ragfile or in tasks/*.rag
2
+ class Rag < Thor
3
+ end
4
+
5
+ # vim: filetype=ruby
data/bin/oldtime ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../lib/oldtime"
3
+
4
+ begin
5
+ Oldtime::CLI.start
6
+ rescue Oldtime::Error => e
7
+ Oldtime.ui.error e.message
8
+ Oldtime.ui.debug e.backtrace.join("\n")
9
+ exit 1
10
+ rescue Interrupt => e
11
+ Oldtime.ui.error "\nQuitting..."
12
+ Oldtime.ui.debug e.backtrace.join("\n")
13
+ exit 1
14
+ end
@@ -0,0 +1,12 @@
1
+ module Oldtime
2
+ module ArchLinux_Kernel
3
+ def backup_archlinux_packages
4
+ sh %~pacman -Qqe | grep -vx "$(pacman -Qqm)" > #{Rc.p.oldtime}/packages.lst~, :verbose => true
5
+ sh %~pacman -Qqm > #{Rc.p.oldtime}/aur.lst~, :verbose => true
6
+ end
7
+ end
8
+ end
9
+
10
+ include Oldtime::ArchLinux_Kernel
11
+
12
+ Optimism.undef_method :backup_archlinux_packages
@@ -0,0 +1,64 @@
1
+ module Oldtime
2
+ class CLI < Thor
3
+ include Thor::Actions
4
+
5
+ # check_unknown_options!
6
+
7
+ # default_task :install
8
+ class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
9
+ class_option "verbose", :aliases => "-V", :type => :boolean, :banner => "Enable verbose output mode"
10
+ class_option "config", :aliases => "-c", :type => :string, :banner => "Config file"
11
+ class_option "user-mode", :aliases => "-u", :type => :boolean, :banner => "Enter into User mode"
12
+
13
+ def initialize(*)
14
+ super
15
+ the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
16
+ Oldtime.ui = UI::Shell.new(the_shell)
17
+ Oldtime.ui.debug! if options["verbose"]
18
+
19
+ config = options["config"] || (options["user-mode"] ? "#{ENV['HOME']}/.oldtimerc" : "/oldtime/oldtimerc")
20
+ Rc << Optimism.require(Pa.absolute2(config))
21
+
22
+ Rc.p.home ||= config.sub(/rc$/, "")
23
+ end
24
+
25
+ desc "backup <profile> [instance]", "begin backup process."
26
+ # method_option "x", :aliases => "-x", :default => "x", :type => :string, :banner => "NAME", :desc => "x"
27
+ def backup(profile, instance=:default)
28
+ Rc.action = "backup"
29
+ Rc.profile = profile
30
+ instance = Rc.instance = instance.to_sym
31
+
32
+ load_profile profile
33
+
34
+ if blk=Rc.backup_blks[instance]
35
+ blk.call
36
+ else
37
+ Oldtime.ui.say "can't find `#{instance}' instance to execute."
38
+ end
39
+ end
40
+
41
+ desc "restore <profile> [instance]", "begin restore process."
42
+ def restore(profile, instance=:default)
43
+ Rc.action = "restore"
44
+ Rc.profile = profile
45
+ Rc.instance = instance.to_sym
46
+
47
+ load_profile profile
48
+
49
+ Rc.restore_blks[instance].call
50
+ end
51
+
52
+ private
53
+
54
+ def load_profile(profile)
55
+ file = Pa("#{Rc.p.home}/#{profile}.conf")
56
+
57
+ if file.exists?
58
+ load file.p
59
+ else
60
+ raise Error, "can't find the profile configuration file -- #{file}"
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/oldtime/rc.rb ADDED
@@ -0,0 +1,15 @@
1
+ # user config
2
+ p:
3
+ home = nil
4
+ oldtime = Pa("/oldtime")
5
+
6
+ backup:
7
+ rsync.options = ""
8
+
9
+ # system config
10
+
11
+ backup_blks = {}
12
+ restore_blks = {}
13
+
14
+ restore:
15
+ rsync.options = ""
@@ -0,0 +1,106 @@
1
+ require "erb"
2
+
3
+ module Oldtime
4
+ class Rsync
5
+ def initialize(end_cmd)
6
+ @end_cmd = ERB.new(end_cmd).result(binding)
7
+ end
8
+
9
+ def run
10
+ cmd = build_cmd(@end_cmd)
11
+ system cmd, :verbose => true
12
+ end
13
+
14
+ private
15
+ def build_cmd(end_cmd)
16
+ "rsync #{Rc[Rc.action].rsync.options} #{end_cmd}"
17
+ end
18
+ end
19
+
20
+ class Rsync2
21
+ def initialize(file)
22
+ @file = file
23
+ end
24
+
25
+ def run
26
+ begin
27
+ @dir = Pa.mktmpdir(Rc.profile)
28
+
29
+ end_cmd, file_config = parse(@file)
30
+ file_config.each { |k, v|
31
+ File.write("#{@dir}/#{k}", v)
32
+ }
33
+ cmd = build_cmd(end_cmd, file_config)
34
+
35
+ system cmd, :verbose => true
36
+ ensure
37
+ # cleanup
38
+ Pa.rm_r @dir
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def parse(file)
45
+ f = open(file.p)
46
+ end_cmd = f.readline.rstrip
47
+ content = f.read
48
+ f.close
49
+
50
+ end_cmd = ERB.new(end_cmd).result(binding)
51
+ file_config = scan(content)
52
+
53
+ [ end_cmd, file_config]
54
+ end
55
+
56
+ def build_cmd(end_cmd, file_config)
57
+ cmd = "rsync #{Rc[Rc.action].rsync.options} "
58
+
59
+ file_config.each { |k,v|
60
+ cmd << "--#{k}-from #{@dir}/#{k} "
61
+ }
62
+
63
+ cmd << end_cmd
64
+ end
65
+
66
+ # Given data:
67
+ # [foo]
68
+ # bar ...
69
+ #
70
+ # => {"foo" => "bar"}
71
+ def scan(data)
72
+ pat = /(.*?)(\[([^\]]+)\] *\n|\z)/m
73
+ ret = {}
74
+
75
+ tokens = []
76
+ data.scan(pat) do |v, _, k|
77
+ tokens << v << k
78
+ end
79
+
80
+ tokens[1..-1].each_slice(2){|k, v|
81
+ next if k.nil?
82
+ v ||= "" # nil is empty string.
83
+
84
+ ret[k] = v
85
+ }
86
+
87
+ ret
88
+ end
89
+ end
90
+
91
+ module Rsync_Kernel
92
+ def rsync(end_cmd)
93
+ Rsync.new(end_cmd).run
94
+ end
95
+
96
+ # read rsync cmd from file.
97
+ def rsync2(filename)
98
+ file = Pa("#{Rc.p.home}/#{Rc.profile}/#{filename}")
99
+ Rsync2.new(file).run
100
+ end
101
+ end
102
+ end
103
+
104
+ include Oldtime::Rsync_Kernel
105
+
106
+ Optimism.undef_method :rsync, :rsync2
data/lib/oldtime/ui.rb ADDED
@@ -0,0 +1,61 @@
1
+ module Oldtime
2
+ class UI
3
+ def warn(message)
4
+ end
5
+
6
+ def debug(message)
7
+ end
8
+
9
+ def error(message)
10
+ end
11
+
12
+ def info(message)
13
+ end
14
+
15
+ def confirm(message)
16
+ end
17
+
18
+ # alias to info.
19
+ def say(*args, &blk)
20
+ info(*args, &blk)
21
+ end
22
+
23
+ class Shell < UI
24
+ attr_writer :shell
25
+
26
+ def initialize(shell)
27
+ @shell = shell
28
+ @quiet = false
29
+ @debug = ENV['DEBUG']
30
+ end
31
+
32
+ def debug(msg)
33
+ @shell.say(msg) if @debug && !@quiet
34
+ end
35
+
36
+ def info(msg)
37
+ @shell.say(msg) if !@quiet
38
+ end
39
+
40
+ def confirm(msg)
41
+ @shell.say(msg, :green) if !@quiet
42
+ end
43
+
44
+ def warn(msg)
45
+ @shell.say(msg, :yellow)
46
+ end
47
+
48
+ def error(msg)
49
+ @shell.say(msg, :red)
50
+ end
51
+
52
+ def be_quiet!
53
+ @quiet = true
54
+ end
55
+
56
+ def debug!
57
+ @debug = true
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module Oldtime
2
+ VERSION="0.0.1"
3
+ end
data/lib/oldtime.rb ADDED
@@ -0,0 +1,55 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
5
+ require "bundler/setup"
6
+ Bundler.require
7
+
8
+ module Oldtime
9
+ autoload :VERSION, "oldtime/version"
10
+ autoload :UI, "oldtime/ui"
11
+ autoload :CLI, "oldtime/cli"
12
+
13
+ Error = Class.new Exception
14
+ FatalError = Class.new Exception
15
+
16
+ class << self
17
+ attr_accessor :ui
18
+
19
+ def ui
20
+ @ui ||= UI.new
21
+ end
22
+ end
23
+ end
24
+
25
+ Rc = Optimism.require("oldtime/rc")
26
+
27
+ module Kernel
28
+ private
29
+
30
+ def configure(data, &blk)
31
+ Rc << Optimism(data, &blk)
32
+ end
33
+
34
+ def backup(instance=:default, &blk)
35
+ Rc.backup_blks[instance] = blk
36
+ end
37
+
38
+ def restore(instance=:default, &blk)
39
+ Rc.restore_blks[instance] = blk
40
+ end
41
+
42
+ def check_mountpoint(path)
43
+ unless Pa.mountpoint?(path)
44
+ raise Error, "`#{path}' is unmounted."
45
+ end
46
+ end
47
+
48
+ def check_root
49
+ unless Process.uid == 0
50
+ raise Error, "need root privilege to run this script."
51
+ end
52
+ end
53
+ end
54
+
55
+ Optimism.undef_method :backup, :restore, :configure
data/oldtime.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ $: << "."
2
+ require "lib/oldtime/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "oldtime"
6
+ s.version = Oldtime::VERSION
7
+ s.summary = "the backup & restore system"
8
+ s.description = <<-EOF
9
+ the backup & restore sytem
10
+ EOF
11
+
12
+ s.author = "Guten"
13
+ s.email = "ywzhaifei@gmail.com"
14
+ s.homepage = "http://github.com/GutenYe/oldtime"
15
+ s.rubyforge_project = "xx"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ #s.executables = ["x"]
19
+
20
+ #s.add_dependency "x"
21
+ end
data/oldtime.watchr ADDED
@@ -0,0 +1,23 @@
1
+ # lib/**/*.rb
2
+ watch %r~lib/(.*)\.rb~ do |m|
3
+ test "spec/#{m[1]}_spec.rb"
4
+ end
5
+
6
+ # spec/**/*_spec.rb
7
+ watch %r~spec/.*_spec\.rb~ do |m|
8
+ test m[0]
9
+ end
10
+
11
+ # Ctrl-\
12
+ Signal.trap('QUIT') do
13
+ puts "--- Running all tests ---\n\n"
14
+ test "spec"
15
+ end
16
+
17
+ def test(path)
18
+ system "clear"
19
+ cmd = "rspec #{path}"
20
+ puts cmd
21
+ system cmd
22
+ end
23
+
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ CLI = Oldtime::CLI
4
+
5
+ class CLI
6
+ public :load_profile
7
+ end
8
+
9
+ describe CLI do
10
+ describe "#load_profile" do
11
+ it "works" do
12
+ lambda { CLI.new.load_profile("deson_t_exists") }.should raise_error(Oldtime::Error)
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+ require "oldtime/rsync"
3
+
4
+ Rsync2 = Oldtime::Rsync2
5
+ Rsync = Oldtime::Rsync
6
+
7
+ class Rsync
8
+ public :build_cmd
9
+ end
10
+
11
+ class Rsync2
12
+ public :scan, :parse, :build_cmd
13
+ end
14
+
15
+ describe Rsync do
16
+ describe "#initialize" do
17
+ it "works" do
18
+ Rc.media = "/media"
19
+ rsync =Rsync.new("/home <%=Rc.media%>")
20
+
21
+ rsync.instance_variable_get(:@end_cmd).should == "/home /media"
22
+ end
23
+ end
24
+
25
+ describe "#build_cmd" do
26
+ it "works" do
27
+ Rc.action = "backup"
28
+ Rc.backup.rsync.options = "-a"
29
+ rsync = Rsync.new("x")
30
+
31
+ rsync.build_cmd("/foo /bar").should == "rsync -a /foo /bar"
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ describe Rsync2 do
38
+ describe "#scan" do
39
+ it "works" do
40
+ data=<<-EOF
41
+ [guten]
42
+ dsaf
43
+ bar
44
+
45
+ [tagen]
46
+ hello
47
+ EOF
48
+
49
+ rsync = Rsync2.new("x")
50
+ a = rsync.scan(data)
51
+ b = { "guten" => "dsaf\nbar\n\n", "tagen" => "hello\n"}
52
+ a.should == b
53
+ end
54
+ end
55
+
56
+ describe "#parse" do
57
+ it "works" do
58
+ rsync = Rsync2.new("x")
59
+
60
+ file = Pa("#{$spec_tmp}/file")
61
+ data=<<-EOF
62
+ <%=Rc.foo%> /tmp /bar
63
+
64
+ [foo]
65
+ guten
66
+ EOF
67
+
68
+
69
+ File.write(file.p, data)
70
+ Rc.foo = 1
71
+
72
+ a = rsync.parse(file)
73
+ b = [ "1 /tmp /bar", { "foo" => "guten\n" } ]
74
+ a.should == b
75
+ end
76
+ end
77
+
78
+ describe "#build_cmd" do
79
+ it "works" do
80
+ Rc.backup.rsync.options = "-avh"
81
+ Rc.action = "backup"
82
+ Rc.profile = "ywank"
83
+ rsync = Rsync2.new("x")
84
+ rsync.instance_variable_set(:@dir, "/a")
85
+
86
+ a = rsync.build_cmd("/tmp /bar", {"files" => "x", "include" => "y"})
87
+ b = "rsync -avh --files-from /a/files --include-from /a/include /tmp /bar"
88
+ a.should == b
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ describe Kernel do
4
+ it "#configure" do
5
+ configure <<-EOF
6
+ a = 1
7
+ EOF
8
+
9
+ Rc.a.should == 1
10
+ end
11
+
12
+ it "#backup" do
13
+ backup(:foo){ "backup" }
14
+
15
+ Rc.backup_blks[:foo].call.should == "backup"
16
+ end
17
+
18
+ it "#restore" do
19
+ restore(:foo){ "restore" }
20
+
21
+ Rc.restore_blks[:foo].call.should == "restore"
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ require "oldtime"
2
+
3
+ $spec_dir = File.expand_path("..", __FILE__)
4
+ $spec_tmp = File.expand_path("../tmp", __FILE__)
data/spec/tmp/file ADDED
@@ -0,0 +1,4 @@
1
+ <%=Rc.foo%> /tmp /bar
2
+
3
+ [foo]
4
+ guten
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oldtime
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Guten
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-31 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'the backup & restore sytem
15
+
16
+ '
17
+ email: ywzhaifei@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - .rspec
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - README.md
27
+ - Ragfile
28
+ - bin/oldtime
29
+ - lib/oldtime.rb
30
+ - lib/oldtime/archlinux.rb
31
+ - lib/oldtime/cli.rb
32
+ - lib/oldtime/rc.rb
33
+ - lib/oldtime/rsync.rb
34
+ - lib/oldtime/ui.rb
35
+ - lib/oldtime/version.rb
36
+ - oldtime.gemspec
37
+ - oldtime.watchr
38
+ - spec/oldtime/cli_spec.rb
39
+ - spec/oldtime/rsync_spec.rb
40
+ - spec/oldtime_spec.rb
41
+ - spec/spec_helper.rb
42
+ - spec/tmp/file
43
+ homepage: http://github.com/GutenYe/oldtime
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project: xx
63
+ rubygems_version: 1.8.11
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: the backup & restore system
67
+ test_files: []
68
+ has_rdoc: