git_multicast 0.1.0 → 0.2.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +17 -1
  3. data/README.md +1 -1
  4. data/git_multicast.gemspec +1 -0
  5. data/lib/git_multicast.rb +3 -8
  6. data/lib/git_multicast/adapter.rb +2 -0
  7. data/lib/git_multicast/{adapters → adapter}/bitbucket.rb +1 -1
  8. data/lib/git_multicast/{adapters → adapter}/github.rb +1 -1
  9. data/lib/git_multicast/cli.rb +38 -6
  10. data/lib/git_multicast/formatter.rb +6 -0
  11. data/lib/git_multicast/formatter/full.rb +18 -0
  12. data/lib/git_multicast/formatter/quiet.rb +13 -0
  13. data/lib/git_multicast/formatter/standard.rb +29 -0
  14. data/lib/git_multicast/formatter/status.rb +17 -0
  15. data/lib/git_multicast/multicaster.rb +31 -0
  16. data/lib/git_multicast/multicaster/clone.rb +35 -0
  17. data/lib/git_multicast/multicaster/pull.rb +30 -0
  18. data/lib/git_multicast/multicaster/status.rb +30 -0
  19. data/lib/git_multicast/repository_fetcher.rb +5 -2
  20. data/lib/git_multicast/task.rb +5 -3
  21. data/lib/git_multicast/task/result.rb +13 -0
  22. data/lib/git_multicast/task/runner.rb +38 -0
  23. data/lib/git_multicast/version.rb +1 -1
  24. data/spec/git_multicast/{adapters → adapter}/bitbucket_spec.rb +7 -3
  25. data/spec/git_multicast/cli_spec.rb +3 -3
  26. data/spec/git_multicast/formatter/full_spec.rb +32 -0
  27. data/spec/git_multicast/formatter/quiet_spec.rb +30 -0
  28. data/spec/git_multicast/formatter/standard_spec.rb +31 -0
  29. data/spec/git_multicast/formatter/status_spec.rb +32 -0
  30. data/spec/git_multicast/multicaster/clone_spec.rb +97 -0
  31. data/spec/git_multicast/multicaster/pull_spec.rb +41 -0
  32. data/spec/git_multicast/multicaster/status_spec.rb +41 -0
  33. data/spec/git_multicast/repository_fetcher_spec.rb +3 -3
  34. data/spec/git_multicast/task/runner_spec.rb +44 -0
  35. data/spec/git_multicast/task_spec.rb +8 -5
  36. metadata +39 -18
  37. data/lib/git_multicast/.rubocop.yml +0 -11
  38. data/lib/git_multicast/adapters.rb +0 -7
  39. data/lib/git_multicast/cloner.rb +0 -36
  40. data/lib/git_multicast/output_formatter.rb +0 -30
  41. data/lib/git_multicast/puller.rb +0 -28
  42. data/lib/git_multicast/statuser.rb +0 -28
  43. data/lib/git_multicast/task_result.rb +0 -7
  44. data/lib/git_multicast/task_runner.rb +0 -40
  45. data/spec/git_multicast/cloner_spec.rb +0 -94
  46. data/spec/git_multicast/output_formatter_spec.rb +0 -30
  47. data/spec/git_multicast/puller_spec.rb +0 -39
  48. data/spec/git_multicast/statuser_spec.rb +0 -39
  49. data/spec/git_multicast/task_runner_spec.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 139ef7bd2f4385eee6c08134ddb538f6bdb7ed2a
4
- data.tar.gz: 73141c42606731439f6b6605634555ad2af72826
3
+ metadata.gz: e05ac031d27eae835462ae840eaf7e0bcdb188bd
4
+ data.tar.gz: 12cd3e8e2e5ca64546bccc77bacdf0513bbd73b2
5
5
  SHA512:
6
- metadata.gz: 0a69b5d1b40d79b14b641c49ddb4e13f2bdeebafb0c8a91a0d97581db197fc680428642802d1ac7aa0daff516eb85b0e11b0a97f12ad02311aa0bdfdd9297d8b
7
- data.tar.gz: 01949df4a72972df66da92fb6133ef0b66dddf1824e1d024a939170c97b6340efea0146814e94b53f4a973345dab5972e6a391e8a578bf6bc0883ea6aff0af8d
6
+ metadata.gz: 7dfbeb2fc26d6986b771b9a9ecf604653f8c17882499e01b67bd5e6470e550cac6b28c1ba3f556275040ac91073db6a848c379f30ff70a74f2b60f2311de2127
7
+ data.tar.gz: 2e53d5c76dfa85e8e656a67668a2d1b516a9f020436deb2e6bea54dcffe30f7cc890f0213ca8b57da4dc4ed19d9074d6734180238b9be6ddd6db67c157e21a4d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_multicast (0.1.0)
4
+ git_multicast (0.2.0)
5
5
  colorize (~> 0.7)
6
6
  recursive-open-struct (~> 0.5.0)
7
7
  thor (~> 0.19)
@@ -10,12 +10,19 @@ GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
12
  addressable (2.3.6)
13
+ ast (2.0.0)
14
+ astrolabe (1.3.0)
15
+ parser (>= 2.2.0.pre.3, < 3.0)
13
16
  coderay (1.1.0)
14
17
  colorize (0.7.3)
15
18
  crack (0.4.2)
16
19
  safe_yaml (~> 1.0.0)
17
20
  diff-lcs (1.2.5)
18
21
  method_source (0.8.2)
22
+ parser (2.2.0.pre.8)
23
+ ast (>= 1.1, < 3.0)
24
+ slop (~> 3.4, >= 3.4.5)
25
+ powerpack (0.0.9)
19
26
  pry (0.10.1)
20
27
  coderay (~> 1.1.0)
21
28
  method_source (~> 0.8.1)
@@ -23,6 +30,7 @@ GEM
23
30
  pry-doc (0.6.0)
24
31
  pry (~> 0.9)
25
32
  yard (~> 0.8)
33
+ rainbow (2.0.0)
26
34
  rake (10.4.2)
27
35
  recursive-open-struct (0.5.0)
28
36
  rspec (3.1.0)
@@ -37,6 +45,13 @@ GEM
37
45
  rspec-mocks (3.1.3)
38
46
  rspec-support (~> 3.1.0)
39
47
  rspec-support (3.1.2)
48
+ rubocop (0.27.1)
49
+ astrolabe (~> 1.3)
50
+ parser (>= 2.2.0.pre.7, < 3.0)
51
+ powerpack (~> 0.0.6)
52
+ rainbow (>= 1.99.1, < 3.0)
53
+ ruby-progressbar (~> 1.4)
54
+ ruby-progressbar (1.7.0)
40
55
  safe_yaml (1.0.4)
41
56
  slop (3.6.0)
42
57
  thor (0.19.1)
@@ -57,5 +72,6 @@ DEPENDENCIES
57
72
  pry-doc
58
73
  rake (~> 10.0)
59
74
  rspec (~> 3.0)
75
+ rubocop
60
76
  vcr
61
77
  webmock
data/README.md CHANGED
@@ -13,7 +13,7 @@ multiple git repositories, much like a multicast sends data to multiple
13
13
  recipients.
14
14
 
15
15
  `git_multicast` executes actions in parallel, so cloning 30 repositories will take
16
- just as long as cloning the biggest one, and nothing more.
16
+ just as long as cloning the larger one, and nothing more.
17
17
 
18
18
  Actions currently supported:
19
19
 
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'rspec', '~> 3.0'
27
27
  spec.add_development_dependency 'rake', '~> 10.0'
28
28
  spec.add_development_dependency 'vcr'
29
+ spec.add_development_dependency 'rubocop'
29
30
  spec.add_development_dependency 'webmock'
30
31
 
31
32
  # these gems are required by emacs' robe-package
data/lib/git_multicast.rb CHANGED
@@ -1,14 +1,9 @@
1
1
  require_relative 'git_multicast/version'
2
- require_relative 'git_multicast/cloner'
3
- require_relative 'git_multicast/puller'
4
- require_relative 'git_multicast/output_formatter'
5
- require_relative 'git_multicast/statuser'
6
2
 
7
- require_relative 'git_multicast/task_runner'
8
- require_relative 'git_multicast/task_result'
3
+ require_relative 'git_multicast/multicaster'
4
+ require_relative 'git_multicast/formatter'
9
5
  require_relative 'git_multicast/task'
10
-
11
- require_relative 'git_multicast/adapters'
6
+ require_relative 'git_multicast/adapter'
12
7
  require_relative 'git_multicast/repository_fetcher'
13
8
 
14
9
  module GitMulticast
@@ -0,0 +1,2 @@
1
+ require_relative 'adapter/bitbucket'
2
+ require_relative 'adapter/github'
@@ -1,5 +1,5 @@
1
1
  module GitMulticast
2
- module Adapters
2
+ module Adapter
3
3
  class Bitbucket
4
4
  def initialize(repo)
5
5
  @repo = repo
@@ -1,5 +1,5 @@
1
1
  module GitMulticast
2
- module Adapters
2
+ module Adapter
3
3
  class Github
4
4
  def initialize(repo)
5
5
  @repo = repo
@@ -4,26 +4,58 @@ require 'git_multicast'
4
4
 
5
5
  module GitMulticast
6
6
  class Cli < Thor
7
+ class_option :version, :type => :boolean
8
+
7
9
  desc 'git_multicast pull', 'Git pulls all repositories contained in\
8
10
  current directory.'
11
+ option :quiet, type: :boolean
12
+ option :verbose, type: :boolean
9
13
  def pull
10
- puts Puller.new(Dir.pwd).pull!
14
+ if formatter
15
+ puts multicaster(:pull).new(Dir.pwd, formatter).execute!
16
+ else
17
+ puts multicaster(:pull).new(Dir.pwd).execute!
18
+ end
11
19
  end
12
20
 
13
- desc 'git_multicast clone :username', 'Git pulls all repositories\
14
- contained in current directory.'
21
+ desc 'git_multicast clone :username', 'Git clone all repositories\
22
+ for given username.'
23
+ option :quiet, type: :boolean
24
+ option :verbose, type: :boolean
15
25
  def clone(username)
16
- puts Cloner.new(username, Dir.pwd).clone!
26
+ if formatter
27
+ puts multicaster(:clone).new(username, Dir.pwd, formatter).execute!
28
+ else
29
+ puts multicaster(:clone).new(username, Dir.pwd).execute!
30
+ end
17
31
  end
18
32
 
19
33
  desc 'git_multicast status', 'Shows status for each repository'
20
34
  def status
21
- puts Statuser.new(Dir.pwd).statuses!
35
+ puts multicaster(:status).new(Dir.pwd).execute!
22
36
  end
23
37
 
24
- desc 'git_multicast version', 'Shows currently installed version'
38
+ desc "version", "Show thor_app version"
25
39
  def version
26
40
  puts GitMulticast::VERSION
27
41
  end
42
+ default_task :version
43
+
44
+ no_tasks do
45
+ def find_version
46
+ version
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def formatter
53
+ return Formatter::Full.new(Time.now) if options[:verbose]
54
+ return Formatter::Quiet.new(Time.now) if options[:quiet]
55
+ end
56
+
57
+ def multicaster(method)
58
+ GitMulticast.const_get("Multicaster::#{method.capitalize}")
59
+ end
28
60
  end
29
61
  end
@@ -0,0 +1,6 @@
1
+ require 'colorize'
2
+
3
+ require_relative 'formatter/standard'
4
+ require_relative 'formatter/quiet'
5
+ require_relative 'formatter/full'
6
+ require_relative 'formatter/status'
@@ -0,0 +1,18 @@
1
+ module GitMulticast
2
+ class Formatter
3
+ class Full < Standard
4
+ def format(task_result)
5
+ case task_result.exit_status
6
+ when 0
7
+ <<EOF
8
+ #{'[Success]'.green} #{task_result.name}
9
+ #{task_result.result}
10
+ #{time_report}\n
11
+ EOF
12
+ else
13
+ super(task_result)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ require 'colorize'
2
+
3
+ module GitMulticast
4
+ class Formatter
5
+ class Quiet < Standard
6
+ def format(task_result)
7
+ return '' if task_result.success?
8
+
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ module GitMulticast
2
+ class Formatter
3
+ class Standard
4
+ def initialize(start_time = nil)
5
+ @start_time = start_time
6
+ end
7
+
8
+ def format(task_result)
9
+ case task_result.exit_status
10
+ when 0
11
+ '[Success]'.green + " #{task_result.name}#{time_report}\n"
12
+ else
13
+ <<EOF
14
+ #{'[Error]'.red} #{task_result.name}
15
+ #{task_result.result}
16
+ EOF
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ attr_reader :start_time
23
+
24
+ def time_report
25
+ " | executed in #{Time.now - start_time} seconds" unless start_time.nil?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ module GitMulticast
2
+ class Formatter
3
+ class Status < Standard
4
+ def format(task_result)
5
+ case task_result.result
6
+ when /\"git add /
7
+ <<EOF
8
+ #{'[Changes]'.red} #{task_result.name.red}
9
+ #{task_result.result}
10
+ EOF
11
+ else
12
+ '[No Changes]'.green + " #{task_result.name}\n"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'multicaster/clone'
2
+ require_relative 'multicaster/pull'
3
+ require_relative 'multicaster/status'
4
+
5
+ module GitMulticast
6
+ class Multicaster
7
+ def initialize(formatter)
8
+ @formatter = formatter
9
+ end
10
+
11
+ def execute!
12
+ Task::Runner
13
+ .new(tasks)
14
+ .run!
15
+ .map(&method(:format))
16
+ .reduce('', &:+)
17
+ end
18
+
19
+ def tasks
20
+ fail NotImplementedError
21
+ end
22
+
23
+ def format(task_result)
24
+ formatter.format(task_result)
25
+ end
26
+
27
+ protected
28
+
29
+ attr_reader :formatter
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module GitMulticast
2
+ class Multicaster
3
+ class Clone < Multicaster
4
+ def initialize(username, dir,
5
+ formatter = Formatter::Standard.new(Time.now)
6
+ )
7
+ @username = username
8
+ @dir = dir
9
+
10
+ super(formatter)
11
+ end
12
+
13
+ protected
14
+
15
+ attr_reader :username, :dir
16
+
17
+ def tasks
18
+ RepositoryFetcher
19
+ .get_all_repos_from_user(username)
20
+ .map { |repo| Task.new(repo.name, command(repo)) }
21
+ end
22
+
23
+ def command(repo)
24
+ if repo.fork
25
+ parent_repo = RepositoryFetcher.get_repo_parent(repo.url)
26
+ "git clone #{repo.ssh_url} #{File.join(dir, repo.name)} && \
27
+ git -C \"#{File.join(dir, repo.name)}\" remote add upstream \
28
+ #{parent_repo.ssh_url} --fetch"
29
+ else
30
+ "git clone #{repo.ssh_url} #{File.join(dir, repo.name)}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ module GitMulticast
2
+ class Multicaster
3
+ class Pull < Multicaster
4
+ def initialize(dir, formatter = Formatter::Standard.new(Time.now))
5
+ @dir = dir
6
+
7
+ super(formatter)
8
+ end
9
+
10
+ protected
11
+
12
+ attr_reader :dir
13
+
14
+ def tasks
15
+ Dir.entries(dir)
16
+ .select { |f| File.directory? f }
17
+ .reject { |f| f =~ /^\./ } # ., .. and .git and the like
18
+ .map { |dir| Task.new(description(dir), command(dir)) }
19
+ end
20
+
21
+ def command(dir)
22
+ "git -C #{dir} pull -r origin"
23
+ end
24
+
25
+ def description(dir)
26
+ File.basename(dir)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module GitMulticast
2
+ class Multicaster
3
+ class Status < Multicaster
4
+ def initialize(dir, formatter = Formatter::Status.new(Time.now))
5
+ @dir = dir
6
+
7
+ super(formatter)
8
+ end
9
+
10
+ protected
11
+
12
+ attr_reader :dir
13
+
14
+ def tasks
15
+ Dir.entries(dir)
16
+ .select { |f| File.directory? f }
17
+ .reject { |f| f =~ /^\./ } # ., .. and .git and the like
18
+ .map { |dir| Task.new(description(dir), command(dir)) }
19
+ end
20
+
21
+ def command(dir)
22
+ "cd #{dir} && git status"
23
+ end
24
+
25
+ def description(dir)
26
+ File.basename(dir)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,11 +1,14 @@
1
1
  require_relative 'repository_fetcher/github'
2
2
  require_relative 'repository_fetcher/bitbucket'
3
3
 
4
+ require 'net/http'
5
+ require 'json'
6
+
4
7
  module GitMulticast
5
8
  class RepositoryFetcher
6
9
  FETCHER_ADAPTER_ZIP = [
7
- [Bitbucket, Adapters::Bitbucket],
8
- [Github, Adapters::Github]
10
+ [Bitbucket, Adapter::Bitbucket],
11
+ [Github, Adapter::Github]
9
12
  ]
10
13
 
11
14
  FETCHERS, ADAPTERS = FETCHER_ADAPTER_ZIP.transpose
@@ -1,3 +1,6 @@
1
+ require_relative 'task/result'
2
+ require_relative 'task/runner'
3
+
1
4
  module GitMulticast
2
5
  class Task
3
6
  include Process
@@ -8,13 +11,12 @@ module GitMulticast
8
11
 
9
12
  def run!
10
13
  r, w = IO.pipe
11
- w.write("Running: #{description}\n")
12
14
  pid = spawn(command, out: w, err: w)
13
15
 
14
- _, exit_status = wait(pid)
16
+ _, status = wait2(pid)
15
17
  w.close unless w.closed?
16
18
 
17
- TaskResult.new(description, r.read, exit_status)
19
+ Result.new(description, r.read, status.exitstatus)
18
20
  ensure
19
21
  w.close unless w.closed?
20
22
  end