workon 0.0.13 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/Guardfile +14 -0
- data/README.md +27 -0
- data/lib/workon.rb +17 -21
- data/lib/workon/actor.rb +18 -15
- data/lib/workon/actor/base.rb +24 -92
- data/lib/workon/actor/git.rb +4 -5
- data/lib/workon/actor/guard.rb +15 -0
- data/lib/workon/actor/helpers.rb +10 -0
- data/lib/workon/actor/helpers/bundler.rb +9 -0
- data/lib/workon/actor/helpers/commandable.rb +16 -0
- data/lib/workon/actor/helpers/configurable.rb +32 -0
- data/lib/workon/actor/helpers/muxable.rb +45 -0
- data/lib/workon/actor/middleman.rb +1 -1
- data/lib/workon/actor/passenger.rb +5 -5
- data/lib/workon/actor/server.rb +42 -0
- data/lib/workon/actor/unicorn.rb +19 -0
- data/lib/workon/actor/watchr.rb +4 -4
- data/lib/workon/actor/web_browser.rb +4 -4
- data/lib/workon/cli.rb +33 -25
- data/lib/workon/cli/commands.rb +8 -8
- data/lib/workon/configuration.rb +46 -37
- data/lib/workon/rspec_helpers.rb +11 -0
- data/lib/workon/version.rb +1 -1
- data/spec/fixtures/projectrc.yml +2 -0
- data/spec/lib/workon/actor/server_spec.rb +10 -0
- data/spec/lib/workon/cli_spec.rb +30 -0
- data/spec/lib/workon/configuration_spec.rb +60 -0
- data/spec/lib/workon_spec.rb +35 -0
- data/spec/spec_helper.rb +8 -0
- data/workon.gemspec +4 -1
- metadata +92 -31
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use ruby-1.9.2-
|
1
|
+
rvm use ruby-1.9.2-p290@workon
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
guard 'rspec', :version => 2, :cli => '-c -f doc', :notification => false, :all_after_pass => false do
|
2
|
+
watch(%r{^spec/.+_spec\.rb})
|
3
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
4
|
+
watch('spec/spec_helper.rb') { "spec" }
|
5
|
+
|
6
|
+
# Rails example
|
7
|
+
# watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
# watch('config/routes.rb') { "spec/routing" }
|
9
|
+
# watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
10
|
+
# watch(%r{^spec/.+_spec\.rb})
|
11
|
+
# watch(%r{^app/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
# watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
+
# watch(%r{^app/controllers/(.+)_(controller)\.rb}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Workon
|
2
|
+
======
|
3
|
+
|
4
|
+
A simple script to bootstrap your work day. It can:
|
5
|
+
|
6
|
+
- Launch your editor with the projects directory.
|
7
|
+
- Start a web server (Middleman, Passenger, Pow, Unicorn).
|
8
|
+
- Run Guard or Watchr.
|
9
|
+
- Display display commit history (currently only Git)
|
10
|
+
- Open your file manager with the projects directory
|
11
|
+
- Open the projects development page in your browser
|
12
|
+
|
13
|
+
$ workon -h
|
14
|
+
Usage: workon [options] project
|
15
|
+
-w, --without ACTORS Exclude unwanted actors
|
16
|
+
-o, --only ACTORS Only use certain actors
|
17
|
+
-d, --dump-configuration Dump workon configuration to project_path/.workonrc
|
18
|
+
--host HOST Ping this host
|
19
|
+
--port PORT Use this port for Middleman/Passenger
|
20
|
+
--server SERVER Use this server (auto,middleman,passenger,pow,unicorn)
|
21
|
+
--install-helper Install `wo' helper function to ~/.bash_profile
|
22
|
+
-P, --show-project Echo project's directory
|
23
|
+
-n, --dry-run Do not run any commands
|
24
|
+
-v, --version Show version information
|
25
|
+
-h, --help Show this help information
|
26
|
+
|
27
|
+
More to come ...
|
data/lib/workon.rb
CHANGED
@@ -1,51 +1,47 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path("../", __FILE__)
|
2
|
-
|
3
|
-
require 'workon/configuration'
|
4
|
-
require 'workon/actor'
|
5
|
-
require "workon/version"
|
6
|
-
|
7
1
|
module Workon
|
2
|
+
autoload :Configuration, 'workon/configuration'
|
3
|
+
# autoload :Actor, 'workon/actor'
|
4
|
+
autoload :VERSION, 'workon/version'
|
5
|
+
|
8
6
|
WORK_DIRS = (ENV['WORKON_ROOT'] || ENV['HOME'] + '/Work') + '/*/*'
|
9
|
-
|
7
|
+
|
10
8
|
def self.all_directories
|
11
9
|
@_all_directories ||= Dir[WORK_DIRS]
|
12
10
|
end
|
13
|
-
|
11
|
+
|
14
12
|
def self.project_name
|
15
13
|
config[:project]
|
16
14
|
end
|
17
|
-
|
15
|
+
|
18
16
|
def self.project_path
|
19
17
|
@_path
|
20
18
|
end
|
21
|
-
|
19
|
+
|
22
20
|
def self.has_project?
|
23
21
|
!project_name.nil? && 0 < project_name.to_s.length
|
24
22
|
end
|
25
|
-
|
23
|
+
|
26
24
|
def self.find_project(str = project_name)
|
27
25
|
candidate = all_directories.find { |d| d.end_with? "/#{str}" }
|
28
|
-
|
26
|
+
|
29
27
|
unless candidate.nil?
|
30
28
|
@_path = candidate
|
31
29
|
config.merge_project_rc
|
32
30
|
end
|
33
31
|
end
|
34
|
-
|
32
|
+
|
35
33
|
def self.commit!
|
36
34
|
Dir.chdir project_path
|
37
|
-
|
35
|
+
|
38
36
|
Workon::Actor.ordered.each do |klass|
|
37
|
+
next if config[:without].include? klass.actor_name
|
39
38
|
klass.new(project_path).commit
|
40
39
|
end
|
41
40
|
end
|
42
|
-
|
43
|
-
def self.load_configuration(args)
|
44
|
-
Workon::Configuration.instance.parse_options args
|
45
|
-
end
|
46
|
-
|
41
|
+
|
47
42
|
def self.config(args = [])
|
48
|
-
|
49
|
-
Workon::Configuration.instance
|
43
|
+
@config ||= Configuration.new args
|
50
44
|
end
|
51
45
|
end
|
46
|
+
|
47
|
+
require 'workon/actor'
|
data/lib/workon/actor.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
module Workon
|
2
2
|
module Actor
|
3
|
-
|
4
|
-
|
3
|
+
autoload :Helpers, 'workon/actor/helpers'
|
4
|
+
|
5
5
|
def self.each(&block)
|
6
|
-
|
6
|
+
Base.subclasses.each {|c| yield c }
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def self.before(actor = nil, other = nil)
|
10
10
|
@before ||= Hash.new { [] }
|
11
|
-
|
11
|
+
|
12
12
|
return @before if actor.nil?
|
13
13
|
raise ArgumentError if other.nil?
|
14
|
-
|
14
|
+
|
15
15
|
@before[other] += [actor]
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def self.ordered
|
19
|
-
order ||=
|
19
|
+
order ||= Base.subclasses.inject([]) do |memo, klass|
|
20
20
|
other = encompass klass
|
21
|
-
should_add = !
|
22
|
-
|
21
|
+
should_add = !memo.include?(klass)
|
22
|
+
|
23
23
|
should_add ? memo + other : memo
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
order
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def self.encompass(klass)
|
30
30
|
finder = klass.actor_name.to_sym
|
31
31
|
_before = before[finder].map {|k| encompass k }
|
32
|
-
|
32
|
+
|
33
33
|
(_before + [klass]).flatten
|
34
34
|
end
|
35
35
|
end
|
@@ -41,5 +41,8 @@ require 'workon/actor/web_browser'
|
|
41
41
|
require 'workon/actor/finder'
|
42
42
|
require 'workon/actor/git'
|
43
43
|
require 'workon/actor/watchr'
|
44
|
-
require 'workon/actor/passenger'
|
45
|
-
require 'workon/actor/middleman'
|
44
|
+
# require 'workon/actor/passenger'
|
45
|
+
# require 'workon/actor/middleman'
|
46
|
+
# require 'workon/actor/unicorn'
|
47
|
+
require 'workon/actor/guard'
|
48
|
+
require 'workon/actor/server'
|
data/lib/workon/actor/base.rb
CHANGED
@@ -1,125 +1,57 @@
|
|
1
1
|
module Workon
|
2
2
|
module Actor
|
3
3
|
class Base
|
4
|
+
include Workon::Actor::Helpers::Configurable
|
5
|
+
include Workon::Actor::Helpers::Commandable
|
6
|
+
include Workon::Actor::Helpers::Muxable
|
7
|
+
include Workon::Actor::Helpers::Bundler
|
8
|
+
|
4
9
|
attr_reader :path
|
5
|
-
|
6
|
-
|
10
|
+
|
7
11
|
def self.inherited(base)
|
8
12
|
@_subclasses ||= []
|
9
13
|
@_subclasses << base
|
10
14
|
end
|
11
|
-
|
12
|
-
def self.option(*args, &block)
|
13
|
-
Workon::Configuration.instance.parser.on(*args) do |v|
|
14
|
-
block.call(v)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.options
|
19
|
-
Workon.config
|
20
|
-
end
|
21
|
-
|
15
|
+
|
22
16
|
def self.subclasses
|
23
17
|
@_subclasses
|
24
18
|
end
|
25
|
-
|
19
|
+
|
26
20
|
def self.before(other = :all)
|
27
21
|
Workon::Actor.before self, other
|
28
22
|
end
|
29
|
-
|
23
|
+
|
30
24
|
def self.actor_name
|
31
25
|
name.split('::').last
|
32
26
|
end
|
33
|
-
|
27
|
+
|
34
28
|
def initialize(path)
|
35
29
|
@path = path
|
36
30
|
end
|
37
|
-
|
38
|
-
def options
|
39
|
-
self.class.options
|
40
|
-
end
|
41
|
-
|
42
|
-
def has_option?(key)
|
43
|
-
options.exists? key
|
44
|
-
end
|
45
|
-
|
46
|
-
def fetch_option(key, default = nil)
|
47
|
-
options.fetch key, default
|
48
|
-
end
|
49
|
-
|
31
|
+
|
50
32
|
def project
|
51
33
|
@project ||= Workon.project_name
|
52
34
|
end
|
53
|
-
|
35
|
+
|
54
36
|
def commit
|
55
|
-
run command
|
56
|
-
end
|
57
|
-
|
58
|
-
def run(command)
|
59
|
-
puts "Running #{command}"
|
60
|
-
Kernel.system command unless options[:dry_run]
|
61
|
-
end
|
62
|
-
|
63
|
-
def has_command?(command)
|
64
|
-
!`command -v '#{command}'`.empty?
|
65
|
-
end
|
66
|
-
|
67
|
-
def capture(command)
|
68
|
-
puts "Running #{command}"
|
69
|
-
output = %x(#{command}) unless options[:dry_run]
|
70
|
-
return output
|
71
|
-
end
|
72
|
-
|
73
|
-
def bundle_command(command)
|
74
|
-
project_uses_bundler? ? "bundle exec #{command}" : command
|
75
|
-
end
|
76
|
-
|
77
|
-
def project_uses_bundler?
|
78
|
-
$project_uses_bundler ||= File.exists? './Gemfile'
|
79
|
-
end
|
80
|
-
|
81
|
-
def screen(command)
|
82
|
-
$has_tmux ||= has_command? 'tmux'
|
83
|
-
|
84
|
-
$has_tmux ? _tmux(command) : _screen(command)
|
85
|
-
end
|
86
|
-
|
87
|
-
def _screen(command, scope = nil)
|
88
|
-
identifier = screen_scope scope
|
89
|
-
|
90
|
-
run %(screen -dmS #{identifier} #{command})
|
91
|
-
puts %(Reconnect with `screen -r #{identifier}')
|
92
|
-
end
|
93
|
-
|
94
|
-
def _tmux(command)
|
95
|
-
initialize_tmux
|
96
|
-
|
97
|
-
run "tmux attach-session -t #{tmux_session} \\; new-window -d -n #{tmux_window} '#{command}' \\; detach-client"
|
98
|
-
end
|
99
|
-
|
100
|
-
def initialize_tmux
|
101
|
-
$tmux_initialized ||= begin
|
102
|
-
run "tmux new-session -s #{tmux_session} \\; set-option -t #{tmux_session} set-remain-on-exit on \\; detach-client"
|
103
|
-
true
|
104
|
-
end
|
37
|
+
run command if !!command
|
105
38
|
end
|
106
|
-
|
107
|
-
def
|
108
|
-
|
109
|
-
"#{project}.#{scope}".downcase
|
39
|
+
|
40
|
+
def project_has_file?(file)
|
41
|
+
!Dir[path + "/#{file}"].empty?
|
110
42
|
end
|
111
|
-
|
112
|
-
def
|
113
|
-
|
43
|
+
|
44
|
+
def project_has_one_of?(*files)
|
45
|
+
files.any? { |f| project_has_file? f }
|
114
46
|
end
|
115
|
-
|
116
|
-
def
|
117
|
-
|
47
|
+
|
48
|
+
def project_has_folder?(folder)
|
49
|
+
File.directory? path + "/#{folder}"
|
118
50
|
end
|
119
|
-
|
51
|
+
|
120
52
|
def open_with_default(thing)
|
121
53
|
$open_command ||= has_command?('xdg-open') ? 'xdg-open' : 'open'
|
122
|
-
|
54
|
+
|
123
55
|
"#{$open_command} #{thing}"
|
124
56
|
end
|
125
57
|
end
|
data/lib/workon/actor/git.rb
CHANGED
@@ -2,12 +2,11 @@ module Workon
|
|
2
2
|
module Actor
|
3
3
|
class Git < Base
|
4
4
|
def project_uses_git?
|
5
|
-
|
5
|
+
project_has_folder? '.git'
|
6
6
|
end
|
7
|
-
|
8
|
-
def
|
9
|
-
|
10
|
-
puts output
|
7
|
+
|
8
|
+
def command
|
9
|
+
"git log --oneline -n 10" if project_uses_git?
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Workon
|
2
|
+
module Actor
|
3
|
+
module Helpers
|
4
|
+
autoload :Bundler, 'workon/actor/helpers/bundler'
|
5
|
+
autoload :Commandable, 'workon/actor/helpers/commandable'
|
6
|
+
autoload :Configurable, 'workon/actor/helpers/configurable'
|
7
|
+
autoload :Muxable, 'workon/actor/helpers/muxable'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Workon::Actor::Helpers::Commandable
|
2
|
+
def run(command)
|
3
|
+
puts "Running #{command}" unless $TESTING
|
4
|
+
Kernel.system command unless options[:dry_run]
|
5
|
+
end
|
6
|
+
|
7
|
+
def has_command?(command)
|
8
|
+
!`command -v '#{command}'`.empty?
|
9
|
+
end
|
10
|
+
|
11
|
+
def capture(command)
|
12
|
+
puts "Running #{command}" unless $TESTING
|
13
|
+
output = %x(#{command}) unless options[:dry_run]
|
14
|
+
return output
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Workon::Actor::Helpers::Configurable
|
2
|
+
module ClassMethods
|
3
|
+
def option(*args, &block)
|
4
|
+
Workon.config.parser.on(*args) do |v|
|
5
|
+
block.call(v)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def options
|
10
|
+
Workon.config
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module InstanceMethods
|
15
|
+
def options
|
16
|
+
self.class.options
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_option?(key)
|
20
|
+
options.exists? key
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch_option(key, default = nil)
|
24
|
+
options.fetch key, default
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.included(receiver)
|
29
|
+
receiver.extend ClassMethods
|
30
|
+
receiver.send :include, InstanceMethods
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Workon::Actor::Helpers::Muxable
|
2
|
+
def screen(command)
|
3
|
+
$has_tmux ||= has_command? 'tmux'
|
4
|
+
command = rvm_exec command
|
5
|
+
|
6
|
+
$has_tmux ? _tmux(command) : _screen(command)
|
7
|
+
end
|
8
|
+
|
9
|
+
def _screen(command, scope = nil)
|
10
|
+
identifier = screen_scope scope
|
11
|
+
|
12
|
+
run %(screen -dmS #{identifier} #{command})
|
13
|
+
puts %(Reconnect with `screen -r #{identifier}')
|
14
|
+
end
|
15
|
+
|
16
|
+
def _tmux(command)
|
17
|
+
initialize_tmux
|
18
|
+
|
19
|
+
run "tmux attach-session -t #{tmux_session} \\; new-window -d -n #{tmux_window} '#{command}' \\; detach-client"
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize_tmux
|
23
|
+
$tmux_initialized ||= begin
|
24
|
+
run "tmux new-session -s #{tmux_session} \\; set-option -t #{tmux_session} set-remain-on-exit on \\; detach-client"
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def screen_scope(scope = nil)
|
30
|
+
scope ||= self.class.actor_name
|
31
|
+
"#{project}.#{scope}".downcase
|
32
|
+
end
|
33
|
+
|
34
|
+
def tmux_session
|
35
|
+
project
|
36
|
+
end
|
37
|
+
|
38
|
+
def tmux_window
|
39
|
+
self.class.actor_name.downcase
|
40
|
+
end
|
41
|
+
|
42
|
+
def rvm_exec(command)
|
43
|
+
Dir['./.rvmrc'].empty? ? command : "rvm --with-rubies default-with-rvmrc exec #{command}"
|
44
|
+
end
|
45
|
+
end
|
@@ -2,15 +2,15 @@ module Workon
|
|
2
2
|
module Actor
|
3
3
|
class Passenger < Base
|
4
4
|
before :WebBrowser
|
5
|
-
|
5
|
+
|
6
6
|
def is_rack_app?
|
7
|
-
|
7
|
+
project_has_file? 'config.ru'
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def passenger_standalone_available?
|
11
11
|
has_command? 'passenger'
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def commit
|
15
15
|
if is_rack_app? && passenger_standalone_available?
|
16
16
|
port = fetch_option :port, 3000
|
@@ -19,4 +19,4 @@ module Workon
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Workon
|
2
|
+
module Actor
|
3
|
+
class Server < Base
|
4
|
+
option('--server SERVER', 'Use this server (auto,middleman,passenger,pow,unicorn)') { |v| options[:server] = v}
|
5
|
+
before :WebBrowser
|
6
|
+
|
7
|
+
def commit
|
8
|
+
actual = fetch_option :server, 'auto'
|
9
|
+
valid = %w(auto middleman passenger pow unicorn)
|
10
|
+
|
11
|
+
return unless valid.include? actual
|
12
|
+
send :"commit_for_#{actual}"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def commit_for_auto
|
17
|
+
commit_for_unicorn and return if project_has_one_of?('unicorn.rb', 'config/unicorn.rb')
|
18
|
+
commit_for_passenger and return if project_has_file?('config.ru') && has_command?('passenger')
|
19
|
+
end
|
20
|
+
|
21
|
+
def commit_for_passenger
|
22
|
+
port = fetch_option :port, 3000
|
23
|
+
screen bundle_command("passenger start --port #{port}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def commit_for_middleman
|
27
|
+
port = fetch_option :port, 4567
|
28
|
+
screen bundle_command("mm-server --port #{port}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def commit_for_pow
|
32
|
+
options[:port] = nil
|
33
|
+
options[:host] = "#{project}.dev"
|
34
|
+
end
|
35
|
+
|
36
|
+
def commit_for_unicorn
|
37
|
+
port = fetch_option :port, 8080
|
38
|
+
screen bundle_command("unicorn_rails -c #{path}/config/unicorn.rb -l #{port}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Workon
|
2
|
+
module Actor
|
3
|
+
class Unicorn < Base
|
4
|
+
before :WebBrowser
|
5
|
+
|
6
|
+
def has_unicorn_config?
|
7
|
+
project_has_file? 'config/unicorn.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
def commit
|
11
|
+
if has_unicorn_config?
|
12
|
+
port = fetch_option :port, 8080
|
13
|
+
screen bundle_command("unicorn_rails -c #{path}/config/unicorn.rb -l #{port}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/lib/workon/actor/watchr.rb
CHANGED
@@ -3,22 +3,22 @@ module Workon
|
|
3
3
|
class WebBrowser < Base
|
4
4
|
option('--host HOST', 'Ping this host') { |v| options[:host] = v}
|
5
5
|
option('--port PORT', Integer, 'Use this port for Middleman/Passenger') { |v| options[:port] = v}
|
6
|
-
|
6
|
+
|
7
7
|
def command
|
8
8
|
host_name = fetch_option :host, %{#{project}.local}
|
9
9
|
port_number = fetch_option :port, nil
|
10
|
-
|
10
|
+
|
11
11
|
command, qualified = port_number.nil? ? ping_test(host_name) : netstat_test(port_number)
|
12
12
|
opener = open_with_default "http://#{qualified}"
|
13
13
|
%(#{command} && #{opener})
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
private
|
17
17
|
def ping_test(host_name)
|
18
18
|
command = %{ping -q -c 1 -t 1 #{host_name}}
|
19
19
|
[ command, host_name ]
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def netstat_test(port)
|
23
23
|
command = %{sleep 3 && netstat -na | egrep 'tcp4*6* +([0-9]+ +){2}(\\*|([0-9]+\\.)+[0-9]+)(:|\\.)#{port}'}
|
24
24
|
[ command, "localhost:#{port}" ]
|
data/lib/workon/cli.rb
CHANGED
@@ -1,35 +1,43 @@
|
|
1
1
|
require 'workon'
|
2
|
-
require 'workon/cli/commands'
|
3
2
|
|
4
3
|
module Workon
|
5
4
|
module CLI
|
5
|
+
autoload :Commands, 'workon/cli/commands'
|
6
|
+
|
7
|
+
def self.show_help
|
8
|
+
puts @config.parser
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.install_helper
|
13
|
+
Commands::InstallHelper.execute
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.show_project
|
18
|
+
puts Workon.project_path
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.dump_configuration
|
23
|
+
@config.dump_to_project_rc
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
6
27
|
def self.execute
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if config[:install_helper]
|
15
|
-
Workon::CLI::Commands::InstallHelper.execute
|
16
|
-
exit
|
17
|
-
end
|
18
|
-
|
28
|
+
Workon.config.merge_options ARGV
|
29
|
+
@config = Workon.config
|
30
|
+
|
31
|
+
show_help if @config[:show_help]
|
32
|
+
install_helper if @config[:install_helper]
|
33
|
+
|
19
34
|
raise OptionParser::MissingArgument unless Workon.has_project?
|
20
|
-
|
35
|
+
|
21
36
|
Workon.find_project
|
22
|
-
|
23
|
-
if config[:show_project]
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
if config[:dump_configuration]
|
29
|
-
Workon::Configuration.instance.dump_to_project_rc
|
30
|
-
exit
|
31
|
-
end
|
32
|
-
|
37
|
+
|
38
|
+
show_project if @config[:show_project]
|
39
|
+
dump_configuration if @config[:dump_configuration]
|
40
|
+
|
33
41
|
Workon.commit!
|
34
42
|
end
|
35
43
|
end
|
data/lib/workon/cli/commands.rb
CHANGED
@@ -3,40 +3,40 @@ module Workon
|
|
3
3
|
module Commands
|
4
4
|
module InstallHelper
|
5
5
|
BASH_PROFILE_PATH = '~/.bash_profile'
|
6
|
-
|
6
|
+
|
7
7
|
def self.execute
|
8
8
|
install unless installed?
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def self.install
|
12
12
|
puts "Installing bash helper function to #{bash_profile_path}"
|
13
|
-
|
13
|
+
|
14
14
|
begin
|
15
15
|
File.open(bash_profile_path, 'a') do |f|
|
16
16
|
f.write "\n\n"
|
17
17
|
f.write finder
|
18
18
|
f.write helper_function
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
puts "... Success!"
|
22
22
|
rescue => error
|
23
23
|
puts "... Failed!"
|
24
24
|
puts error
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def self.bash_profile_path
|
29
29
|
BASH_PROFILE_PATH.sub '~', ENV['HOME']
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def self.finder
|
33
33
|
"# Created by workon\n"
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def self.installed?
|
37
37
|
!(File.read(bash_profile_path) =~ /#{finder}/).nil?
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def self.helper_function
|
41
41
|
<<'BASH'
|
42
42
|
wo () {
|
data/lib/workon/configuration.rb
CHANGED
@@ -5,69 +5,78 @@ module Workon
|
|
5
5
|
class Configuration
|
6
6
|
attr_reader :options
|
7
7
|
attr_reader :parser
|
8
|
-
|
9
|
-
def
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
|
9
|
+
def initialize(options = nil)
|
10
|
+
@options = {
|
11
|
+
show_project: false,
|
12
|
+
without: [],
|
13
|
+
only: [],
|
14
|
+
install_helper: false,
|
15
|
+
dump_configuration: false,
|
16
|
+
project: nil,
|
17
|
+
show_help: false
|
18
|
+
}
|
19
|
+
|
20
|
+
merge_options options unless blank? options
|
16
21
|
end
|
17
|
-
|
18
|
-
def
|
19
|
-
|
20
|
-
|
22
|
+
|
23
|
+
def merge_options(args)
|
24
|
+
if Hash === args
|
25
|
+
@options.merge! args
|
26
|
+
elsif Array === args
|
27
|
+
parser.parse! args
|
28
|
+
options[:project] = args.first unless args.empty?
|
29
|
+
end
|
21
30
|
end
|
22
|
-
|
31
|
+
|
23
32
|
def exists?(key)
|
24
33
|
key = key.to_sym
|
25
34
|
!blank? options[key]
|
26
35
|
end
|
27
|
-
|
36
|
+
|
28
37
|
def set(key, value)
|
29
38
|
key = key.to_sym
|
30
39
|
options[key] = value
|
31
40
|
end
|
32
|
-
|
41
|
+
|
33
42
|
def fetch(key, default = nil)
|
34
43
|
key = key.to_sym
|
35
|
-
|
44
|
+
|
36
45
|
if !exists?(key) && !blank?(default)
|
37
46
|
set key, default
|
38
47
|
end
|
39
|
-
|
48
|
+
|
40
49
|
options[key]
|
41
50
|
end
|
42
|
-
|
51
|
+
|
43
52
|
def [](key)
|
44
53
|
fetch key
|
45
54
|
end
|
46
|
-
|
55
|
+
|
47
56
|
def []=(key, value)
|
48
57
|
set key, value
|
49
58
|
end
|
50
|
-
|
59
|
+
|
51
60
|
def parser
|
52
61
|
@parser ||= OptionParser.new do |o|
|
53
|
-
o.banner = "Usage:
|
54
|
-
|
62
|
+
o.banner = "Usage: workon [options] project"
|
63
|
+
|
55
64
|
o.on('-w', '--without ACTORS', Array, 'Exclude unwanted actors') do |v|
|
56
65
|
options[:without] = v
|
57
66
|
end
|
58
|
-
|
67
|
+
|
59
68
|
o.on('-o', '--only ACTORS', Array, 'Only use certain actors') do |v|
|
60
69
|
options[:only] = v
|
61
70
|
end
|
62
|
-
|
71
|
+
|
63
72
|
o.on('-d', '--dump-configuration', 'Dump workon configuration to project_path/.workonrc') do
|
64
73
|
options[:dump_configuration] = true
|
65
74
|
end
|
66
|
-
|
75
|
+
|
67
76
|
o.on_tail('--install-helper', 'Install `wo\' helper function to ~/.bash_profile') do
|
68
77
|
options[:install_helper] = true
|
69
78
|
end
|
70
|
-
|
79
|
+
|
71
80
|
o.on_tail('-P', '--show-project', TrueClass, "Echo project's directory") do
|
72
81
|
options[:show_project] = true
|
73
82
|
end
|
@@ -75,52 +84,52 @@ module Workon
|
|
75
84
|
o.on_tail('-n', '--dry-run', 'Do not run any commands') do
|
76
85
|
options[:dry_run] = true
|
77
86
|
end
|
78
|
-
|
87
|
+
|
79
88
|
o.on_tail('-v', '--version', 'Show version information') do
|
80
89
|
puts Workon::VERSION
|
81
90
|
exit
|
82
91
|
end
|
83
|
-
|
92
|
+
|
84
93
|
o.on_tail('-h', '--help', 'Show this help information') do
|
85
94
|
options[:show_help] = true
|
86
95
|
# exit
|
87
96
|
end
|
88
97
|
end
|
89
98
|
end
|
90
|
-
|
99
|
+
|
91
100
|
def project_rc_path
|
92
101
|
@project_rc_path ||= File.join Workon.project_path, '.workonrc'
|
93
102
|
end
|
94
|
-
|
103
|
+
|
95
104
|
def project_rc_exists?
|
96
105
|
File.exist? project_rc_path
|
97
106
|
end
|
98
|
-
|
107
|
+
|
99
108
|
def merge_project_rc
|
100
109
|
if project_rc_exists?
|
101
|
-
|
102
|
-
@options.merge! opts
|
110
|
+
merge_options YAML.load_file(project_rc_path)
|
103
111
|
end
|
104
112
|
end
|
105
|
-
|
113
|
+
|
106
114
|
def dump_to_project_rc
|
107
115
|
o = options.dup
|
108
116
|
o.delete :install_helper
|
109
117
|
o.delete :dump_configuration
|
110
118
|
o.delete :project
|
111
119
|
o.delete :show_help
|
112
|
-
|
120
|
+
o.delete :show_project
|
121
|
+
|
113
122
|
begin
|
114
123
|
File.open(project_rc_path, 'w') do |f|
|
115
124
|
YAML.dump o, f
|
116
125
|
end
|
117
|
-
|
126
|
+
|
118
127
|
puts %(Saved workon configuration to #{project_rc_path})
|
119
128
|
rescue
|
120
129
|
STDERR.puts %(Could not save workon configuration to #{project_rc_path})
|
121
130
|
end
|
122
131
|
end
|
123
|
-
|
132
|
+
|
124
133
|
private
|
125
134
|
def blank?(object)
|
126
135
|
object.respond_to?(:empty?) ? object.empty? : !object
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Workon
|
2
|
+
module RSpecHelpers
|
3
|
+
def stub_projectrc!(rc_file = 'projectrc')
|
4
|
+
fixtures_path = File.expand_path '../../../spec/fixtures', __FILE__
|
5
|
+
fixture_path = fixtures_path + "/#{rc_file}.yml"
|
6
|
+
|
7
|
+
subject.stub(:project_rc_exists?).and_return true
|
8
|
+
subject.stub(:project_rc_path).and_return fixture_path
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/workon/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'workon/cli'
|
3
|
+
|
4
|
+
describe Workon::CLI do
|
5
|
+
before(:each) { Workon.instance_eval { @config = nil } }
|
6
|
+
|
7
|
+
it "shows help when asked" do
|
8
|
+
Workon.config show_help: true
|
9
|
+
described_class.should_receive(:show_help).and_return { exit }
|
10
|
+
expect { described_class.execute }.to raise_error SystemExit
|
11
|
+
end
|
12
|
+
|
13
|
+
it "installs bash helper when asked" do
|
14
|
+
Workon.config install_helper: true
|
15
|
+
described_class.should_receive(:install_helper).and_return { exit }
|
16
|
+
expect { described_class.execute }.to raise_error SystemExit
|
17
|
+
end
|
18
|
+
|
19
|
+
it "shows project path when asked" do
|
20
|
+
Workon.config show_project: true, project: 'foo'
|
21
|
+
described_class.should_receive(:show_project).and_return { exit }
|
22
|
+
expect { described_class.execute }.to raise_error SystemExit
|
23
|
+
end
|
24
|
+
|
25
|
+
it "dumps configuration" do
|
26
|
+
Workon.config dump_configuration: true, project: 'foo'
|
27
|
+
described_class.should_receive(:dump_configuration).and_return { exit }
|
28
|
+
expect { described_class.execute }.to raise_error SystemExit
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Workon::Configuration do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
describe "has defaults" do
|
7
|
+
its([:show_project]) { should be_false }
|
8
|
+
its([:without]) { should == [] }
|
9
|
+
its([:only]) { should == [] }
|
10
|
+
its([:install_helper]) { should be_false }
|
11
|
+
its([:dump_configuration]) { should be_false }
|
12
|
+
its([:project]) { should be_nil }
|
13
|
+
its([:show_help]) { should be_false }
|
14
|
+
its(:parser) { should be_an(OptionParser) }
|
15
|
+
|
16
|
+
describe "can be overriden" do
|
17
|
+
subject { described_class.new(dump_configuration: true) }
|
18
|
+
|
19
|
+
its([:dump_configuration]) { should be_true }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "works from ARGV (--show-project foo)" do
|
24
|
+
subject { described_class.new %w(--show-project foo) }
|
25
|
+
|
26
|
+
its([:project]) { should == "foo" }
|
27
|
+
its([:show_project]) { should be_true }
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can tell if a key exists" do
|
31
|
+
subject.exists?(:foo).should be_false
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can set things" do
|
35
|
+
new_value = :bar
|
36
|
+
subject.set :foo, new_value
|
37
|
+
subject[:foo].should == new_value
|
38
|
+
end
|
39
|
+
|
40
|
+
it "uses fetch to also set values" do
|
41
|
+
default_port = 3000
|
42
|
+
subject.fetch(:port, default_port).should == default_port
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe "with project .workonrc" do
|
47
|
+
it "can find project .workonrc" do
|
48
|
+
project_path = '/code/foo'
|
49
|
+
Workon.stub(:project_path).and_return project_path
|
50
|
+
|
51
|
+
subject.project_rc_path.should == project_path + '/.workonrc'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can merge project .workonrc" do
|
55
|
+
stub_projectrc!
|
56
|
+
subject.merge_project_rc
|
57
|
+
subject[:port].should == 3000
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Workon do
|
4
|
+
before do
|
5
|
+
Workon.stub(:all_directories) { %w(/code/foo /code/bar) }
|
6
|
+
end
|
7
|
+
|
8
|
+
before(:each) { Workon.instance_eval { @config = nil } }
|
9
|
+
|
10
|
+
it "finds a project" do
|
11
|
+
Workon.config[:project] = 'foo'
|
12
|
+
Workon.find_project
|
13
|
+
Workon.project_path.should == '/code/foo'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "runs nothing when -n passed" do
|
17
|
+
Dir.stub(:chdir) { true }
|
18
|
+
|
19
|
+
Workon.config[:dry_run] = true
|
20
|
+
Workon.config[:project] = 'foo'
|
21
|
+
Workon.find_project
|
22
|
+
Workon.commit!
|
23
|
+
|
24
|
+
Kernel.should_not_receive :system
|
25
|
+
Kernel.should_not_receive :exec
|
26
|
+
end
|
27
|
+
|
28
|
+
it "ignores things in --without" do
|
29
|
+
Dir.stub(:chdir).with(Workon.project_path)
|
30
|
+
Workon::Actor::Server.should_not_receive :new
|
31
|
+
Workon.config project: 'foo', without: 'Server', dry_run: true
|
32
|
+
Workon.find_project
|
33
|
+
Workon.commit!
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/workon.gemspec
CHANGED
@@ -13,7 +13,10 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = %q{Runs actions based on directories}
|
14
14
|
|
15
15
|
# s.add_dependency "activesupport"
|
16
|
-
|
16
|
+
s.add_development_dependency "rspec"
|
17
|
+
s.add_development_dependency "guard"
|
18
|
+
s.add_development_dependency "guard-rspec"
|
19
|
+
s.add_development_dependency "rb-fsevent" if RUBY_PLATFORM =~ /darwin/
|
17
20
|
|
18
21
|
s.rubyforge_project = "workon"
|
19
22
|
|
metadata
CHANGED
@@ -1,31 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: workon
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.15
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.13
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Mike Wyatt
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
|
12
|
+
date: 2011-08-24 00:00:00.000000000 -02:30
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
requirement: &70248633807960 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70248633807960
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: guard
|
28
|
+
requirement: &70248633807540 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *70248633807540
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: guard-rspec
|
39
|
+
requirement: &70248633807120 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *70248633807120
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rb-fsevent
|
50
|
+
requirement: &70248633806660 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *70248633806660
|
16
59
|
description: Runs actions based on directories
|
17
|
-
email:
|
60
|
+
email:
|
18
61
|
- wyatt.mike@gmail.com
|
19
|
-
executables:
|
62
|
+
executables:
|
20
63
|
- workon
|
21
64
|
extensions: []
|
22
|
-
|
23
65
|
extra_rdoc_files: []
|
24
|
-
|
25
|
-
files:
|
66
|
+
files:
|
26
67
|
- .gitignore
|
27
68
|
- .rvmrc
|
28
69
|
- Gemfile
|
70
|
+
- Guardfile
|
71
|
+
- README.md
|
29
72
|
- Rakefile
|
30
73
|
- bin/workon
|
31
74
|
- lib/workon.rb
|
@@ -34,41 +77,59 @@ files:
|
|
34
77
|
- lib/workon/actor/editor.rb
|
35
78
|
- lib/workon/actor/finder.rb
|
36
79
|
- lib/workon/actor/git.rb
|
80
|
+
- lib/workon/actor/guard.rb
|
81
|
+
- lib/workon/actor/helpers.rb
|
82
|
+
- lib/workon/actor/helpers/bundler.rb
|
83
|
+
- lib/workon/actor/helpers/commandable.rb
|
84
|
+
- lib/workon/actor/helpers/configurable.rb
|
85
|
+
- lib/workon/actor/helpers/muxable.rb
|
37
86
|
- lib/workon/actor/middleman.rb
|
38
87
|
- lib/workon/actor/passenger.rb
|
88
|
+
- lib/workon/actor/server.rb
|
89
|
+
- lib/workon/actor/unicorn.rb
|
39
90
|
- lib/workon/actor/watchr.rb
|
40
91
|
- lib/workon/actor/web_browser.rb
|
41
92
|
- lib/workon/cli.rb
|
42
93
|
- lib/workon/cli/commands.rb
|
43
94
|
- lib/workon/configuration.rb
|
95
|
+
- lib/workon/rspec_helpers.rb
|
44
96
|
- lib/workon/version.rb
|
97
|
+
- spec/fixtures/projectrc.yml
|
98
|
+
- spec/lib/workon/actor/server_spec.rb
|
99
|
+
- spec/lib/workon/cli_spec.rb
|
100
|
+
- spec/lib/workon/configuration_spec.rb
|
101
|
+
- spec/lib/workon_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
45
103
|
- workon.gemspec
|
46
|
-
|
104
|
+
has_rdoc: true
|
105
|
+
homepage: ''
|
47
106
|
licenses: []
|
48
|
-
|
49
107
|
post_install_message:
|
50
108
|
rdoc_options: []
|
51
|
-
|
52
|
-
require_paths:
|
109
|
+
require_paths:
|
53
110
|
- lib
|
54
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
112
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version:
|
60
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
118
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version:
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
66
123
|
requirements: []
|
67
|
-
|
68
124
|
rubyforge_project: workon
|
69
|
-
rubygems_version: 1.
|
125
|
+
rubygems_version: 1.6.2
|
70
126
|
signing_key:
|
71
127
|
specification_version: 3
|
72
128
|
summary: Runs actions based on directories
|
73
|
-
test_files:
|
74
|
-
|
129
|
+
test_files:
|
130
|
+
- spec/fixtures/projectrc.yml
|
131
|
+
- spec/lib/workon/actor/server_spec.rb
|
132
|
+
- spec/lib/workon/cli_spec.rb
|
133
|
+
- spec/lib/workon/configuration_spec.rb
|
134
|
+
- spec/lib/workon_spec.rb
|
135
|
+
- spec/spec_helper.rb
|