giternal-digarc 0.1.1Digarc

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.
File without changes
@@ -0,0 +1,6 @@
1
+ spec/test_repos
2
+ pkg
3
+ features/tmp
4
+ test_repos
5
+ .idea
6
+ .rvmrc
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.
@@ -0,0 +1,93 @@
1
+ = Why giternal
2
+
3
+ There are a couple tools out there that keep track of git externals
4
+ for you. Git submodules are built in, and braid is a different
5
+ project. They both have problems that prevent them from using those
6
+ externals collaboratively.
7
+
8
+ In a nutshell, git submodules keep a reference to the head of each
9
+ external project. This means that if Joe and Sarah each make
10
+ non-conflicting changes to their externals, and push the external
11
+ reference in the main project, one of them will get a conflict on
12
+ update. Braid doesn't treat the externals as being separate from the
13
+ main project, so any commits you make will go to the parent instead of
14
+ the external.
15
+
16
+ In order to demonstrate these issues more concretely, I've written a
17
+ script that will simulate the workflow of making changes to an
18
+ external, pushing it upstream, and pulling it into another project.
19
+ You'll notice in the submodule example that there's a conflict when
20
+ updating the main repo, and files are missing in the local external
21
+ after update. In the braid example, the changes never make it
22
+ upstream. This script checks to see if a tool allows you to not only
23
+ track dependencies but collaborate as well. To execute it, run
24
+
25
+ ruby test_trackers.rb giternal|submodules|braid
26
+
27
+ = Using it
28
+
29
+ Put a file in your project named .giternal.yml or config/giternal.yml,
30
+ that looks like this:
31
+
32
+ local_dir_name:
33
+ repo: git://path/to/repo.git
34
+ path: local/sub/dir
35
+ branch: any_branch_in_repo
36
+
37
+ As an example, here's how you'd track rspec:
38
+
39
+ rspec:
40
+ repo: git://github.com/dchelimsky/rspec.git
41
+ path: vendor/plugins
42
+
43
+ Or alternatively, here's how to track the experimental branch of rspec:
44
+
45
+ rspec:
46
+ repo: git://github.com/dchelimsky/rspec.git
47
+ path: vendor/plugins
48
+ branch: experimental
49
+
50
+ To pull the externals into your workspace, run "giternal update". You
51
+ should add vendor/plugins/rspec to .gitignore to keep the files from
52
+ being added to your main repo.
53
+
54
+ If you specify a branch, on a fresh check out it will check out that branch. If you already have a different branch checked out, it will switch to the specified branch (CAUTION! YOU WILL LOSE UNCOMMITED CHANGES!)
55
+
56
+ = Deploying externals
57
+
58
+ I frequently use a cap task that changes to deploy_root and runs
59
+ "giternal update" to pull all the externals. The downside with this
60
+ approach is that you'll get the bleeding edge of your external, and
61
+ you may want to use a particular version that you've tested and know
62
+ works with your app. Enter freezing.
63
+
64
+ Make sure your working dir is clean and then run "giternal freeze".
65
+ The externals are no longer separate repos - the history was zipped up
66
+ so that the external can be unfrozen later. Each external is added to
67
+ the git index, so all you have to do is commit. You've got a
68
+ self-contained external that is frozen to a working version, suitable
69
+ for deploy.
70
+
71
+ After you've tagged your release, you can unfreeze the giternal with
72
+ "giternal unfreeze" and get back to development.
73
+
74
+ = How I want to work with externals
75
+
76
+ When tracking externals, the most important thing is knowing my
77
+ libraries work together, and second I can try to stay up to date.
78
+ When I update an external, I would run rake. If it passes, keep that
79
+ version. If not, look at what it would take to take for my code and
80
+ the library code to work. If I feel like I can do it, I do, otherwise
81
+ I unfreeze and stay on the older working version.
82
+
83
+ = THANK YOUs
84
+
85
+ Rollcall of awesome people who have contributed to giternal:
86
+
87
+ Brian Takita & Honkster Team - ability to specify individual repos for
88
+ freeze/unfreeze/update
89
+
90
+
91
+ == Copyright
92
+
93
+ Copyright (c) 2009-2011 Pat Maddox. See LICENSE for details.
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "#{ENV["GEM_PREFIX"]}giternal"
8
+ gem.summary = %Q{Non-sucky git externals}
9
+ gem.description = %Q{Giternal provides dead-simple management of external git dependencies. It only stores a small bit of metadata, letting you actively develop in any of the repos. Come deploy time, you can easily freeze freeze all the dependencies to particular versions}
10
+ gem.email = "pat.maddox@gmail.com"
11
+ gem.homepage = "http://github.com/pat-maddox/giternal"
12
+ gem.authors = ["Pat Maddox"]
13
+ gem.add_development_dependency "rspec"
14
+ gem.add_development_dependency "cucumber"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ begin
36
+ require 'cucumber/rake/task'
37
+ Cucumber::Rake::Task.new(:features)
38
+
39
+ task :features => :check_dependencies
40
+ rescue LoadError
41
+ task :features do
42
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
43
+ end
44
+ end
45
+
46
+ task :default => [:spec, :features]
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ if File.exist?('VERSION')
51
+ version = File.read('VERSION')
52
+ else
53
+ version = ""
54
+ end
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "giternal #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 1
3
+ :patch: 0
4
+ :major: 0
@@ -0,0 +1,19 @@
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
+ puts ""
13
+ puts File.read(File.dirname(__FILE__) + '/../README.rdoc')
14
+ exit 1
15
+ end
16
+
17
+ Giternal::Repository.verbose = true
18
+ app = Giternal::App.new(FileUtils.pwd)
19
+ app.run(*ARGV)
@@ -0,0 +1,51 @@
1
+ Feature: Checking out and updating externals
2
+ As a developer
3
+ I want to check out and update external projects via git
4
+ So that I can add functionality to my app with little effort
5
+
6
+ Scenario: Repository is not yet checked out
7
+ Given an external repository named 'first_external'
8
+ And 'first_external' is not yet checked out
9
+ When I update the externals
10
+ Then 'first_external' should be checked out
11
+
12
+ Scenario: Multiple externals
13
+ Given an external repository named 'first_external'
14
+ And an external repository named 'second_external'
15
+ When I update the externals
16
+ Then 'first_external' should be checked out
17
+ And 'second_external' should be checked out
18
+
19
+ Scenario: Repository checked out then updated
20
+ Given an external repository named 'first_external'
21
+ And the externals are up to date
22
+ And content is added to 'first_external'
23
+ Then 'first_external' should not be up to date
24
+ When I update the externals
25
+ Then 'first_external' should be up to date
26
+
27
+ Scenario: Two Repositories checked out and one updated
28
+ Given an external repository named 'first_external'
29
+ And an external repository named 'second_external'
30
+ And the externals are up to date
31
+ And content is added to 'first_external'
32
+ And content is added to 'second_external'
33
+ Then 'first_external' should not be up to date
34
+ And 'second_external' should not be up to date
35
+ When I update the external 'second_external'
36
+ Then 'first_external' should not be up to date
37
+ And 'second_external' should be up to date
38
+
39
+ Scenario: One repo frozen, one repo unfrozen, and all updated
40
+ Given an external repository named 'first_external'
41
+ And an external repository named 'second_external'
42
+ And the externals are up to date
43
+ And the externals are frozen
44
+ And content is added to 'first_external'
45
+ And content is added to 'second_external'
46
+ Then 'first_external' should not be up to date
47
+ And 'second_external' should not be up to date
48
+ When I unfreeze the external 'second_external'
49
+ And I update the externals
50
+ Then 'first_external' should not be up to date
51
+ And 'second_external' should be up to date
@@ -0,0 +1,26 @@
1
+ Feature: Freeze externals
2
+ As a developer
3
+ I want to freeze externals
4
+ So that I can test and deploy my app with no worries
5
+
6
+ Scenario: Main project has one external
7
+ Given an external repository named 'first_external'
8
+ And the externals are up to date
9
+ When I freeze the externals
10
+ Then 'first_external' should no longer be a git repo
11
+ And 'first_external' should be added to the commit index
12
+
13
+ Scenario: External has been added to .gitignore
14
+ Given an external repository named 'first_external'
15
+ And the external 'first_external' has been added to .gitignore
16
+ And the externals are up to date
17
+ When I freeze the externals
18
+ Then 'first_external' should be added to the commit index
19
+
20
+ Scenario: Main project has two externals
21
+ Given an external repository named 'first_external'
22
+ And an external repository named 'second_external'
23
+ And the externals are up to date
24
+ When I freeze the external 'second_external'
25
+ Then 'second_external' should be added to the commit index
26
+ And 'first_external' should be removed from the commit index
@@ -0,0 +1,117 @@
1
+ require 'rspec'
2
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
3
+ require 'giternal'
4
+ require 'giternal_helper'
5
+
6
+ RSpec::Matchers.define :be_up_to_date do
7
+ match do |actual_repo_name|
8
+ File.directory?(GiternalHelper.checked_out_path(actual_repo_name)) &&
9
+ GiternalHelper.repo_contents(GiternalHelper.checked_out_path(actual_repo_name)) ==
10
+ GiternalHelper.repo_contents(GiternalHelper.external_path(actual_repo_name))
11
+ end
12
+ end
13
+
14
+ RSpec::Matchers.define :be_a_git_repo do
15
+ match do |actual_repo_name|
16
+ File.directory?(GiternalHelper.checked_out_path(actual_repo_name) + '/.git')
17
+ end
18
+ end
19
+
20
+ RSpec::Matchers.define :be_added_to_commit_index do
21
+ match do |actual_repo_name|
22
+ Dir.chdir(GiternalHelper.tmp_path + '/main_repo') do
23
+ status = `git status`
24
+ flattened_status = status.split("\n").join(" ")
25
+ to_be_committed_regex = /new file:\W+dependencies\/#{actual_repo_name}/
26
+ untracked_files_regex = /Untracked files:.*#{actual_repo_name}/
27
+ status =~ to_be_committed_regex && !(flattened_status =~ untracked_files_regex)
28
+ end
29
+ end
30
+ end
31
+
32
+ Before do
33
+ GiternalHelper.clean!
34
+ GiternalHelper.create_main_repo
35
+ end
36
+
37
+ After do
38
+ GiternalHelper.clean!
39
+ end
40
+
41
+ Given /an external repository named '(.*)'/ do |repo_name|
42
+ GiternalHelper.create_repo repo_name
43
+ GiternalHelper.add_content repo_name
44
+ end
45
+
46
+ Given /'(.*)' is not yet checked out/ do |repo_name|
47
+ # TODO: Figure out why I can't use should be_false here
48
+ File.directory?(GiternalHelper.checked_out_path(repo_name)).should == false
49
+ end
50
+
51
+ Given "the externals are up to date" do
52
+ GiternalHelper.update_externals
53
+ end
54
+
55
+ Given "the externals are frozen" do
56
+ GiternalHelper.freeze_externals
57
+ end
58
+
59
+ Given /content is added to '(.*)'/ do |repo_name|
60
+ GiternalHelper.add_content(repo_name)
61
+ end
62
+
63
+ Given /^the external '(.*)' has been added to \.gitignore$/ do |repo_name|
64
+ GiternalHelper.add_external_to_ignore(repo_name)
65
+ end
66
+
67
+ When "I update the externals" do
68
+ GiternalHelper.update_externals
69
+ end
70
+
71
+ When /I update the external '(.*)'/ do |external_name|
72
+ GiternalHelper.update_externals("dependencies/#{external_name}")
73
+ end
74
+
75
+ When "I freeze the externals" do
76
+ GiternalHelper.freeze_externals
77
+ end
78
+
79
+ When /I freeze the external '(.*)'/ do |external_name|
80
+ GiternalHelper.freeze_externals("dependencies/#{external_name}")
81
+ end
82
+
83
+ When "I unfreeze the externals" do
84
+ GiternalHelper.unfreeze_externals
85
+ end
86
+
87
+ When /I unfreeze the external '(.*)'/ do |external_name|
88
+ GiternalHelper.unfreeze_externals("dependencies/#{external_name}")
89
+ end
90
+
91
+ Then /'(.*)' should be checked out/ do |repo_name|
92
+ repo_name.should be_up_to_date
93
+ end
94
+
95
+ Then /'(.*)' should be up to date/ do |repo_name|
96
+ repo_name.should be_up_to_date
97
+ end
98
+
99
+ Then /'(.*)' should not be up to date/ do |repo_name|
100
+ repo_name.should_not be_up_to_date
101
+ end
102
+
103
+ Then /'(.*)' should no longer be a git repo/ do |repo_name|
104
+ repo_name.should_not be_a_git_repo
105
+ end
106
+
107
+ Then /'(.*)' should be a git repo/ do |repo_name|
108
+ repo_name.should be_a_git_repo
109
+ end
110
+
111
+ Then /'(.*)' should be added to the commit index/ do |repo_name|
112
+ repo_name.should be_added_to_commit_index
113
+ end
114
+
115
+ Then /'(.*)' should be removed from the commit index/ do |repo_name|
116
+ repo_name.should_not be_added_to_commit_index
117
+ end
@@ -0,0 +1,23 @@
1
+ Feature: Unfreeze externals
2
+ As a developer
3
+ I want to unfreeze externals
4
+ So that I can continue to update and develop on them
5
+
6
+ Scenario: Main project has one frozen external
7
+ Given an external repository named 'first_external'
8
+ And the externals are up to date
9
+ And the externals are frozen
10
+ When I unfreeze the externals
11
+ Then 'first_external' should be a git repo
12
+ And 'first_external' should be removed from the commit index
13
+
14
+ Scenario: Main project has two frozen externals
15
+ Given an external repository named 'first_external'
16
+ And an external repository named 'second_external'
17
+ And the externals are up to date
18
+ And the externals are frozen
19
+ When I unfreeze the external 'second_external'
20
+ Then 'second_external' should be a git repo
21
+ And 'second_external' should be removed from the commit index
22
+ And 'first_external' should no longer be a git repo
23
+ And 'first_external' should be added to the commit index
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{giternal-digarc}
8
+ s.version = "0.1.1Digarc"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Pat Maddox"]
12
+ s.date = %q{2009-10-10}
13
+ s.default_executable = %q{giternal}
14
+ s.description = %q{Giternal provides dead-simple management of external git dependencies. It only stores a small bit of metadata, letting you actively develop in any of the repos. Come deploy time, you can easily freeze freeze all the dependencies to particular versions}
15
+ s.email = %q{pat.maddox@gmail.com}
16
+ s.executables = ["giternal"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".emacs-project",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION.yml",
28
+ "bin/giternal",
29
+ "features/checking_out_externals.feature",
30
+ "features/freeze_externals.feature",
31
+ "features/steps/repository_steps.rb",
32
+ "features/unfreeze_externals.feature",
33
+ "giternal.gemspec",
34
+ "giternal_helper.rb",
35
+ "lib/giternal.rb",
36
+ "lib/giternal/app.rb",
37
+ "lib/giternal/repository.rb",
38
+ "lib/giternal/version.rb",
39
+ "lib/giternal/yaml_config.rb",
40
+ "spec/giternal/app_spec.rb",
41
+ "spec/giternal/repository_spec.rb",
42
+ "spec/giternal/yaml_config_spec.rb",
43
+ "spec/spec.opts",
44
+ "spec/spec_helper.rb",
45
+ "test_trackers.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/pat-maddox/giternal}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.5}
51
+ s.summary = %q{Non-sucky git externals}
52
+ s.test_files = [
53
+ "spec/giternal/app_spec.rb",
54
+ "spec/giternal/repository_spec.rb",
55
+ "spec/giternal/yaml_config_spec.rb",
56
+ "spec/spec_helper.rb"
57
+ ]
58
+
59
+ if s.respond_to? :specification_version then
60
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
+ s.specification_version = 3
62
+
63
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
+ s.add_development_dependency(%q<rspec>, [">= 0"])
65
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
66
+ else
67
+ s.add_dependency(%q<rspec>, [">= 0"])
68
+ s.add_dependency(%q<cucumber>, [">= 0"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<rspec>, [">= 0"])
72
+ s.add_dependency(%q<cucumber>, [">= 0"])
73
+ end
74
+ end