onboard 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDFmNjkwZDVlMGFmMmI1NjYzY2I5OGZmMTgwNzRiYjkwMjBlNGI3YQ==
4
+ OTgwMzQzNzYzZTdkM2I4Zjg5OWNlYjIyY2VmMmVkZTQ1ODhhYmJkMA==
5
5
  data.tar.gz: !binary |-
6
- NWMyMTdkYTYwNTdmOWM0NDkyZTc3ZGQyMTEwMjJiYzM3MTcyNDE2Ng==
6
+ MDcyODg3MzM0NjAzMDNiY2Q0YTYzYTY3ZmZlNzM4NjkwZDBlMDg2ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NWRkOTUyMzMxOTJjMGY2MDJmZDQxZDEyMDkxYjJkM2RhNmE0N2ZmM2I3YjE4
10
- YTBlMGM1ODg5ZGRlM2UxZThkODkxNWM0ZWI2MjAxZTUxNzY0MTRjYWJiMjFi
11
- NjYyZmNhYmI4OTQ2NzM3MWRjNzA1NTg4YTFiYWI1MmRiNzhmNjQ=
9
+ NzY4YjJiYjQxZTVkMTA0ZDY0YWNlOTQyMDFmOTFhOWQwMmIxYTYwYWVhODY2
10
+ ZWY5ZTY5Yjg4YmJhOGZhMDVmOWI0ZDQwMTkyYzQ0YmRjMTdiNzVhNjcxYWU2
11
+ ZWJhODJiYmVlN2ViYzUxYTVhZDY3MGNhZjA3Y2JkY2Y1ZTJmZWQ=
12
12
  data.tar.gz: !binary |-
13
- MzQ3NzYwOWNiODMxNzJhNWViZDljODcyOTQyNzk3NWIzOWIzYWIwMzc3ODYw
14
- NjNhZTkxNmFkNTgxMTU3MjQ1OGU3YTcyYmIwNTg2OTc4YjBhYTA2NDg4YWQ2
15
- ZGJhMjcxODhhM2QyY2MyZTc0YjdjMmE3YjExYTYyZTcwZGEzOGM=
13
+ Y2M3NmI2Zjg1MzA2MGM2YThlOGZhZDNkMjlhNmRkZmU0OTMwYjIzZGRhZmJh
14
+ ZjBkMWQ5NThkNTJiMDY5MmJlYmM2MDBmNDhhN2M2MmQ0MjE3NWUyZjM2MDQ0
15
+ ZDkwOTc1OGRlNzg3ODA2ZDNkNjNhMDM4OGFmNDFiY2FjOGU2YWU=
data/bin/onboard CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
3
6
  require 'onboard'
4
7
 
5
8
  Onboard::CLI.start(ARGV)
data/lib/onboard/cli.rb CHANGED
@@ -10,7 +10,6 @@ require_relative 'repo'
10
10
 
11
11
  module Onboard
12
12
  class CLI < Thor
13
- # TODO: switch from DOCROOT to CODEBASE to enable more comprehensive searching
14
13
  desc "projects CODEBASE", "add projects to CODEBASE"
15
14
  long_desc <<-LONGDESC
16
15
  `onboard projects` performs multiple tasks when installing contrib
@@ -23,8 +22,6 @@ module Onboard
23
22
  * Adds and commits each project
24
23
 
25
24
  LONGDESC
26
- # TODO: Analyze codebase for project version
27
- # ala - find ./CODEBASE -type f -name '*.info' | xargs -I {} grep -rn '^version = \"' {}
28
25
  option :branch, :aliases => "-b", :desc => "Specify repository branch to update"
29
26
  option :core, :required => true, :aliases => "-c", :type => :numeric, :desc => "Specify Drupal core version"
30
27
  option :path, :required => true, :aliases => "-p", :desc => "Specify project path relative to CODEBASE"
@@ -38,27 +35,32 @@ module Onboard
38
35
  option :yes, :aliases => "-y", :desc => "Assume 'yes' for all prompts"
39
36
  def projects(codebase)
40
37
  core = "#{options[:core]}.x"
41
- projects = []
38
+ projects = {}
42
39
  if options[:modules].nil? == false
43
- options[:modules].each { |x| projects.push x }
40
+ options[:modules].each { |x| projects[x] = '' }
44
41
  elsif options[:themes].nil? == false
45
- options[:themes].each { |x| projects.push x }
42
+ options[:themes].each { |x| projects[x] = '' }
46
43
  end
47
44
  path = "#{options[:path]}"
48
45
  found = Finder.new(projects, codebase).locate
49
- if found.any?
46
+ if found.empty? == false
50
47
  say("Projects exist at the following locations:", :yellow)
51
- found.each { |x| puts " " + x }
48
+ found.each do |x, y|
49
+ puts " " + x
50
+ projects[File.basename(x)] = y
51
+ end
52
52
  puts ""
53
53
  end
54
54
  if options[:force] != 'force'
55
- found.each do |x|
56
- projects.delete(File.basename(x))
55
+ if found.empty? == false
56
+ found.each do |x, y|
57
+ projects.delete(File.basename(x))
58
+ end
57
59
  end
58
60
  end
59
61
  if projects.empty? == false
60
62
  say("Ready to add the following projects:", :green)
61
- projects.each do |x|
63
+ projects.each do |x, y|
62
64
  puts " " + "#{codebase}/#{path}/#{x}"
63
65
  end
64
66
  puts ""
@@ -68,53 +70,22 @@ module Onboard
68
70
  say("Script was exited.")
69
71
  exit
70
72
  end
71
- projects.each do |x|
72
- prm = {}
73
- prm['path'] = "#{codebase}/#{path}/#{x}"
74
- Project.new(prm).rm
75
- # TODO: replace 'open().read' with custom caching solution
76
- pdl = {}
77
- pdl['project'] = x
78
- pdl['core'] = core
79
- dl = Project.new(pdl).dl
80
- feed_md5, archive = dl
81
- # TODO: replace 'open().read' with custom caching solution
82
- open(archive).read
83
- uri = URI.parse(archive)
84
- targz = "/tmp/open-uri-503" + [ @path, uri.host, Digest::SHA1.hexdigest(archive) ].join('/')
85
- md5 = Digest::MD5.file(targz).hexdigest
86
- # TODO: retry download after failed download verification
87
- if md5 == feed_md5
88
- pex = {}
89
- pex['dest'] = "#{codebase}/#{path}"
90
- pex['path'] = targz
91
- Project.new(pex).extract
92
- else
93
- say("Verification failed for #{x} archive!", :red)
94
- exit
95
- end
96
- end
73
+ prj = {}
74
+ prj['codebase'] = codebase
75
+ prj['path'] = "#{codebase}/#{path}"
76
+ prj['projects'] = projects
77
+ prj['core'] = core
78
+ Project.new(prj).dl
97
79
  if options[:vc] == true
98
- require_relative 'msg'
99
80
  branch = options[:branch].nil? ? '' : options[:branch]
100
81
  repo = {}
101
82
  repo['branch'] = branch
102
83
  repo['codebase'] = codebase
103
- repo_info = Repo.new(repo).info
104
- projects.each do |x|
105
- acmsg = "Committing #{x} on #{repo_info['current_branch']} branch..."
106
- say(Msg.new(acmsg).format)
107
- repo['path'] = "#{path}/#{x}"
108
- Repo.new(repo).update
109
- say(" [done]", :green)
110
- # TODO: error handling and conditional messaging for failures
111
- end
112
- pmsg = "Pushing all changes to #{repo_info['remotes']}..."
113
- say(Msg.new(pmsg).format)
114
- Repo.new(repo).push
115
- say(" [done]", :green)
84
+ repo['projects'] = projects
85
+ repo['path'] = path
86
+ Repo.new(repo).update
116
87
  else
117
- projects.each do |x|
88
+ projects.each do |x, y|
118
89
  say("#{x} added to codebase but changes are not yet tracked in version control.", :yellow)
119
90
  end
120
91
  end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'net/http'
4
+
5
+ module Onboard
6
+ class Download
7
+ def initialize(cache_dir='/tmp')
8
+ @cache_dir = cache_dir
9
+ end
10
+
11
+ def path(url)
12
+ File.join("", @cache_dir, Digest::MD5.hexdigest(url))
13
+ end
14
+
15
+ def fetch(url, max_age=1800)
16
+ file_path = self.path(url)
17
+ if File.exists? file_path
18
+ return File.new(file_path).read if Time.now-File.mtime(file_path)<max_age
19
+ end
20
+ File.open(file_path, "w") do |data|
21
+ data << Net::HTTP.get_response(URI.parse(url)).body
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/onboard/find.rb CHANGED
@@ -12,20 +12,38 @@ module Onboard
12
12
  end
13
13
 
14
14
  def locate
15
- found = []
15
+ found = {}
16
16
  Find.find(haystack) do |e|
17
17
  if File.directory?(e)
18
- if needle.include?(File.basename(e))
19
- Find.find(e) do |f|
20
- if File.extname(f) == '.info'
21
- found.push e
18
+ if needle.has_key?(File.basename(e))
19
+ Dir.entries(e).select do |f|
20
+ file = "#{e}/#{f}"
21
+ if File.file?(file)
22
+ if self.info_ext?(file)
23
+ if self.version(file).empty? == false
24
+ found[e] = self.version(file)
25
+ end
26
+ end
22
27
  end
23
28
  end
24
29
  end
25
30
  end
26
31
  end
32
+ return found
33
+ end
34
+
35
+ def info_ext?(file)
36
+ File.extname(file) == '.info'
37
+ end
27
38
 
28
- return found.uniq
39
+ def version(file)
40
+ File.open(file) do |g|
41
+ g.each_line do |line|
42
+ if line =~ /version/
43
+ return line.scan(/.*?"(.*?)".*$/)[0].nil? ? '' : line.scan(/.*?"(.*?)".*$/)[0]
44
+ end
45
+ end
46
+ end
29
47
  end
30
48
  end
31
49
  end
data/lib/onboard/msg.rb CHANGED
@@ -14,9 +14,9 @@ module Onboard
14
14
  end
15
15
 
16
16
  def format
17
- width = Screen.new().width
17
+ height, width = Screen.new().size
18
18
  spaces = " " * (width - msg.length - 8)
19
- return msg + spaces
19
+ say(msg + spaces)
20
20
  end
21
21
  end
22
22
  end
@@ -1,65 +1,125 @@
1
1
  # encoding: utf-8
2
+
2
3
  require 'fileutils'
3
4
  require 'find'
4
5
  require 'nokogiri'
5
6
  require 'rubygems/package'
7
+ require 'thor'
6
8
  require 'zlib'
7
9
 
10
+ require_relative 'confirm'
11
+ require_relative 'download'
12
+ require_relative 'repo'
13
+
8
14
  module Onboard
9
15
 
10
16
  TAR_LONGLINK = '././@LongLink'
17
+ DRUPAL_PRJ_FEED = "http://updates.drupal.org/release-history/"
18
+ DRUPAL_DL_LINK = "http://ftp.drupal.org/files/projects/"
11
19
 
12
- class Project
13
- attr_reader :feed, :path, :dest
20
+ class Project < Thor
21
+ attr_reader :core, :path, :projects, :codebase
14
22
 
15
- def initialize(args = {})
16
- @feed = "http://updates.drupal.org/release-history/#{args['project']}/#{args['core']}"
17
- @path = args['path']
18
- @dest = args['dest']
19
- end
23
+ no_tasks do
24
+ def initialize(args = {})
25
+ @core = args['core']
26
+ @path = args['path']
27
+ @projects = args['projects']
28
+ @codebase = args['codebase']
29
+ end
30
+
31
+ def feed(project)
32
+ "#{DRUPAL_PRJ_FEED}#{project}/#{core}"
33
+ end
20
34
 
21
- def dl
22
- doc = Nokogiri::XML(open(@feed).read)
23
- releases = {}
24
- doc.xpath('//releases//release').each do |item|
25
- if !item.at_xpath('version_extra')
26
- releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
35
+ def hacked?(project, existing)
36
+ self.clean("#{path}/#{project}")
37
+ link = DRUPAL_DL_LINK + project + "-" + existing + ".tar.gz"
38
+ Download.new.fetch(link)
39
+ self.extract(Download.new.path(link)) if self.verify(project, link, existing)
40
+ st = {}
41
+ st['codebase'] = codebase
42
+ changes = Repo.new(st).st
43
+ if changes.empty? == false
44
+ Confirm.new("Proceed?").yes?
27
45
  end
28
46
  end
29
- if releases.nil?
30
- doc.xpath('//releases//release').each do |item|
31
- releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
47
+
48
+ def dl
49
+ projects.each do |x, y|
50
+ self.hacked?(x, y[0]) if y.empty? == false
51
+ self.clean("#{path}/#{x}")
52
+ md5, link = self.release(x)
53
+ Download.new.fetch(link)
54
+ self.extract(Download.new.path(link)) if self.verify(x, link)
55
+ # TODO: retry download after failed download verification
32
56
  end
33
57
  end
34
- return releases.first
35
- end
36
58
 
37
- def rm
38
- FileUtils.rm_r path if File.directory?(path)
39
- end
59
+ def verify(x, file, version='')
60
+ md5, link = self.release(x, version)
61
+ if md5 == Digest::MD5.file(Download.new.path(file)).hexdigest
62
+ return true
63
+ else
64
+ say("Verification failed for #{project} download!", :red)
65
+ exit
66
+ end
67
+ end
40
68
 
41
- def extract
42
- Gem::Package::TarReader.new( Zlib::GzipReader.open path ) do |tar|
43
- dst = nil
44
- tar.each do |entry|
45
- if entry.full_name == TAR_LONGLINK
46
- dst = File.join dest, entry.read.strip
47
- next
69
+ def release(project, version='')
70
+ feed = self.feed(project)
71
+ Download.new.fetch(feed)
72
+ xml = File.open(Download.new.path(feed))
73
+ doc = Nokogiri::XML(xml)
74
+ releases = {}
75
+ if version.empty? == false
76
+ doc.xpath('//releases//release').each do |item|
77
+ if item.at_xpath('version').content == version
78
+ releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
79
+ end
48
80
  end
49
- dst ||= File.join dest, entry.full_name
50
- if entry.directory?
51
- FileUtils.rm_rf dst unless File.directory? dst
52
- FileUtils.mkdir_p dst, :mode => entry.header.mode, :verbose => false
53
- elsif entry.file?
54
- FileUtils.rm_rf dst unless File.file? dst
55
- File.open dst, "wb" do |f|
56
- f.print entry.read
81
+ else
82
+ doc.xpath('//releases//release').each do |item|
83
+ if !item.at_xpath('version_extra')
84
+ releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
57
85
  end
58
- FileUtils.chmod entry.header.mode, dst, :verbose => false
59
- elsif entry.header.typeflag == '2' #Symlink!
60
- File.symlink entry.header.linkname, dst
61
86
  end
87
+ end
88
+ if releases.nil?
89
+ doc.xpath('//releases//release').each do |item|
90
+ releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
91
+ end
92
+ end
93
+ return releases.first
94
+ end
95
+
96
+ def clean(arg)
97
+ FileUtils.rm_r arg if File.directory?(arg)
98
+ end
99
+
100
+ def extract(archive)
101
+ Gem::Package::TarReader.new( Zlib::GzipReader.open archive ) do |tar|
62
102
  dst = nil
103
+ tar.each do |entry|
104
+ if entry.full_name == TAR_LONGLINK
105
+ dst = File.join path, entry.read.strip
106
+ next
107
+ end
108
+ dst ||= File.join path, entry.full_name
109
+ if entry.directory?
110
+ FileUtils.rm_rf dst unless File.directory? dst
111
+ FileUtils.mkdir_p dst, :mode => entry.header.mode, :verbose => false
112
+ elsif entry.file?
113
+ FileUtils.rm_rf dst unless File.file? dst
114
+ File.open dst, "wb" do |f|
115
+ f.print entry.read
116
+ end
117
+ FileUtils.chmod entry.header.mode, dst, :verbose => false
118
+ elsif entry.header.typeflag == '2' #Symlink!
119
+ File.symlink entry.header.linkname, dst
120
+ end
121
+ dst = nil
122
+ end
63
123
  end
64
124
  end
65
125
  end
data/lib/onboard/repo.rb CHANGED
@@ -1,52 +1,109 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # TODO: Watch for updates to rugged that enable git push
4
3
  require 'git'
5
4
  require 'pathname'
5
+ require 'thor'
6
+
7
+ require_relative 'msg'
6
8
 
7
9
  module Onboard
8
- class Repo
9
- attr_reader :g, :path, :branch
10
-
11
- def initialize(repo)
12
- @codebase = repo['codebase']
13
- @g = self.prepare(repo)
14
- @path = repo['path']
15
- @branch = repo['branch']
16
- end
10
+ class Repo < Thor
11
+ attr_reader :g, :path, :branch, :codebase, :projects
17
12
 
18
- def info
19
- repo = {}
20
- repo['current_branch'] = g.current_branch
21
- repo['remotes'] = g.remotes
22
- return repo
23
- end
13
+ no_tasks do
14
+ def initialize(repo)
15
+ @codebase = repo['codebase']
16
+ @g = self.prepare(repo)
17
+ @path = repo['path']
18
+ @branch = repo['branch']
19
+ @projects = repo['projects']
20
+ end
24
21
 
25
- def prepare(args)
26
- repo = Git.open((Pathname.new(args['codebase'])).to_s)
27
- selection = args['branch'].empty? ? repo.current_branch : args['branch']
28
- repo.branch(selection).checkout
29
- return repo
30
- end
22
+ def st
23
+ changed = []
24
+ deleted = []
25
+ untracked = []
26
+
27
+ # TODO: figure out why g.status.changed.keys.each is returning
28
+ # unchanged files
29
+ g.status.changed.keys.each { |file| changed.push(file.to_s) if !g.diff('HEAD', file).patch.empty? }
30
+ g.status.deleted.keys.each { |file| deleted.push(file.to_s) }
31
+ g.status.untracked.keys.each { |file| untracked.push(file.to_s) }
32
+ all = changed + deleted + untracked
31
33
 
32
- def update
33
- project = File.basename(path)
34
+ if changed.empty? == false
35
+ say('CHANGED FILES:', :yellow)
36
+ changed.each { |z| puts g.diff('HEAD', z).patch }
37
+ puts ''
38
+ end
34
39
 
35
- changes = []
36
- g.status.changed.keys.each { |x| changes.push x }
37
- g.status.deleted.keys.each { |x| changes.push x }
38
- g.status.untracked.keys.each { |x| changes.push x }
40
+ if deleted.empty? == false
41
+ say('DELETED FILES:', :yellow)
42
+ deleted.each { |x| say(x, :red) }
43
+ puts ''
44
+ end
39
45
 
40
- if changes.nil? == false
41
- g.add(path, :all=>true)
42
- g.commit("Add #{project}")
43
- else
44
- puts "No changes to commit for #{project}"
46
+ if untracked.empty? == false
47
+ say('UNTRACKED FILES:', :yellow)
48
+ untracked.each { |y| say(y, :red) }
49
+ puts ''
50
+ end
51
+
52
+ return all
45
53
  end
46
- end
47
54
 
48
- def push
49
- g.push
55
+ def info
56
+ repo = {}
57
+ repo['current_branch'] = g.current_branch
58
+ repo['remotes'] = g.remotes
59
+ return repo
60
+ end
61
+
62
+ def prepare(args)
63
+ Git.open((Pathname.new(args['codebase'])).to_s)
64
+ end
65
+
66
+ def update
67
+ info = self.info
68
+ changes = []
69
+ projects.each do |x, y|
70
+ msg = "Committing #{x} on #{info['current_branch']} branch..."
71
+ Msg.new(msg).format
72
+ changes = self.commit("#{path}/#{x}")
73
+ if changes.empty? == false
74
+ say(" [done]", :green)
75
+ else
76
+ puts "\nNo changes to commit for #{x}"
77
+ end
78
+ end
79
+ if changes.empty? == false
80
+ msg = "Pushing all changes to #{info['remotes'][0]}..."
81
+ Msg.new(msg).format
82
+ self.push
83
+ say(" [done]", :green)
84
+ end
85
+ end
86
+
87
+ def commit(path)
88
+ project = File.basename(path)
89
+
90
+ changes = []
91
+ g.status.changed.keys.each { |x| changes.push x if !g.diff('HEAD', x).patch.empty? }
92
+ g.status.deleted.keys.each { |x| changes.push x }
93
+ g.status.untracked.keys.each { |x| changes.push x }
94
+
95
+ if changes.empty? == false
96
+ g.add(path, :all=>true)
97
+ g.commit("Add #{project}")
98
+ end
99
+
100
+ return changes
101
+ end
102
+
103
+ def push
104
+ g.push
105
+ end
50
106
  end
51
107
  end
52
108
  end
109
+
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'curses'
3
+ require 'io/console'
4
4
 
5
5
  module Onboard
6
6
  class Screen
7
- Curses.init_screen()
8
7
 
9
- def width
10
- return Curses.cols
8
+ def size
9
+ IO.console.winsize
10
+ rescue LoadError
11
+ [Integer(`tput li`), Integer(`tput co`)]
11
12
  end
12
13
  end
13
14
  end
15
+
@@ -1,3 +1,3 @@
1
1
  module Onboard
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/onboard.gemspec CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
  spec.add_dependency "nokogiri", "~> 1.6"
20
- spec.add_dependency "open-uri-cached", [">= 0.0.5", "< 2"]
21
20
  spec.add_dependency "git", "~> 1.2"
22
21
  spec.add_dependency "thor", [">= 0.19.1", "< 2"]
23
22
  spec.add_development_dependency "bundler", "~> 1.6"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathaniel Hoag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-24 00:00:00.000000000 Z
11
+ date: 2014-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -24,26 +24,6 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
- - !ruby/object:Gem::Dependency
28
- name: open-uri-cached
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: 0.0.5
34
- - - <
35
- - !ruby/object:Gem::Version
36
- version: '2'
37
- type: :runtime
38
- prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: 0.0.5
44
- - - <
45
- - !ruby/object:Gem::Version
46
- version: '2'
47
27
  - !ruby/object:Gem::Dependency
48
28
  name: git
49
29
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +103,7 @@ files:
123
103
  - lib/onboard.rb
124
104
  - lib/onboard/cli.rb
125
105
  - lib/onboard/confirm.rb
106
+ - lib/onboard/download.rb
126
107
  - lib/onboard/find.rb
127
108
  - lib/onboard/msg.rb
128
109
  - lib/onboard/project.rb