git_multicast 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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