pat-maddox-giternal 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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pat Maddox
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = giternal
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Pat Maddox. See LICENSE for details.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 1
3
+ :patch: 0
4
+ :major: 0
data/bin/giternal ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ if File.exist?(File.dirname(__FILE__) + '/../lib/giternal.rb')
4
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
5
+ end
6
+ require 'giternal'
7
+
8
+ action = ARGV[0]
9
+ available_actions = %w(update freeze unfreeze)
10
+ unless available_actions.include?(action)
11
+ puts "Usage: giternal (#{available_actions.join(':')})"
12
+ exit 1
13
+ end
14
+
15
+ Giternal::Repository.verbose = true
16
+ app = Giternal::App.new(FileUtils.pwd)
17
+ app.run(action)
data/lib/giternal.rb ADDED
@@ -0,0 +1,10 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Giternal
5
+
6
+ end
7
+
8
+ require 'giternal/repository'
9
+ require 'giternal/yaml_config'
10
+ require 'giternal/app'
@@ -0,0 +1,45 @@
1
+ module Giternal
2
+ class App
3
+ def initialize(base_dir)
4
+ @base_dir = base_dir
5
+ end
6
+
7
+ def update
8
+ config.each_repo {|r| r.update }
9
+ end
10
+
11
+ def freezify
12
+ config.each_repo {|r| r.freezify }
13
+ end
14
+
15
+ def unfreezify
16
+ config.each_repo {|r| r.unfreezify }
17
+ end
18
+
19
+ def run(action)
20
+ case action
21
+ when "freeze"
22
+ freezify
23
+ when "unfreeze"
24
+ unfreezify
25
+ else
26
+ send(action)
27
+ end
28
+ end
29
+
30
+ def config
31
+ return @config if @config
32
+
33
+ config_file = ['config/giternal.yml', '.giternal.yml'].detect do |file|
34
+ File.file? File.expand_path(@base_dir + '/' + file)
35
+ end
36
+
37
+ if config_file.nil?
38
+ $stderr.puts "config/giternal.yml is missing"
39
+ exit 1
40
+ end
41
+
42
+ @config = YamlConfig.new(@base_dir, File.read(config_file))
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,92 @@
1
+ require 'fileutils'
2
+
3
+ module Giternal
4
+ class Repository
5
+ class << self
6
+ attr_accessor :verbose
7
+ end
8
+ attr_accessor :verbose
9
+
10
+ def initialize(base_dir, name, repo_url, rel_path)
11
+ @base_dir = base_dir
12
+ @name = name
13
+ @repo_url = repo_url
14
+ @rel_path = rel_path
15
+ @verbose = self.class.verbose
16
+ end
17
+
18
+ def update
19
+ git_ignore_self
20
+
21
+ return true if frozen?
22
+ FileUtils.mkdir_p checkout_path unless File.exist?(checkout_path)
23
+ if checked_out?
24
+ if !File.exist?(repo_path + '/.git')
25
+ raise "Directory '#{@name}' exists but is not a git repository"
26
+ else
27
+ update_output { `cd #{repo_path} && git pull 2>&1` }
28
+ end
29
+ else
30
+ update_output { `cd #{checkout_path} && git clone #{@repo_url} #{@name}` }
31
+ end
32
+ true
33
+ end
34
+
35
+ def freezify
36
+ return true if frozen? || !checked_out?
37
+
38
+ Dir.chdir(repo_path) do
39
+ `tar czf .git.frozen.tgz .git`
40
+ FileUtils.rm_r('.git')
41
+ end
42
+ `cd #{@base_dir} && git add -f #{rel_repo_path}`
43
+ true
44
+ end
45
+
46
+ def unfreezify
47
+ return true unless frozen?
48
+
49
+ Dir.chdir(repo_path) do
50
+ `tar xzf .git.frozen.tgz`
51
+ FileUtils.rm('.git.frozen.tgz')
52
+ end
53
+ `cd #{@base_dir} && git rm -r --cached #{rel_repo_path}`
54
+ true
55
+ end
56
+
57
+ def frozen?
58
+ File.exist?(repo_path + '/.git.frozen.tgz')
59
+ end
60
+
61
+ def checked_out?
62
+ File.exist?(repo_path)
63
+ end
64
+
65
+ private
66
+ def checkout_path
67
+ File.expand_path(File.join(@base_dir, @rel_path))
68
+ end
69
+
70
+ def repo_path
71
+ File.expand_path(checkout_path + '/' + @name)
72
+ end
73
+
74
+ def rel_repo_path
75
+ @rel_path + '/' + @name
76
+ end
77
+
78
+ def update_output(&block)
79
+ puts "Updating #{@name}" if verbose
80
+ block.call
81
+ puts " ..updated\n" if verbose
82
+ end
83
+
84
+ def git_ignore_self
85
+ Dir.chdir(@base_dir) do
86
+ unless File.exist?('.gitignore') && File.read('.gitignore').include?(rel_repo_path)
87
+ `echo '#{rel_repo_path}' >> .gitignore`
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ module Giternal
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ require 'yaml'
2
+
3
+ module Giternal
4
+ class YamlConfig
5
+ def initialize(base_dir, yaml_string)
6
+ @base_dir = base_dir
7
+ @config_hash = YAML.load yaml_string
8
+ end
9
+
10
+ def each_repo
11
+ repositories.each { |r| yield(r) if block_given? }
12
+ end
13
+
14
+ private
15
+ def repositories
16
+ @config_hash.map do |name, attributes|
17
+ Repository.new(@base_dir, name, attributes["repo"], attributes["path"])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ module Giternal
4
+ describe App do
5
+ before(:each) do
6
+ @app = App.new("some_fake_dir")
7
+ @mock_config = stub("config", :null_object => true)
8
+ end
9
+
10
+ describe "loading the config file" do
11
+ before(:each) do
12
+ File.stub!(:file?).and_return true
13
+ File.stub!(:read).and_return "yaml config"
14
+ YamlConfig.stub!(:new).and_return @mock_config
15
+ end
16
+
17
+ it "should look for config/giternal.yml" do
18
+ File.should_receive(:file?).with(/some_fake_dir\/config\/giternal\.yml/)
19
+ @app.config
20
+ end
21
+
22
+ it "should look for .giternal.yml if giternal.yml does not exist" do
23
+ File.should_receive(:file?).with(/some_fake_dir\/config\/giternal\.yml/).and_return false
24
+ File.should_receive(:file?).with(/some_fake_dir\/\.giternal\.yml/).and_return true
25
+ @app.config
26
+ end
27
+
28
+ it "should exit with an error when no config file exists" do
29
+ File.stub!(:file?).and_return false
30
+ $stderr.should_receive(:puts)
31
+ @app.should_receive(:exit).with(1)
32
+ @app.config
33
+ end
34
+
35
+ it "should create a config from the config file" do
36
+ YamlConfig.should_receive(:new).with('some_fake_dir', "yaml config").and_return @mock_config
37
+ @app.config
38
+ end
39
+ end
40
+
41
+ describe "app actions" do
42
+ before(:each) do
43
+ @app.stub!(:config).and_return @mock_config
44
+ @mock_repo = mock("repo")
45
+ @mock_config.stub!(:each_repo).and_yield(@mock_repo)
46
+ end
47
+
48
+ it "should update each of the repositories" do
49
+ @mock_repo.should_receive(:update)
50
+ @app.update
51
+ end
52
+
53
+ it "should freeze each of the repositories" do
54
+ @mock_repo.should_receive(:freezify)
55
+ @app.freezify
56
+ end
57
+
58
+ it "should unfreeze each of the repositories" do
59
+ @mock_repo.should_receive(:unfreezify)
60
+ @app.unfreezify
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,133 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ module Giternal
4
+ describe Repository do
5
+ before(:each) do
6
+ GiternalHelper.create_main_repo
7
+ GiternalHelper.create_repo 'foo'
8
+ @repository = Repository.new(GiternalHelper.base_project_dir, "foo",
9
+ GiternalHelper.external_path('foo'),
10
+ 'dependencies')
11
+ end
12
+
13
+ it "should check itself out to a dir" do
14
+ @repository.update
15
+ File.file?(GiternalHelper.checked_out_path('foo/foo')).should be_true
16
+ File.read(GiternalHelper.checked_out_path('foo/foo')).strip.
17
+ should == 'foo'
18
+ end
19
+
20
+ it "should be ignored from git" do
21
+ @repository.update
22
+ Dir.chdir(GiternalHelper.base_project_dir) do
23
+ # TODO: What I really want is to say it shouldn't include 'foo'
24
+ `git status`.should_not include('dependencies')
25
+ end
26
+ end
27
+
28
+ it "should only add itself to .gitignore if it's not already there" do
29
+ 2.times { @repository.update }
30
+ Dir.chdir(GiternalHelper.base_project_dir) do
31
+ File.read('.gitignore').scan(/foo/).should have(1).item
32
+ # TODO: What I really want is to say it shouldn't include 'foo'
33
+ `git status`.should_not include('dependencies')
34
+ end
35
+ end
36
+
37
+ it "should not show any output when verbose mode is off" do
38
+ @repository.verbose = false
39
+ @repository.should_not_receive(:puts)
40
+ @repository.update
41
+ end
42
+
43
+ it "should not show output when verbose mode is on" do
44
+ @repository.verbose = true
45
+ @repository.should_receive(:puts).any_number_of_times
46
+ @repository.update
47
+ end
48
+
49
+ it "should update the repo when it's already been checked out" do
50
+ @repository.update
51
+ GiternalHelper.add_content 'foo', 'newfile'
52
+ @repository.update
53
+ File.file?(GiternalHelper.checked_out_path('foo/newfile')).should be_true
54
+ File.read(GiternalHelper.checked_out_path('foo/newfile')).strip.
55
+ should == 'newfile'
56
+ end
57
+
58
+ it "should raise an error if the directory exists but there's no .git dir" do
59
+ FileUtils.mkdir_p(GiternalHelper.checked_out_path('foo'))
60
+ lambda {
61
+ @repository.update
62
+ }.should raise_error(/Directory 'foo' exists but is not a git repository/)
63
+ end
64
+
65
+ describe "freezify" do
66
+ before(:each) do
67
+ GiternalHelper.create_repo('external')
68
+ @repository = Repository.new(GiternalHelper.base_project_dir, 'external',
69
+ GiternalHelper.external_path('external'),
70
+ 'dependencies')
71
+ @repository.update
72
+ end
73
+
74
+ it "should archive the .git dir" do
75
+ @repository.freezify
76
+ File.file?(GiternalHelper.checked_out_path('external/.git.frozen.tgz')).should be_true
77
+ end
78
+
79
+ it "should get rid of the .git dir" do
80
+ File.directory?(GiternalHelper.checked_out_path('external/.git')).should be_true
81
+ @repository.freezify
82
+ File.directory?(GiternalHelper.checked_out_path('external/.git')).should be_false
83
+ end
84
+ end
85
+
86
+ it "should simply return if updated when frozen" do
87
+ @repository.update
88
+ @repository.freezify
89
+ lambda { @repository.update }.should_not raise_error
90
+ end
91
+
92
+ it "should simply return when made to freeze when already frozen" do
93
+ @repository.update
94
+ @repository.freezify
95
+ lambda { @repository.freezify }.should_not raise_error
96
+ end
97
+
98
+ it "should simply return when made to freeze before checked out" do
99
+ lambda { @repository.freezify }.should_not raise_error
100
+ end
101
+
102
+ it "should simply return when made to unfreeze before checked out" do
103
+ lambda { @repository.unfreezify }.should_not raise_error
104
+ end
105
+
106
+ it "should simply return when made to unfreeze when already unfrozen" do
107
+ @repository.update
108
+ lambda { @repository.unfreezify }.should_not raise_error
109
+ end
110
+
111
+ describe "unfreezify" do
112
+ before(:each) do
113
+ GiternalHelper.create_repo('main')
114
+ GiternalHelper.create_repo('external')
115
+ @repository = Repository.new(GiternalHelper.base_project_dir, 'external',
116
+ GiternalHelper.external_path('external'),
117
+ 'dependencies')
118
+ @repository.update
119
+ @repository.freezify
120
+ end
121
+
122
+ it "should unarchive the .git dir" do
123
+ @repository.unfreezify
124
+ File.directory?(GiternalHelper.checked_out_path('external/.git')).should be_true
125
+ end
126
+
127
+ it "should remove the archived file" do
128
+ @repository.unfreezify
129
+ File.file?(GiternalHelper.checked_out_path('external/.git.frozen.tgz')).should be_false
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ module Giternal
4
+ describe YamlConfig do
5
+ it "should create repositories from the config" do
6
+ config = YamlConfig.new('base_dir',
7
+ "rspec:\n repo: git://rspec\n path: vendor/plugins\n" +
8
+ "foo:\n repo: git://at/foo\n path: path/to/foo\n")
9
+ Repository.should_receive(:new).with('base_dir', "rspec", "git://rspec", "vendor/plugins").and_return :a_repo
10
+ Repository.should_receive(:new).with('base_dir', "foo", "git://at/foo", "path/to/foo").and_return :a_repo
11
+ config.each_repo {|r| r.should == :a_repo}
12
+ end
13
+ end
14
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+
8
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
9
+ require 'giternal'
10
+ require 'fileutils'
11
+ require 'giternal_helper'
12
+
13
+ Spec::Runner.configuration.before(:each) do
14
+ GiternalHelper.wipe_repos
15
+ end
16
+
17
+ Spec::Runner.configuration.after(:each) do
18
+ GiternalHelper.wipe_repos
19
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pat-maddox-giternal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Pat Maddox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-04 00:00:00 -07:00
13
+ default_executable: giternal
14
+ dependencies: []
15
+
16
+ description:
17
+ email: pat.maddox@gmail.com
18
+ executables:
19
+ - giternal
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - LICENSE
25
+ files:
26
+ - README.rdoc
27
+ - VERSION.yml
28
+ - bin/giternal
29
+ - lib/giternal
30
+ - lib/giternal/app.rb
31
+ - lib/giternal/repository.rb
32
+ - lib/giternal/version.rb
33
+ - lib/giternal/yaml_config.rb
34
+ - lib/giternal.rb
35
+ - spec/giternal
36
+ - spec/giternal/app_spec.rb
37
+ - spec/giternal/repository_spec.rb
38
+ - spec/giternal/yaml_config_spec.rb
39
+ - spec/spec.opts
40
+ - spec/spec_helper.rb
41
+ - LICENSE
42
+ has_rdoc: true
43
+ homepage: http://github.com/pat-maddox/giternal
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --inline-source
47
+ - --charset=UTF-8
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: TODO
69
+ test_files: []
70
+