manifestly 2.0.0 → 2.1.0.beta01

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 722ffef1df06266d067ba5b96f2ee8a27acd0b88
4
- data.tar.gz: bca5c8ae71fe0bfd625aa8e6a3a9e8f9833f032d
3
+ metadata.gz: b3b76a0cb51544491ed359e34ba6d1840bbc1e4b
4
+ data.tar.gz: c68ee1b277d1781ee6134155b0e015cadbf15e98
5
5
  SHA512:
6
- metadata.gz: 15d56f3af994efd7879ff98b86b2754b076c7ade392be6379b63b2c2f22743e6f9bcef9bdbf40303e29000185c8e6bf8c01cec294af11ee7850e6571879fd07e
7
- data.tar.gz: 68557cf67c367588dac6c96bcbb290ef8ba01f92bdde112faf208757a0f2c5215885f5adc8637d66b5c97d10858972e0657b1321baa2c6c213a336f3cb034436
6
+ metadata.gz: 4d59f5a417cc490f73df414fc916e6ff34508f72743e7368e79589da2b0e71c5084b89e477859ccabf6541e717b3249041f4f1375da464e5a8a22cb7d0d96c46
7
+ data.tar.gz: a37bcc031e90f3cd6bb1c364c991c2679dcdd06f652adebd090a18af911f2fd2b02858daaaf492c8ca36603651478108f164edf252bd04d5212a81044e36c82b
data/.travis.yml CHANGED
@@ -4,6 +4,9 @@ rvm:
4
4
  - 2.2.3
5
5
  cache: bundler
6
6
  before_install: gem install bundler
7
+ before_script:
8
+ - git config --global user.email "cyrus@redblock.com"
9
+ - git config --global user.name "Cyrus Redblock"
7
10
  branches:
8
11
  only:
9
12
  - master
data/README.md CHANGED
@@ -25,6 +25,8 @@ Manifestly has built in help:
25
25
 
26
26
  $ manifestly help
27
27
 
28
+ _Note_: underscores and hyphens are interchangeable in option names, e.g. `--search_paths=blah` is the same as `--search-paths=blah`.
29
+
28
30
  ### create
29
31
 
30
32
  To create a new manifest, run
@@ -35,7 +37,7 @@ Both `create` and `apply` take a `--search-paths` option to specify where the re
35
37
 
36
38
  `create` by default is non-interactive (see `$>manifestly help create`) but there is an interactive option that will show you a blank manifest and give you options to add or remove repositories, or to choose the manifest commit for an existing repository. When repositories are added, their latest commit is listed. All commits seen during manifest creation are local commits only -- this tool does not look up remote commits.
37
39
 
38
- ### push
40
+ ### upload
39
41
 
40
42
  To push a manifest file you have created, call:
41
43
 
@@ -57,6 +59,24 @@ To apply a manifest file to your local repositories... instructions TBD, see bui
57
59
 
58
60
  To list available manifest files... instructions TBD, see built-in help
59
61
 
62
+ ### tag
63
+
64
+ You can add a tag to a manifest. The same tag can be added multiple times (under the covers, Manifestly adds some unique characters to the tag you provide).
65
+
66
+ See `$> manifestly help tag`.
67
+
68
+ ### find
69
+
70
+ You can retrieve manifest SHAs for tags you've added.
71
+
72
+ See `$> manifestly help find`.
73
+
74
+ ### diff
75
+
76
+ You can diff two manifests, resulting in markdown output that lists the PRs merged between manifests for each application repository listed in the "to" manifest.
77
+
78
+ See `$> manifestly help diff`.
79
+
60
80
  ## Development
61
81
 
62
82
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -98,17 +98,17 @@ module Manifestly
98
98
 
99
99
  --add: a space-separated list of repository paths to add, can be relative or
100
100
  absolute path names; if relative, manifestly tries to find them based on the
101
- --search_paths option. The special all option adds all available repos.
101
+ --search-paths option. The special all option adds all available repos.
102
102
 
103
103
  --remove: a space-separated list of repository paths to remove, only useful
104
- if you've also passed a --based_on manifest as a starting point.
104
+ if you've also passed a --based-on manifest as a starting point.
105
105
 
106
- --save_as: lets you provide a name for the created manifest, otherwise defaults
106
+ --save-as: lets you provide a name for the created manifest, otherwise defaults
107
107
  to a timestamp name with a random hex hash
108
108
 
109
109
  Examples:
110
110
 
111
- $ manifestly create --search_paths=.. --add=repo1 repo2 repo3
111
+ $ manifestly create --search-paths=.. --add=repo1 repo2 repo3
112
112
 
113
113
  The above is the same as:
114
114
 
@@ -118,7 +118,7 @@ module Manifestly
118
118
 
119
119
  $ manifestly create --add=all
120
120
 
121
- $ manifestly create --based_on=existing.manifest --remove=repo1 --save_as=new.manifest
121
+ $ manifestly create --based-on=existing.manifest --remove=repo1 --save-as=new.manifest
122
122
 
123
123
  INTERACTIVE CREATION
124
124
 
@@ -162,20 +162,20 @@ module Manifestly
162
162
 
163
163
  (r)eturn - entering 'r' returns to the previous menu
164
164
 
165
- Examples:
165
+ #{Rainbow("Examples:").bright}
166
166
 
167
167
  $ manifestly create -i\x5
168
168
  Create manifest from scratch with the default search path
169
169
 
170
- $ manifestly create -i --search_paths=..\x5
170
+ $ manifestly create -i --search-paths=..\x5
171
171
  Create manifest looking for repositories one dir up
172
172
 
173
- $ manifestly create -i --based_on=~my.manifest --search_paths=~jim/repos\x5
173
+ $ manifestly create -i --based-on=~my.manifest --search-paths=~jim/repos\x5
174
174
  Create manifest starting from an existing one
175
175
  DESC
176
176
  def create
177
177
  manifest = if options[:based_on]
178
- read_manifest(options[:based_on]) || return
178
+ load_manifest(file: options[:based_on]) || return
179
179
  else
180
180
  Manifest.new
181
181
  end
@@ -205,7 +205,7 @@ module Manifestly
205
205
  DESC
206
206
  def apply
207
207
  begin
208
- manifest = read_manifest(options[:file]) || return
208
+ manifest = load_manifest(file: options[:file]) || return
209
209
  rescue Manifestly::ManifestItem::MultipleSameNameRepositories => e
210
210
  say "Multiple repositories have the same name (#{e.message}) so we " +
211
211
  "can't apply the manifest. Try limiting the search_paths or " +
@@ -293,6 +293,126 @@ module Manifestly
293
293
  present_list_menu(commits, show_author: true)
294
294
  end
295
295
 
296
+ desc "tag", "Add a tag to a manifest"
297
+ long_desc <<-DESC
298
+ Add a tag (with optional message) to a manifest as identified by its SHA.
299
+
300
+ Tags are not currently ever removed from manifests, but the `find` command
301
+ has an option to only return info for the latest tag.
302
+
303
+ When you run this command, the tag is immediately pushed to the upstream
304
+ manifest repository.
305
+
306
+ #{Rainbow("Examples:").bright}
307
+
308
+ $> manifestly tag --repo=org/repo --sha=fe10b5fdb9 --tag=release-to-qa --message="howdy"
309
+ DESC
310
+ repo_option
311
+ method_option :sha,
312
+ desc: "The commit SHA of the manifest on the remote repository",
313
+ type: :string,
314
+ banner: '',
315
+ required: true
316
+ method_option :tag,
317
+ desc: "The value of the tag",
318
+ type: :string,
319
+ banner: '',
320
+ required: true
321
+ method_option :message,
322
+ desc: "An optional message on the tag",
323
+ type: :string,
324
+ banner: '',
325
+ required: false
326
+ def tag
327
+ repository = Repository.load_cached(options[:repo], update: true)
328
+ repository.tag_scoped_to_file(
329
+ tag: options[:tag], sha: options[:sha], message: options[:message], push: true
330
+ )
331
+ end
332
+
333
+ desc "find", "Finds tagged manifest SHAs"
334
+ long_desc <<-DESC
335
+ Returns a list of manifest SHAs that have the specified tag on the
336
+ specified repository file.
337
+
338
+ SHAs are sorted in order of descending tag timestamp. Note that these
339
+ timestamps are unavoidably linked to the time on the machine doing the
340
+ tagging, so it is possible to have unintended orderings if tagging machine
341
+ times are inaccurate or if tags are created at near simultaneous times
342
+ on multiple machines. Time zones of those machines do not matter.
343
+
344
+ You can limit the number of returned SHAs with the `--limit` flag.
345
+ Otherwise, all matching SHAs are returned.
346
+
347
+ #{Rainbow("Examples:").bright}
348
+
349
+ $> manifestly find --tag=release-to-qa --repo=org/some_repo --repo-file=foo\x5
350
+ fe10b5fdb9e2559a7b7f9268e9f3b9cff840f5cb\x5
351
+ 9fc60bee7cc80ce85ad2c066bf251be44f8ad8f1\x5
352
+
353
+ $> manifestly find --tag=release-to-qa --repo=org/some_repo --repo-file=foo --limit=1\x5
354
+ fe10b5fdb9e2559a7b7f9268e9f3b9cff840f5cb
355
+ DESC
356
+ repo_option
357
+ repo_file_option("The name of the manifest to look for tags on")
358
+ method_option :tag,
359
+ desc: "The value of the tag",
360
+ type: :string,
361
+ banner: '',
362
+ required: true
363
+ method_option :limit,
364
+ desc: "The number of results to return",
365
+ type: :string,
366
+ banner: '',
367
+ required: false
368
+ def find
369
+ repository = Repository.load_cached(options[:repo], update: true)
370
+ shas = repository.get_shas_with_tag(tag: options[:tag], file: options[:repo_file])
371
+ options[:limit] ? shas.take(options[:limit].to_i) : shas
372
+ end
373
+
374
+ desc "diff", "Show PR commits between two manifests across its repos"
375
+ long_desc <<-DESC
376
+ Runs a diff between two manifests (as identified by their commit SHAs) and
377
+ produces output (by default in markdown) that lists the PRs that were merged
378
+ between the manifests for each application repository listed in the "to"
379
+ manifest.
380
+
381
+ Up-to-date repositories are required wherever you are running manifestly,
382
+ and will need to be referenced with the normal --search-paths option (unless
383
+ they are in the default path).
384
+
385
+ #{Rainbow("Examples:").bright}
386
+
387
+ $> manifestly diff --repo=org/some_repo --from-sha=fe10b5fdb9e --to-sha=9fc60bee7c > changes.md
388
+ DESC
389
+ search_paths_option
390
+ repo_option
391
+ method_option :from_sha,
392
+ desc: "The commit SHA of the manifest on the remote repository to diff from",
393
+ type: :string,
394
+ banner: '',
395
+ required: true
396
+ method_option :to_sha,
397
+ desc: "The commit SHA of the manifest on the remote repository to diff from",
398
+ type: :string,
399
+ banner: '',
400
+ required: true
401
+ def diff
402
+ repository = Repository.load_cached(options[:repo], update: true)
403
+ from_manifest = load_manifest(repository: repository, sha: options[:from_sha])
404
+ to_manifest = load_manifest(repository: repository, sha: options[:to_sha])
405
+
406
+ if !from_manifest || !to_manifest
407
+ say("Could not load the 'from' manifest so cannot continue with the diff.") if !from_manifest
408
+ say("Could not load the 'to' manifest so cannot continue with the diff.") if !to_manifest
409
+ return
410
+ end
411
+
412
+ manifest_diff = ManifestDiff.new(from_manifest, to_manifest)
413
+ manifest_diff.to_markdown
414
+ end
415
+
296
416
  protected
297
417
 
298
418
  def present_create_menu(manifest)
@@ -429,12 +549,24 @@ module Manifestly
429
549
  end
430
550
  end
431
551
 
432
- def read_manifest(file)
552
+ def load_manifest(options={})
433
553
  begin
434
- Manifest.read(file, available_repositories)
435
- rescue Manifestly::ManifestItem::RepositoryNotFound
436
- say "Couldn't find all the repositories listed in #{file}. " +
437
- "Might need to specify --search_paths."
554
+ if options[:file]
555
+ Manifest.read_file(options[:file], available_repositories)
556
+ elsif options[:repository] && options[:sha]
557
+ content = options[:repository].get_commit_content(options[:sha])
558
+ Manifest.read_lines(content, available_repositories).tap do |manifest|
559
+ manifest.manifest_repository = options[:repository]
560
+ manifest.manifest_sha = options[:sha]
561
+ manifest.manifest_file = options[:repository].get_commit_filename(options[:sha])
562
+ end
563
+ else
564
+ say "Missing arguments when trying to load manifest"
565
+ nil
566
+ end
567
+ rescue Manifestly::ManifestItem::RepositoryNotFound => e
568
+ say "Couldn't find the #{e.message} repository listed in the manifest. " +
569
+ "Might need to specify --search-paths."
438
570
  nil
439
571
  end
440
572
  end
@@ -541,7 +673,7 @@ module Manifestly
541
673
  row do
542
674
  column "#{index}", align: 'right'
543
675
  column "#{commit.sha[0..9]}"
544
- column "#{summarize_commit_message(commit)}"
676
+ column "#{Commit.new(commit).summarized_message}"
545
677
  column "#{commit.author.name[0..13]}" if options[:show_author]
546
678
  column "#{commit.date}"
547
679
  end
@@ -549,13 +681,6 @@ module Manifestly
549
681
  end
550
682
  end
551
683
 
552
- def summarize_commit_message(commit)
553
- commit.message
554
- .gsub(/Merge pull request (#\w+)( from [\w-]+\/[\w-]+)/, 'PR \1')
555
- .gsub("\n",' ')
556
- .gsub(/\s+/, ' ')[0..79]
557
- end
558
-
559
684
  def repository_choices(except_in_manifest=nil)
560
685
  choices = available_repositories.collect{|repo| {display: repo.display_name, value: repo}}
561
686
  except_in_manifest.nil? ?
@@ -0,0 +1,25 @@
1
+ module Manifestly
2
+ class Commit
3
+
4
+ def initialize(commit)
5
+ @commit = commit
6
+ end
7
+
8
+ def is_pr?
9
+ @commit.message.starts_with?("Merge pull request")
10
+ end
11
+
12
+ def pr_number
13
+ match = @commit.message.match(/Merge pull request #(\d+)/)
14
+ match.nil? ? nil : match[1]
15
+ end
16
+
17
+ def summarized_message
18
+ @commit.message
19
+ .gsub(/Merge pull request (#\w+)( from [\w-]+\/[\w-]+)/, 'PR \1')
20
+ .gsub("\n",' ')
21
+ .gsub(/\s+/, ' ')[0..79]
22
+ end
23
+
24
+ end
25
+ end
@@ -49,6 +49,7 @@ module Manifestly
49
49
  def initialize(diff_string)
50
50
  file_strings = diff_string.split("diff --git ")
51
51
  file_strings.reject!(&:blank?)
52
+ file_strings.reject!{|str| str.starts_with?("commit ")} # from 'git show' output
52
53
  @files = file_strings.collect{|file_string| File.new(file_string)}
53
54
  end
54
55
 
@@ -29,17 +29,17 @@ module Manifestly
29
29
  @items[index]
30
30
  end
31
31
 
32
- def self.read(filename, repositories)
33
- manifest = Manifest.new
34
-
32
+ def self.read_file(filename, repositories)
35
33
  File.open(filename, 'r') do |file|
36
- file.each_line do |line|
37
- item = ManifestItem.from_file_string(line, repositories)
38
- manifest.add_item(item)
39
- end
34
+ read_lines(file, repositories)
40
35
  end
36
+ end
41
37
 
42
- manifest
38
+ def self.read_lines(lines, repositories)
39
+ lines.split("\n").each_with_object(Manifest.new) do |line, manifest|
40
+ item = ManifestItem.from_file_string(line, repositories)
41
+ manifest.add_item(item)
42
+ end
43
43
  end
44
44
 
45
45
  def write(filename)
@@ -61,5 +61,10 @@ module Manifestly
61
61
  items.empty?
62
62
  end
63
63
 
64
+ # Some meta info that some callers want to attach to the manifest
65
+ attr_accessor :manifest_repository
66
+ attr_accessor :manifest_sha
67
+ attr_accessor :manifest_file
68
+
64
69
  end
65
70
  end
@@ -0,0 +1,100 @@
1
+ module Manifestly
2
+ class ManifestDiff
3
+
4
+ class ItemDiff
5
+ def initialize(from_item, to_item)
6
+ @from_item = from_item
7
+ @to_item = to_item
8
+
9
+ @markdown = "## #{to_item.repository_name}#{item_source_info}\n\n#{commits_markdown}\n"
10
+ end
11
+
12
+ def to_markdown
13
+ @markdown
14
+ end
15
+
16
+ def from_sha
17
+ @from_item.commit.sha
18
+ end
19
+
20
+ def to_sha
21
+ @to_item.commit.sha
22
+ end
23
+
24
+ def item_source_info
25
+ new_item? ?
26
+ " (new manifest entry)" :
27
+ " (`#{from_sha[0..9]}` to `#{to_sha[0..9]}`)"
28
+ end
29
+
30
+ def new_item?
31
+ @from_item.nil?
32
+ end
33
+
34
+ def commits_markdown
35
+ if new_item?
36
+ "* This manifest item was not in the prior manifest, so all of its commits are new."
37
+ else
38
+ repository = @from_item.repository
39
+ repository.toggle_prs_only
40
+
41
+ is_rollback = false
42
+
43
+ commits = repository.commits(between: [from_sha, to_sha])
44
+
45
+ if commits.size == 0
46
+ # This might be a rollback, so try them backwards
47
+ commits = repository.commits(between: [to_sha, from_sha])
48
+ is_rollback = commits.size != 0
49
+ end
50
+
51
+ if commits.size == 0
52
+ "* There were no pull requests merged in this range of commits."
53
+ else
54
+ entries = commits.collect do |commit|
55
+ wrapper = Commit.new(commit)
56
+ entry = wrapper.summarized_message
57
+
58
+ entry = "[#{entry}](https://github.com/#{repository.display_name}/pull/#{wrapper.pr_number})" if wrapper.is_pr?
59
+
60
+ "1. #{entry}"
61
+ end.join("\n")
62
+
63
+ is_rollback ? "These commits were ***rolled back***:\n\n#{entries}" : entries
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def initialize(from_manifest, to_manifest)
70
+ @from_manifest = from_manifest
71
+ @to_manifest = to_manifest
72
+
73
+ @item_diffs = @to_manifest.items.collect do |to_item|
74
+ from_item = @from_manifest.items.detect do |from_item|
75
+ from_item.repository_name == to_item.repository_name
76
+ end
77
+
78
+ ItemDiff.new(from_item, to_item)
79
+ end
80
+ end
81
+
82
+ def to_markdown
83
+ "# Manifest Diff\n\n#{manifest_source_info}\n\n#{@item_diffs.collect(&:to_markdown).join("\n")}"
84
+ end
85
+
86
+ def manifest_source_info
87
+ repository = @from_manifest.manifest_repository
88
+ file = @from_manifest.manifest_file
89
+ from_sha = @from_manifest.manifest_sha
90
+ to_sha = @to_manifest.manifest_sha
91
+
92
+ if repository && file && from_sha && to_sha
93
+ "Comparing manifest ***#{file}*** on repository ***#{repository.display_name}*** from commit `#{from_sha[0..9]}` to `#{to_sha[0..9]}`."
94
+ else
95
+ "Manifest source info is *unknown*."
96
+ end
97
+ end
98
+
99
+ end
100
+ end
@@ -39,8 +39,7 @@ module Manifestly
39
39
  raise(InvalidManifestItem, string) if repo_name.blank? || sha.blank?
40
40
 
41
41
  matching_repositories = repositories.select do |repo|
42
- repo.github_name == repo_name ||
43
- repo.working_dir.to_s == repo_name
42
+ repo.display_name == repo_name
44
43
  end
45
44
 
46
45
  raise(MultipleSameNameRepositories, repo_name) if matching_repositories.size > 1
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'ostruct'
2
3
 
3
4
  module Manifestly
4
5
  class Repository
@@ -7,6 +8,8 @@ module Manifestly
7
8
  class ManifestUnchanged < StandardError; end
8
9
  class CommitContentError < StandardError; end
9
10
  class NoCommitsError < StandardError; end
11
+ # class TagNotFound < StandardError; end
12
+ class TagShaNotFound < StandardError; end
10
13
 
11
14
  # Returns an object if can load a git repository at the specified path,
12
15
  # otherwise nil
@@ -17,26 +20,32 @@ module Manifestly
17
20
 
18
21
  # Loads a gem-cached copy of the specified repository, cloning it if
19
22
  # necessary.
20
- def self.load_cached(github_name, options)
23
+ def self.load_cached(github_name_or_path, options)
21
24
  options[:update] ||= false
22
25
 
23
- raise(IllegalArgument, "Repository name is blank.") if github_name.blank?
26
+ raise(IllegalArgument, "Repository name is blank.") if github_name_or_path.blank?
24
27
 
25
- path = "./.manifestly/.manifest_repositories/#{github_name}"
26
- FileUtils.mkdir_p(path)
28
+ cached_path = "#{Manifestly.configuration.cached_repos_root_dir}/.manifestly/.manifest_repositories/#{github_name_or_path}"
29
+ FileUtils.mkdir_p(cached_path)
27
30
 
28
- repository = load(path)
31
+ repository = load(cached_path)
29
32
 
30
33
  if repository.nil?
31
- url = "git@github.com:#{github_name}.git"
32
- Git.clone(url, path)
33
- repository = new(path)
34
+ remote_location = is_github_name?(github_name_or_path) ?
35
+ "git@github.com:#{github_name_or_path}.git" :
36
+ github_name_or_path
37
+ Git.clone(remote_location, cached_path)
38
+ repository = new(cached_path)
34
39
  end
35
40
 
36
41
  repository.make_like_just_cloned! if options[:update]
37
42
  repository
38
43
  end
39
44
 
45
+ def self.is_github_name?(value)
46
+ value.match(/\A[^\/]+\/[^\/]+\z/)
47
+ end
48
+
40
49
  def is_git_repository?
41
50
  begin
42
51
  git
@@ -76,9 +85,10 @@ module Manifestly
76
85
  git.push
77
86
  end
78
87
 
79
- def commits
88
+ def commits(options={})
80
89
  begin
81
- log = git.log(1000000).object('origin/master') # don't limit
90
+ log = git.log(1000000).object('master') # don't limit
91
+ log = log.between(options[:between][0], options[:between][1]) if options[:between]
82
92
  log = log.grep("Merge pull request") if @prs_only
83
93
  log.tap(&:first) # tap to force otherwise lazy checks
84
94
  rescue Git::GitExecuteError => e
@@ -96,13 +106,21 @@ module Manifestly
96
106
  end
97
107
 
98
108
  def get_commit_content(sha)
99
- diff_string = find_commit("#{sha}^").diff(sha).to_s
109
+ get_commit_file(sha).to_content
110
+ end
111
+
112
+ def get_commit_filename(sha)
113
+ get_commit_file(sha).to_name
114
+ end
115
+
116
+ def get_commit_file(sha)
117
+ diff_string = git.show(sha)
100
118
  sha_diff = Diff.new(diff_string)
101
119
 
102
120
  raise(CommitContentError, "No content to retrieve for SHA #{sha}!") if sha_diff.num_files == 0
103
121
  raise(CommitContentError, "More than one file in the commit for SHA #{sha}!") if sha_diff.num_files > 1
104
122
 
105
- sha_diff[0].to_content
123
+ sha_diff[0]
106
124
  end
107
125
 
108
126
  def file_commits(file)
@@ -126,6 +144,36 @@ module Manifestly
126
144
  find_commit(sha)
127
145
  end
128
146
 
147
+ def tag_scoped_to_file(options={})
148
+ raise(IllegalArgument, "Tag names cannot contain forward slashes") if options[:tag].include?("/")
149
+
150
+ options[:push] ||= false
151
+ options[:message] ||= "no message"
152
+
153
+ filename = get_commit_filename(options[:sha])
154
+ tag = "#{Time.now.utc.strftime("%Y%m%d-%H%M%S.%6N")}/#{::SecureRandom.hex(2)}/#{filename}/#{options[:tag]}"
155
+ git.add_tag(tag, options[:sha], {annotate: true, message: options[:message], f: true})
156
+ git.push('origin', "refs/tags/#{tag}", f: true) if options[:push]
157
+ end
158
+
159
+ def get_shas_with_tag(options={})
160
+ options[:file] ||= ".*"
161
+ options[:order] ||= :descending
162
+
163
+ pattern = /.*\/#{options[:file]}\/#{options[:tag]}/
164
+
165
+ tag_objects = git.tags.select{|tag| tag.name.match(pattern)}
166
+ .sort_by(&:name)
167
+
168
+ tag_objects.reverse! if options[:order] == :descending
169
+
170
+ tag_objects.collect do |tag_object|
171
+ matched_sha = tag_object.contents.match(/[a-f0-9]{40}/)
172
+ raise(TagShaNotFound, "Could not retrieve SHA for tag '#{full_tag}'") if matched_sha.nil?
173
+ matched_sha.to_s
174
+ end
175
+ end
176
+
129
177
  def toggle_prs_only
130
178
  @prs_only = !@prs_only
131
179
  end
@@ -134,7 +182,7 @@ module Manifestly
134
182
  @origin ||= git.remotes.select{|remote| remote.name == 'origin'}.first
135
183
  end
136
184
 
137
- def github_name
185
+ def github_name_or_path
138
186
  # Extract 'org/reponame' out of remote url for both HTTP and SSH clones
139
187
  return nil if origin.nil?
140
188
  origin.url[/github.com.(.*?)(.git)?$/,1]
@@ -145,16 +193,16 @@ module Manifestly
145
193
  end
146
194
 
147
195
  def display_name
148
- if github_name
149
- repo_name = github_name.split('/').last
196
+ if github_name_or_path
197
+ repo_name = github_name_or_path.split('/').last
150
198
  dir_name = working_dir.to_s.split(File::SEPARATOR).last
151
199
  if repo_name == dir_name
152
- github_name
200
+ github_name_or_path
153
201
  else
154
- github_name + " (#{dir_name})"
202
+ github_name_or_path + " (#{dir_name})"
155
203
  end
156
204
  else
157
- working_dir.to_s
205
+ working_dir.to_s.split('/').last
158
206
  end
159
207
  end
160
208
 
@@ -1,3 +1,3 @@
1
1
  module Manifestly
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0.beta01"
3
3
  end
data/lib/manifestly.rb CHANGED
@@ -1,9 +1,31 @@
1
1
  require_relative "manifestly/version"
2
2
  require_relative 'manifestly/utilities'
3
+ require_relative 'manifestly/commit'
3
4
  require_relative 'manifestly/diff'
4
5
  require_relative 'manifestly/repository'
5
6
  require_relative 'manifestly/manifest'
7
+ require_relative 'manifestly/manifest_diff'
6
8
  require_relative 'manifestly/ui'
7
9
  require_relative 'manifestly/cli'
8
10
 
9
- module Manifestly; end
11
+ module Manifestly
12
+
13
+ class << self
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ class Configuration
19
+ attr_accessor :cached_repos_root_dir
20
+
21
+ def initialize
22
+ reset!
23
+ end
24
+
25
+ def reset!
26
+ @cached_repos_root_dir = '.'
27
+ end
28
+ end
29
+ end
30
+
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manifestly
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0.beta01
5
5
  platform: ruby
6
6
  authors:
7
7
  - JP Slavinsky
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-25 00:00:00.000000000 Z
11
+ date: 2016-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -158,8 +158,10 @@ files:
158
158
  - exe/manifestly
159
159
  - lib/manifestly.rb
160
160
  - lib/manifestly/cli.rb
161
+ - lib/manifestly/commit.rb
161
162
  - lib/manifestly/diff.rb
162
163
  - lib/manifestly/manifest.rb
164
+ - lib/manifestly/manifest_diff.rb
163
165
  - lib/manifestly/manifest_item.rb
164
166
  - lib/manifestly/repository.rb
165
167
  - lib/manifestly/ui.rb
@@ -181,9 +183,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
183
  version: '0'
182
184
  required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  requirements:
184
- - - ">="
186
+ - - ">"
185
187
  - !ruby/object:Gem::Version
186
- version: '0'
188
+ version: 1.3.1
187
189
  requirements: []
188
190
  rubyforge_project:
189
191
  rubygems_version: 2.4.8