amp-core 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.
Files changed (46) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +17 -0
  6. data/Rakefile +67 -0
  7. data/VERSION +1 -0
  8. data/features/amp-core.feature +9 -0
  9. data/features/step_definitions/amp-core_steps.rb +0 -0
  10. data/features/support/env.rb +4 -0
  11. data/lib/amp-core.rb +53 -0
  12. data/lib/amp-core/command_ext/repository_loading.rb +31 -0
  13. data/lib/amp-core/repository/abstract/abstract_changeset.rb +113 -0
  14. data/lib/amp-core/repository/abstract/abstract_local_repo.rb +208 -0
  15. data/lib/amp-core/repository/abstract/abstract_staging_area.rb +202 -0
  16. data/lib/amp-core/repository/abstract/abstract_versioned_file.rb +116 -0
  17. data/lib/amp-core/repository/abstract/common_methods/changeset.rb +185 -0
  18. data/lib/amp-core/repository/abstract/common_methods/local_repo.rb +293 -0
  19. data/lib/amp-core/repository/abstract/common_methods/staging_area.rb +248 -0
  20. data/lib/amp-core/repository/abstract/common_methods/versioned_file.rb +87 -0
  21. data/lib/amp-core/repository/generic_repo_picker.rb +94 -0
  22. data/lib/amp-core/repository/repository.rb +41 -0
  23. data/lib/amp-core/support/encoding_utils.rb +46 -0
  24. data/lib/amp-core/support/platform_utils.rb +92 -0
  25. data/lib/amp-core/support/rooted_opener.rb +143 -0
  26. data/lib/amp-core/support/string_utils.rb +86 -0
  27. data/lib/amp-core/templates/git/blank.log.erb +18 -0
  28. data/lib/amp-core/templates/git/default.log.erb +18 -0
  29. data/lib/amp-core/templates/mercurial/blank.commit.erb +23 -0
  30. data/lib/amp-core/templates/mercurial/blank.log.erb +18 -0
  31. data/lib/amp-core/templates/mercurial/default.commit.erb +23 -0
  32. data/lib/amp-core/templates/mercurial/default.log.erb +26 -0
  33. data/lib/amp-core/templates/template.rb +202 -0
  34. data/spec/amp-core_spec.rb +11 -0
  35. data/spec/command_ext_specs/repository_loading_spec.rb +64 -0
  36. data/spec/command_ext_specs/spec_helper.rb +1 -0
  37. data/spec/repository_specs/repository_spec.rb +41 -0
  38. data/spec/repository_specs/spec_helper.rb +1 -0
  39. data/spec/spec.opts +1 -0
  40. data/spec/spec_helper.rb +14 -0
  41. data/spec/support_specs/encoding_utils_spec.rb +69 -0
  42. data/spec/support_specs/platform_utils_spec.rb +33 -0
  43. data/spec/support_specs/spec_helper.rb +1 -0
  44. data/spec/support_specs/string_utils_spec.rb +44 -0
  45. data/test/test_templates.rb +81 -0
  46. metadata +157 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .hg*
23
+ *.gemspec
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # This is an install-only file - it's not used by the application
2
+ source "http://rubygems.org"
3
+
4
+ gem 'amp-front'
5
+
6
+ group :development do
7
+ gem 'jeweler'
8
+ gem 'rspec', '< 2.0.0'
9
+ gem 'yard'
10
+ gem 'cucumber'
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Michael Edgar
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,17 @@
1
+ = amp-core
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Michael Edgar. See LICENSE for details.
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "amp-core"
8
+ gem.summary = %Q{The core plugin for Amp. Necessary for Amp to function.}
9
+ gem.description = <<-EOF
10
+ Amp's required plugin, providing core functionality (such as repository detection
11
+ and amp-specific command validations) to all other plugins.
12
+ EOF
13
+ gem.email = "michael.j.edgar@dartmouth.edu"
14
+ gem.homepage = "http://github.com/michaeledgar/amp-core"
15
+ gem.authors = ["Michael Edgar"]
16
+ gem.add_development_dependency "rspec", ">= 1.2.9"
17
+ gem.add_development_dependency "yard", ">= 0"
18
+ gem.add_development_dependency "cucumber", ">= 0"
19
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
20
+ end
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
25
+
26
+ require 'spec/rake/spectask'
27
+ Spec::Rake::SpecTask.new(:spec) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.spec_files = FileList['spec/**/*_spec.rb']
30
+ end
31
+
32
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.rcov = true
36
+ end
37
+
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new do |t|
40
+ t.libs << "test"
41
+ t.test_files = FileList['test/**/test*.rb']
42
+ t.verbose = true
43
+ end
44
+
45
+ task :spec => :check_dependencies
46
+
47
+ begin
48
+ require 'cucumber/rake/task'
49
+ Cucumber::Rake::Task.new(:features)
50
+
51
+ task :features => :check_dependencies
52
+ rescue LoadError
53
+ task :features do
54
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
55
+ end
56
+ end
57
+
58
+ task :default => [:spec, :test]
59
+
60
+ begin
61
+ require 'yard'
62
+ YARD::Rake::YardocTask.new
63
+ rescue LoadError
64
+ task :yardoc do
65
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
66
+ end
67
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,9 @@
1
+ Feature: something something
2
+ In order to something something
3
+ A user something something
4
+ something something something
5
+
6
+ Scenario: something something
7
+ Given inspiration
8
+ When I create a sweet new gem
9
+ Then everyone should see how awesome I am
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'amp-core'
3
+
4
+ require 'spec/expectations'
@@ -0,0 +1,53 @@
1
+ module Amp
2
+ module Core
3
+ end
4
+ module Support
5
+ end
6
+ end
7
+
8
+ class Amp::Plugins::Core < Amp::Plugins::Base
9
+ # this is necessary to prevent loading when #load! isn't called.
10
+ @loader = lambda {
11
+ $:.unshift(File.expand_path(File.dirname(__FILE__)))
12
+ module ::Amp
13
+ module Core
14
+ module Repositories
15
+ autoload :GenericRepoPicker, 'amp-core/repository/generic_repo_picker.rb'
16
+ autoload :AbstractLocalRepository, 'amp-core/repository/abstract/abstract_local_repo.rb'
17
+ autoload :AbstractStagingArea, 'amp-core/repository/abstract/abstract_staging_area.rb'
18
+ autoload :AbstractChangeset, 'amp-core/repository/abstract/abstract_changeset.rb'
19
+ autoload :AbstractVersionedFile, 'amp-core/repository/abstract/abstract_versioned_file.rb'
20
+ autoload :CommonChangesetMethods, 'amp-core/repository/abstract/common_methods/changeset.rb'
21
+ autoload :CommonLocalRepoMethods, 'amp-core/repository/abstract/common_methods/local_repo.rb'
22
+ autoload :CommonStagingAreaMethods, 'amp-core/repository/abstract/common_methods/staging_area.rb'
23
+ autoload :CommonChangesetMethods, 'amp-core/repository/abstract/common_methods/changeset.rb'
24
+ autoload :CommonVersionedFileMethods,'amp-core/repository/abstract/common_methods/versioned_file.rb'
25
+ end
26
+ module Support
27
+ autoload :EncodingUtils, 'amp-core/support/encoding_utils.rb'
28
+ autoload :Platform, 'amp-core/support/platform_utils.rb'
29
+ autoload :RootedOpener, 'amp-core/support/rooted_opener.rb'
30
+ autoload :StringUtils, 'amp-core/support/string_utils.rb'
31
+ end
32
+ end
33
+ end
34
+ }
35
+ class << self
36
+ attr_reader :loader
37
+ end
38
+
39
+ def initialize(opts={})
40
+ @opts = opts
41
+ end
42
+
43
+ def load!
44
+ puts "Loading amp-core..."
45
+ require 'amp-core/command_ext/repository_loading'
46
+ require 'amp-core/repository/repository.rb'
47
+ require 'amp-core/repository/generic_repo_picker.rb'
48
+ ::Amp::Support.class_eval do
49
+ autoload :Template, "amp-core/templates/template.rb"
50
+ end
51
+ self.class.loader.call
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ module Amp
2
+ module Core
3
+ module RepositoryLoading
4
+ def self.included(klass)
5
+ klass.__send__(:extend, ClassMethods)
6
+ klass.__send__(:include, InstanceMethods)
7
+ end
8
+ module ClassMethods
9
+
10
+ end
11
+ module InstanceMethods
12
+ DEFAULT_OPTS = {:create => false}
13
+ def repository(repo_opts=DEFAULT_OPTS)
14
+ repo_opts = DEFAULT_OPTS.merge(repo_opts)
15
+ path = options[:repository]
16
+ # pick a repo based on this
17
+ return Repositories.pick(options, path, repo_opts[:create])
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ module Command
24
+ class Base
25
+ def self.has_repo
26
+ include Core::RepositoryLoading
27
+ opt :repository, "The path to the repository to use", :short => "-R", :default => Dir.pwd
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,113 @@
1
+ ##################################################################
2
+ # Licensing Information #
3
+ # #
4
+ # The following code is licensed, as standalone code, under #
5
+ # the Ruby License, unless otherwise directed within the code. #
6
+ # #
7
+ # For information on the license of this code when distributed #
8
+ # with and used in conjunction with the other modules in the #
9
+ # Amp project, please see the root-level LICENSE file. #
10
+ # #
11
+ # © Michael J. Edgar and Ari Brown, 2009-2010 #
12
+ # #
13
+ ##################################################################
14
+
15
+ module Amp
16
+ module Core
17
+ module Repositories
18
+ class AbstractChangeset
19
+ include CommonChangesetMethods
20
+ include Enumerable
21
+ include Comparable
22
+
23
+ ##
24
+ # the nodes that this node inherits from
25
+ #
26
+ # @return [Array<Abstract Changeset>]
27
+ def parents
28
+ raise NotImplementedError.new("parents() must be implemented by subclasses of AbstractChangeset.")
29
+ end
30
+
31
+ ##
32
+ # Iterates over every tracked file in this changeset.
33
+ #
34
+ # @return [AbstractChangeset] self
35
+ def each
36
+ raise NotImplementedError.new("each() must be implemented by subclasses of AbstractChangeset.")
37
+ end
38
+
39
+ ##
40
+ # How does this changeset compare to +other+? Used in sorting.
41
+ #
42
+ # @param [AbstractChangeset] other
43
+ # @return [Integer] -1, 0, or 1
44
+ def <=>(other)
45
+ raise NotImplementedError.new("<=>() must be implemented by subclasses of AbstractChangeset.")
46
+ end
47
+
48
+ ##
49
+ # Retrieve +filename+
50
+ #
51
+ # @return [AbstractVersionedFile]
52
+ def get_file(filename)
53
+ raise NotImplementedError.new("get_file() must be implemented by subclasses of AbstractChangeset.")
54
+ end
55
+ alias_method :[], :get_file
56
+
57
+ ##
58
+ # When was the changeset made?
59
+ #
60
+ # @return [Time]
61
+ def date
62
+ raise NotImplementedError.new("date() must be implemented by subclasses of AbstractChangeset.")
63
+ end
64
+
65
+ ##
66
+ # The user who made the changeset
67
+ #
68
+ # @return [String] the user who made the changeset
69
+ def user
70
+ raise NotImplementedError.new("user() must be implemented by subclasses of AbstractChangeset.")
71
+ end
72
+
73
+ ##
74
+ # Which branch this changeset belongs to
75
+ #
76
+ # @return [String] the user who made the changeset
77
+ def branch
78
+ raise NotImplementedError.new("branch() must be implemented by subclasses of AbstractChangeset.")
79
+ end
80
+
81
+ ##
82
+ # @return [String]
83
+ def description
84
+ raise NotImplementedError.new("description() must be implemented by subclasses of AbstractChangeset.")
85
+ end
86
+
87
+ ##
88
+ # What files have been altered in this changeset?
89
+ #
90
+ # @return [Array<String>]
91
+ def altered_files
92
+ raise NotImplementedError.new("altered_files() must be implemented by subclasses of AbstractChangeset.")
93
+ end
94
+
95
+ ##
96
+ # Returns a list of all files that are tracked at this current revision.
97
+ #
98
+ # @return [Array<String>] the files tracked at the given revision
99
+ def all_files
100
+ raise NotImplementedError.new("all_files() must be implemented by subclasses of AbstractChangeset.")
101
+ end
102
+
103
+ # Is this changeset a working changeset?
104
+ #
105
+ # @return [Boolean] is the changeset representing the working directory?
106
+ def working?
107
+ raise NotImplementedError.new("working() must be implemented by subclasses of AbstractChangeset.")
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,208 @@
1
+ ##################################################################
2
+ # Licensing Information #
3
+ # #
4
+ # The following code is licensed, as standalone code, under #
5
+ # the Ruby License, unless otherwise directed within the code. #
6
+ # #
7
+ # For information on the license of this code when distributed #
8
+ # with and used in conjunction with the other modules in the #
9
+ # Amp project, please see the root-level LICENSE file. #
10
+ # #
11
+ # © Michael J. Edgar and Ari Brown, 2009-2010 #
12
+ # #
13
+ ##################################################################
14
+
15
+ module Amp
16
+ module Core
17
+ module Repositories
18
+ ##
19
+ # This class contains the functionality of all repositories ever.
20
+ # Methods here rely on certain base methods that are unimplemented,
21
+ # left as an exercise for the reader.
22
+
23
+ class AbstractLocalRepository
24
+ include CommonLocalRepoMethods
25
+
26
+ ##
27
+ # Returns the root of the repository (not the .hg/.git root)
28
+ #
29
+ # @return [String]
30
+ def root
31
+ raise NotImplementedError.new("root() must be implemented by subclasses of AbstractLocalRepository.")
32
+ end
33
+
34
+ ##
35
+ # Returns the staging area for the repository, which provides the ability to add/remove
36
+ # files in the next commit.
37
+ #
38
+ # @return [AbstractStagingArea]
39
+ def staging_area
40
+ raise NotImplementedError.new("staging_area() must be implemented by subclasses of AbstractLocalRepository.")
41
+ end
42
+
43
+ ##
44
+ # Has the file been modified from node1 to node2?
45
+ #
46
+ # @param [String] file the file to check
47
+ # @param [Hash] opts needs to have :node1 and :node2
48
+ # @return [Boolean] has the +file+ been modified?
49
+ def file_modified?(file, opts={})
50
+ raise NotImplementedError.new("file_modified?() must be implemented by subclasses of AbstractLocalRepository.")
51
+ end
52
+
53
+ ##
54
+ # Write +text+ to +filename+, where +filename+
55
+ # is local to the root.
56
+ #
57
+ # @param [String] filename The file as relative to the root
58
+ # @param [String] text The text to write to said file
59
+ def working_write(filename, text)
60
+ raise NotImplementedError.new("working_write() must be implemented by subclasses of AbstractLocalRepository.")
61
+ end
62
+
63
+ ##
64
+ # Commits a changeset or set of files to the repository. You will quite often
65
+ # use this method since it's basically the basis of version control systems.
66
+ #
67
+ # @api
68
+ # @param [Hash] opts the options to this method are all optional, so it's a very
69
+ # flexible method. Options listed below.
70
+ # @option opts [Array] :modified ([]) which files have been added or modified
71
+ # that you want to be added as a changeset.
72
+ # @option opts [Array] :removed ([]) which files should be removed in this
73
+ # commit?
74
+ # @option opts [Hash] :extra ({}) any extra data, such as "close" => true
75
+ # will close the active branch.
76
+ # @option opts [String] :message ("") the message for the commit. An editor
77
+ # will be opened if this is not provided.
78
+ # @option opts [Boolean] :force (false) Forces the commit, ignoring minor details
79
+ # like when you try to commit when no files have been changed.
80
+ # @option opts [Match] :match (nil) A match object to specify how to pick files
81
+ # to commit. These are useful so you don't accidentally commit ignored files,
82
+ # for example.
83
+ # @option opts [Array<String>] :parents (nil) the node IDs of the parents under
84
+ # which this changeset will be committed. No more than 2 for mercurial.
85
+ # @option opts [Boolean] :empty_ok (false) Is an empty commit message a-ok?
86
+ # @option opts [Boolean] :force_editor (false) Do we force the editor to be
87
+ # opened, even if :message is provided?
88
+ # @option opts [String] :user (ENV["HGUSER"]) the username to associate with the commit.
89
+ # Defaults to AmpConfig#username.
90
+ # @option opts [DateTime, Time, Date] :date (Time.now) the date to mark with
91
+ # the commit. Useful if you miss a deadline and want to pretend that you actually
92
+ # made it!
93
+ # @return [String] the digest referring to this entry in the changelog
94
+ def commit(opts={})
95
+ raise NotImplementedError.new("commit() must be implemented by subclasses of AbstractLocalRepository.")
96
+ end
97
+
98
+ ##
99
+ # Pushes changesets to a remote repository.
100
+ #
101
+ # @param [Repository] remote_repo the remote repository object to push to
102
+ # @param [Hash] options extra options for pushing
103
+ # @option options [Boolean] :force (false) Force pushing, even if it would create
104
+ # new heads (or some other error arises)
105
+ # @option options [Array<Fixnum, String>] :revs ([]) specify which revisions to push
106
+ # @return [Boolean] for success/failure
107
+ def push(remote_repo, options = {})
108
+ raise NotImplementedError.new("push() must be implemented by subclasses of AbstractLocalRepository.")
109
+ end
110
+
111
+ ##
112
+ # Pulls changesets from a remote repository
113
+ # Does *not* apply them to the working directory.
114
+ #
115
+ # @param [Repository] remote_repo the remote repository object to pull from
116
+ # @param [Hash] options extra options for pulling
117
+ # @option options [Array<String, Fixnum>] :heads ([]) which repository heads to pull, such as
118
+ # a branch name or a sha-1 identifier
119
+ # @option options [Boolean] :force (false) force the pull, ignoring any errors or warnings
120
+ # @return [Boolean] for success/failure
121
+ def pull(remote_repo, options = {})
122
+ raise NotImplementedError.new("pull() must be implemented by subclasses of AbstractLocalRepository.")
123
+ end
124
+
125
+ ##
126
+ # Returns a changeset for the given revision.
127
+ # Must support at least integer indexing as well as a string "node ID", if the repository
128
+ # system has such IDs. Also "tip" should return the tip of the revision tree.
129
+ #
130
+ # @return [AbstractChangeset]
131
+ def [](revision)
132
+ raise NotImplementedError.new("[]() must be implemented by subclasses of AbstractLocalRepository.")
133
+ end
134
+
135
+ ##
136
+ # Returns the number of changesets in the repository.
137
+ #
138
+ # @return [Fixnum]
139
+ def size
140
+ raise NotImplementedError.new("size() must be implemented by subclasses of AbstractLocalRepository.")
141
+ end
142
+
143
+ ##
144
+ # Gets a given file at the given revision, in the form of an AbstractVersionedFile object.
145
+ #
146
+ # @return [AbstractVersionedFile]
147
+ def get_file(file, revision)
148
+ raise NotImplementedError.new("get_file() must be implemented by subclasses of AbstractLocalRepository.")
149
+ end
150
+
151
+ ##
152
+ # In whatever conflict-resolution system your repository format defines, mark a given file
153
+ # as in conflict. If your format does not manage conflict resolution, re-define this method as
154
+ # a no-op.
155
+ #
156
+ # @return [Boolean]
157
+ def mark_conflicted(*filenames)
158
+ raise NotImplementedError.new("mark_conflicted() must be implemented by subclasses of AbstractLocalRepository.")
159
+ end
160
+
161
+ ##
162
+ # In whatever conflict-resolution system your repository format defines, mark a given file
163
+ # as no longer in conflict (resolved). If your format does not manage conflict resolution,
164
+ # re-define this method as a no-op.
165
+ #
166
+ # @return [Boolean]
167
+ def mark_resolved(*filenames)
168
+ raise NotImplementedError.new("mark_resolved() must be implemented by subclasses of AbstractLocalRepository.")
169
+ end
170
+
171
+ ##
172
+ # Attempts to resolve the given file, according to how mercurial manages
173
+ # merges. Needed for api compliance.
174
+ #
175
+ # @api
176
+ # @param [String] filename the file to attempt to resolve
177
+ def try_resolve_conflict(filename)
178
+ raise NotImplementedError.new("try_resolve_conflict() must be implemented by subclasses of AbstractLocalRepository.")
179
+ end
180
+
181
+ ##
182
+ # Returns all files that have not been merged. In other words, if we're
183
+ # waiting for the user to fix up their merge, then return the list of files
184
+ # we need to be correct before merging.
185
+ #
186
+ # @todo think up a better name
187
+ #
188
+ # @return [Array<Array<String, Symbol>>] an array of String-Symbol pairs - the
189
+ # filename is the first entry, the status of the merge is the second.
190
+ def uncommitted_merge_files
191
+ raise NotImplementedError.new("uncommitted_merge_files() must be implemented by subclasses of AbstractLocalRepository.")
192
+ end
193
+
194
+ ##
195
+ # Regarding branch support.
196
+ #
197
+ # For each repository format, you begin in a default branch. Each repo format, of
198
+ # course, starts with a different default branch. Mercurial's is "default", Git's is "master".
199
+ #
200
+ # @api
201
+ # @return [String] the default branch name
202
+ def default_branch_name
203
+ raise NotImplementedError.new("default_branch_name() must be implemented by subclasses of AbstractLocalRepository.")
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end