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 +4 -4
- data/.travis.yml +3 -0
- data/README.md +21 -1
- data/lib/manifestly/cli.rb +148 -23
- data/lib/manifestly/commit.rb +25 -0
- data/lib/manifestly/diff.rb +1 -0
- data/lib/manifestly/manifest.rb +13 -8
- data/lib/manifestly/manifest_diff.rb +100 -0
- data/lib/manifestly/manifest_item.rb +1 -2
- data/lib/manifestly/repository.rb +66 -18
- data/lib/manifestly/version.rb +1 -1
- data/lib/manifestly.rb +23 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3b76a0cb51544491ed359e34ba6d1840bbc1e4b
|
4
|
+
data.tar.gz: c68ee1b277d1781ee6134155b0e015cadbf15e98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d59f5a417cc490f73df414fc916e6ff34508f72743e7368e79589da2b0e71c5084b89e477859ccabf6541e717b3249041f4f1375da464e5a8a22cb7d0d96c46
|
7
|
+
data.tar.gz: a37bcc031e90f3cd6bb1c364c991c2679dcdd06f652adebd090a18af911f2fd2b02858daaaf492c8ca36603651478108f164edf252bd04d5212a81044e36c82b
|
data/.travis.yml
CHANGED
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
|
-
###
|
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.
|
data/lib/manifestly/cli.rb
CHANGED
@@ -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
|
-
--
|
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 --
|
104
|
+
if you've also passed a --based-on manifest as a starting point.
|
105
105
|
|
106
|
-
--
|
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 --
|
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 --
|
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 --
|
170
|
+
$ manifestly create -i --search-paths=..\x5
|
171
171
|
Create manifest looking for repositories one dir up
|
172
172
|
|
173
|
-
$ manifestly create -i --
|
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
|
-
|
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 =
|
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
|
552
|
+
def load_manifest(options={})
|
433
553
|
begin
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
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 "#{
|
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
|
data/lib/manifestly/diff.rb
CHANGED
@@ -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
|
|
data/lib/manifestly/manifest.rb
CHANGED
@@ -29,17 +29,17 @@ module Manifestly
|
|
29
29
|
@items[index]
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.
|
33
|
-
manifest = Manifest.new
|
34
|
-
|
32
|
+
def self.read_file(filename, repositories)
|
35
33
|
File.open(filename, 'r') do |file|
|
36
|
-
file
|
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
|
-
|
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.
|
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(
|
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
|
26
|
+
raise(IllegalArgument, "Repository name is blank.") if github_name_or_path.blank?
|
24
27
|
|
25
|
-
|
26
|
-
FileUtils.mkdir_p(
|
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(
|
31
|
+
repository = load(cached_path)
|
29
32
|
|
30
33
|
if repository.nil?
|
31
|
-
|
32
|
-
|
33
|
-
|
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('
|
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
|
-
|
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]
|
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
|
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
|
149
|
-
repo_name =
|
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
|
-
|
200
|
+
github_name_or_path
|
153
201
|
else
|
154
|
-
|
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
|
|
data/lib/manifestly/version.rb
CHANGED
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
|
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.
|
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-
|
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:
|
188
|
+
version: 1.3.1
|
187
189
|
requirements: []
|
188
190
|
rubyforge_project:
|
189
191
|
rubygems_version: 2.4.8
|