rover 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/rover +20 -0
  2. data/lib/rover.rb +213 -0
  3. metadata +80 -0
data/bin/rover ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+
5
+ require 'rover'
6
+
7
+ if ARGV.size <= 0
8
+ puts "You need at least one argument:\nrover install\nrover run"
9
+ else
10
+ rover = Rover.new
11
+ puts ARGV.first.downcase
12
+ case ARGV.first.downcase
13
+ when "install"
14
+ rover.install_configs
15
+ when "run"
16
+ rover.run_servers
17
+ else
18
+ puts "Unknown arguments: #{ARGV.inspect}"
19
+ end
20
+ end
data/lib/rover.rb ADDED
@@ -0,0 +1,213 @@
1
+ require 'logger'
2
+ require 'open3'
3
+ require 'colorize'
4
+ require 'foreman'
5
+
6
+ module Utils
7
+ # Cross-platform way of finding an executable in the $PATH.
8
+ #
9
+ # which('ruby') #=> /usr/bin/ruby
10
+ def which(cmd)
11
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
12
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
13
+ exts.each { |ext|
14
+ exe = File.join(path, "#{cmd}#{ext}")
15
+ return exe if File.executable? exe
16
+ }
17
+ end
18
+ return nil
19
+ end
20
+
21
+ end
22
+
23
+ module Logging
24
+ # This is the magical bit that gets mixed into your classes
25
+ def logger
26
+ Logging.logger
27
+ end
28
+
29
+ # Global, memoized, lazy initialized instance of a logger
30
+ def self.logger
31
+ @logger ||= begin
32
+ logger = Logger.new(STDOUT)
33
+ logger.level = ENV['ROVER_VERBOSE'] ? Logger::INFO : Logger::FATAL
34
+
35
+ logger
36
+ end
37
+ end
38
+ end
39
+
40
+ # Rover.new
41
+ # rover.list_configs #=> hash
42
+ # rover.install_configs #=> execute on hash above
43
+ # TODO rover.run
44
+ # TODO rover.update_from_git
45
+ # TODO rover.authors_from_git
46
+
47
+ class Rover
48
+ include Logging
49
+ include Utils
50
+
51
+ attr_accessor :start_directory
52
+
53
+ CONFIG_FILE_NAMES = {
54
+ "npm" => 'package.json',
55
+ 'bundle' => 'Gemfile',
56
+ 'pip' => 'requirements.txt'
57
+ }
58
+
59
+ def initialize
60
+ @start_directory = Dir.pwd
61
+
62
+ puts "Rover is starting in #{@start_directory}"
63
+ end
64
+
65
+ def list_configs
66
+ discover_config_files
67
+ end
68
+
69
+ def config_env config_type
70
+ return nil unless config_type
71
+ self.send("config_env_#{config_type}")
72
+ end
73
+
74
+ def config_env_npm
75
+ unless which('npm')
76
+ raise "you are fucked. go install npm"
77
+ end
78
+ end
79
+
80
+ def config_env_bundle
81
+ # nothing to do
82
+ unless which('bundle')
83
+ exec_cmd "gem install bundler"
84
+ unless which('bundle')
85
+ raise "you're fucked. go install bundler"
86
+ end
87
+ end
88
+ end
89
+
90
+ # TODO BROKEN
91
+ def config_env_pip
92
+ ['virtualenv','pip'].each do |exe|
93
+ unless which(exe)
94
+ raise "you're fucked; missing #{exe}. please install first"
95
+ end
96
+ end
97
+
98
+ python_dir = "#{@start_directory}/.python"
99
+ exec_cmd "mkdir -p #{python_dir}"
100
+ exec_cmd "virtualenv #{python_dir}"
101
+ ENV['PATH'] = "#{python_dir}/bin:#{ENV['PATH']}"
102
+ ENV['PYTHONPATH'] = ""
103
+ end
104
+
105
+ def install_configs
106
+ discovered_config_files = discover_config_files
107
+
108
+ if discovered_config_files.empty?
109
+ logger.info "Rover did not find any configuration files in this project"
110
+ else
111
+ logger.info "Rover found the following configuration files:"
112
+
113
+ puts "Rover found #{discovered_config_files.size} configuration files".underline
114
+ puts "\n"
115
+
116
+ discovered_config_files.each do |config_file_name,config_parts|
117
+ puts "Installing Config: #{config_file_name}".colorize( :color => :white, :background => :blue )
118
+
119
+ config_env(config_parts['config_type'])
120
+
121
+ cmd = "#{config_parts['config_type']} "
122
+ case config_parts['config_type']
123
+ when 'pip'
124
+ cmd += "install -r #{config_parts['config_file']}"
125
+ when 'bundle'
126
+ cmd += "install"
127
+ when 'npm'
128
+ cmd += "install"
129
+ else
130
+ logger.info "Unknown Config Type: #{config_parts['config_type']}"
131
+ next
132
+ end
133
+
134
+ change_dir(config_parts['config_path'])
135
+ exec_cmd(cmd)
136
+
137
+ puts "\n\n"
138
+ end
139
+
140
+ puts "Finished attempting to install config files. Moving back to the starting directory".colorize( :color => :white, :background => :blue )
141
+
142
+ change_dir(@start_directory)
143
+ end
144
+ end
145
+
146
+ def run_servers procfile_location = nil
147
+ if procfile_location && !procfile_location.end_with?('/')
148
+ procfile_location = "#{procfile_location}/"
149
+ end
150
+
151
+ specified_procfile = "#{procfile_location}Procfile"
152
+ if procfile_location
153
+ if File.exists?(specified_procfile)
154
+ puts "Loading Procfile found in #{specified_procfile}"
155
+ change_dir procfile_location
156
+ else
157
+ puts "No Procfile found at #{procfile_location}"
158
+ return false
159
+ end
160
+ else
161
+ puts "No Procfile location specified, defaulting to #{@start_directory}"
162
+ change_dir @start_directory
163
+ if File.exists?('Procfile')
164
+ puts "Profile exists... running foreman"
165
+ else
166
+ puts "No Procfile found. Rover can not run servers without a Procfile"
167
+ return false
168
+ end
169
+ end
170
+
171
+ `foreman start`
172
+ end
173
+
174
+ private
175
+
176
+ def exec_cmd cmd
177
+ puts cmd.colorize( :color => :red, :background => :white )
178
+ system cmd
179
+ end
180
+
181
+ def change_dir path
182
+ puts "cd #{path}".colorize( :color => :white, :background => :blue )
183
+ Dir.chdir path
184
+ end
185
+
186
+ def discover_config_files path = @start_directory
187
+ file_names_pattern = "{#{CONFIG_FILE_NAMES.values.join(',')}}"
188
+
189
+ logger.info "/Rover looks for config files (#{file_names_pattern})"
190
+
191
+ parts = [path,'**',file_names_pattern]
192
+
193
+ resp = {}
194
+
195
+ Dir.glob(parts.join('/')).each do |config_file|
196
+ next if should_exclude?(config_file)
197
+
198
+ resp[config_file] = {}
199
+
200
+ file_parts = config_file.split('/')
201
+
202
+ resp[config_file]['config_type'] = CONFIG_FILE_NAMES.key(file_parts.last)
203
+ resp[config_file]['config_file'] = file_parts.pop
204
+ resp[config_file]['config_path'] = file_parts.join('/')
205
+ end
206
+
207
+ resp
208
+ end
209
+
210
+ def should_exclude? config_file
211
+ config_file.include? 'node_module'
212
+ end
213
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rover
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Rosengarten
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: colorize
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: foreman
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: orchestrate the dependency installations of a project that uses npm +-
47
+ bundler +- pip requirements
48
+ email: mfrosengarten@gmail.com
49
+ executables:
50
+ - rover
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/rover.rb
55
+ - bin/rover
56
+ homepage: http://rubygems.org/gems/rover
57
+ licenses: []
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.8.23
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: dependency config orchestration
80
+ test_files: []