workon 0.0.15 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Guardfile +3 -12
  2. data/README.markdown +27 -0
  3. data/lib/workon.rb +3 -2
  4. data/lib/workon/actor.rb +0 -3
  5. data/lib/workon/actor/base.rb +9 -28
  6. data/lib/workon/actor/finder.rb +2 -2
  7. data/lib/workon/actor/guard.rb +3 -1
  8. data/lib/workon/actor/server.rb +21 -15
  9. data/lib/workon/actor/watchr.rb +1 -1
  10. data/lib/workon/actor/web_browser.rb +4 -16
  11. data/lib/workon/cli.rb +5 -1
  12. data/lib/workon/command.rb +76 -0
  13. data/lib/workon/command/wrappers.rb +65 -0
  14. data/lib/workon/configuration.rb +3 -3
  15. data/lib/workon/helpers.rb +5 -0
  16. data/lib/workon/helpers/assertable.rb +17 -0
  17. data/lib/workon/helpers/commandable.rb +35 -0
  18. data/lib/workon/{actor/helpers → helpers}/configurable.rb +3 -3
  19. data/lib/workon/rspec_helpers.rb +12 -0
  20. data/lib/workon/version.rb +6 -1
  21. data/spec/lib/workon/actor/base_spec.rb +21 -0
  22. data/spec/lib/workon/actor/finder_spec.rb +12 -0
  23. data/spec/lib/workon/actor/guard_spec.rb +19 -0
  24. data/spec/lib/workon/actor/server_spec.rb +1 -1
  25. data/spec/lib/workon/actor/watchr_spec.rb +19 -0
  26. data/spec/lib/workon/actor/web_browser_spec.rb +15 -0
  27. data/spec/lib/workon/cli_spec.rb +7 -1
  28. data/spec/lib/workon/command_spec.rb +62 -0
  29. data/spec/lib/workon_spec.rb +4 -3
  30. data/workon.gemspec +4 -4
  31. metadata +46 -19
  32. data/README.md +0 -27
  33. data/lib/workon/actor/helpers.rb +0 -10
  34. data/lib/workon/actor/helpers/bundler.rb +0 -9
  35. data/lib/workon/actor/helpers/commandable.rb +0 -16
  36. data/lib/workon/actor/helpers/muxable.rb +0 -45
  37. data/lib/workon/actor/middleman.rb +0 -15
  38. data/lib/workon/actor/passenger.rb +0 -22
  39. data/lib/workon/actor/unicorn.rb +0 -19
data/Guardfile CHANGED
@@ -1,14 +1,5 @@
1
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"] }
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/" }
14
5
  end
@@ -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 ...
@@ -1,7 +1,8 @@
1
1
  module Workon
2
+ autoload :Command, 'workon/command'
2
3
  autoload :Configuration, 'workon/configuration'
3
- # autoload :Actor, 'workon/actor'
4
- autoload :VERSION, 'workon/version'
4
+ autoload :Helpers, 'workon/helpers'
5
+ autoload :Version, 'workon/version'
5
6
 
6
7
  WORK_DIRS = (ENV['WORKON_ROOT'] || ENV['HOME'] + '/Work') + '/*/*'
7
8
 
@@ -41,8 +41,5 @@ 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'
46
- # require 'workon/actor/unicorn'
47
44
  require 'workon/actor/guard'
48
45
  require 'workon/actor/server'
@@ -1,12 +1,11 @@
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
4
+ include Workon::Helpers::Assertable
5
+ include Workon::Helpers::Commandable
6
+ include Workon::Helpers::Configurable
8
7
 
9
- attr_reader :path
8
+ attr_reader :path, :project
10
9
 
11
10
  def self.inherited(base)
12
11
  @_subclasses ||= []
@@ -26,33 +25,15 @@ module Workon
26
25
  end
27
26
 
28
27
  def initialize(path)
29
- @path = path
30
- end
31
-
32
- def project
33
- @project ||= Workon.project_name
28
+ @path = path
29
+ @project = Workon.project_name
34
30
  end
35
31
 
36
32
  def commit
37
- run command if !!command
38
- end
39
-
40
- def project_has_file?(file)
41
- !Dir[path + "/#{file}"].empty?
42
- end
43
-
44
- def project_has_one_of?(*files)
45
- files.any? { |f| project_has_file? f }
46
- end
47
-
48
- def project_has_folder?(folder)
49
- File.directory? path + "/#{folder}"
50
- end
51
-
52
- def open_with_default(thing)
53
- $open_command ||= has_command?('xdg-open') ? 'xdg-open' : 'open'
33
+ return if command.nil?
54
34
 
55
- "#{$open_command} #{thing}"
35
+ to_run = interpret_command command
36
+ to_run.run if !!to_run
56
37
  end
57
38
  end
58
39
  end
@@ -2,8 +2,8 @@ module Workon
2
2
  module Actor
3
3
  class Finder < Base
4
4
  def command
5
- open_with_default path
5
+ run path, :default_open
6
6
  end
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -2,7 +2,9 @@ module Workon
2
2
  module Actor
3
3
  class Guard < Base
4
4
  def command
5
- screen bundle_command("guard --clear") if has_guardfile?
5
+ return unless has_guardfile?
6
+
7
+ mux 'guard --clear', :bundler
6
8
  end
7
9
 
8
10
  private
@@ -4,38 +4,44 @@ module Workon
4
4
  option('--server SERVER', 'Use this server (auto,middleman,passenger,pow,unicorn)') { |v| options[:server] = v}
5
5
  before :WebBrowser
6
6
 
7
- def commit
7
+ def command
8
8
  actual = fetch_option :server, 'auto'
9
9
  valid = %w(auto middleman passenger pow unicorn)
10
10
 
11
11
  return unless valid.include? actual
12
- send :"commit_for_#{actual}"
12
+ send :"command_for_#{actual}"
13
13
  end
14
14
 
15
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')
16
+ def command_for_auto
17
+ command_for_unicorn and return if project_has_one_of?('unicorn.rb', 'config/unicorn.rb')
18
+ command_for_passenger and return if project_has_file?('config.ru') && has_command?('passenger')
19
19
  end
20
20
 
21
- def commit_for_passenger
22
- port = fetch_option :port, 3000
23
- screen bundle_command("passenger start --port #{port}")
21
+ def command_for_passenger
22
+ bundled_server "passenger start --port %{port}", 3000
24
23
  end
25
24
 
26
- def commit_for_middleman
27
- port = fetch_option :port, 4567
28
- screen bundle_command("mm-server --port #{port}")
25
+ def command_for_middleman
26
+ bundled_server "mm-server --port %{port}", 4567
29
27
  end
30
28
 
31
- def commit_for_pow
29
+ def command_for_pow
32
30
  options[:port] = nil
33
31
  options[:host] = "#{project}.dev"
32
+
33
+ nil
34
+ end
35
+
36
+ def command_for_unicorn
37
+ bundled_server 'unicorn_rails -c config/unicorn-rb', 8080
34
38
  end
35
39
 
36
- def commit_for_unicorn
37
- port = fetch_option :port, 8080
38
- screen bundle_command("unicorn_rails -c #{path}/config/unicorn.rb -l #{port}")
40
+ def bundled_server(command, port, new_host = 'localhost')
41
+ options[:host] = new_host
42
+ new_port = fetch_option :port, port
43
+
44
+ mux command % { port: port }, :bundler
39
45
  end
40
46
  end
41
47
  end
@@ -6,7 +6,7 @@ module Workon
6
6
  end
7
7
 
8
8
  def command
9
- screen "watchr" if watchr_file_exists?
9
+ mux "watchr" if watchr_file_exists?
10
10
  end
11
11
  end
12
12
  end
@@ -1,27 +1,15 @@
1
1
  module Workon
2
2
  module Actor
3
3
  class WebBrowser < Base
4
- option('--host HOST', 'Ping this host') { |v| options[:host] = v}
5
- option('--port PORT', Integer, 'Use this port for Middleman/Passenger') { |v| options[:port] = v}
4
+ option('--host HOST', 'Open host in your default browser') { |v| options[:host] = v}
5
+ option('--port PORT', Integer, 'Use this port for the webserver') { |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
+ qualified = [ host_name, port_number ].compact.join ':'
10
11
 
11
- command, qualified = port_number.nil? ? ping_test(host_name) : netstat_test(port_number)
12
- opener = open_with_default "http://#{qualified}"
13
- %(#{command} && #{opener})
14
- end
15
-
16
- private
17
- def ping_test(host_name)
18
- command = %{ping -q -c 1 -t 1 #{host_name}}
19
- [ command, host_name ]
20
- end
21
-
22
- def netstat_test(port)
23
- command = %{sleep 3 && netstat -na | egrep 'tcp4*6* +([0-9]+ +){2}(\\*|([0-9]+\\.)+[0-9]+)(:|\\.)#{port}'}
24
- [ command, "localhost:#{port}" ]
12
+ default_open "http://#{qualified}"
25
13
  end
26
14
  end
27
15
  end
@@ -25,7 +25,7 @@ module Workon
25
25
  end
26
26
 
27
27
  def self.execute
28
- Workon.config.merge_options ARGV
28
+ Workon.config.merge_options cli_options
29
29
  @config = Workon.config
30
30
 
31
31
  show_help if @config[:show_help]
@@ -40,5 +40,9 @@ module Workon
40
40
 
41
41
  Workon.commit!
42
42
  end
43
+
44
+ def self.cli_options
45
+ ARGV
46
+ end
43
47
  end
44
48
  end
@@ -0,0 +1,76 @@
1
+ module Workon
2
+ class Command
3
+ autoload :Wrappers, 'workon/command/wrappers'
4
+
5
+ include Wrappers
6
+
7
+ BANNERS = {
8
+ running: 'Running %s',
9
+ screening: 'Screening %s'
10
+ }.freeze
11
+
12
+ def initialize(command, env = {})
13
+ @command = command
14
+ @env = env
15
+
16
+ extract_options
17
+ end
18
+
19
+ def extract_options
20
+ @banner = @env.delete :banner
21
+ @mux_window = @env.delete :mux_window
22
+ end
23
+
24
+ def env
25
+ @env.inject({}) do |memo, (key, value)|
26
+ memo[key.to_s] = value
27
+ memo
28
+ end
29
+ end
30
+
31
+ def update_env(new_env = {})
32
+ @env.merge! new_env
33
+ extract_options
34
+ self
35
+ end
36
+
37
+ def expanded_env
38
+ return if @env.empty?
39
+
40
+ @env.inject('') do |memo, (key, value)|
41
+ memo << "#{key.to_s.chomp}=#{value.to_s.chomp}"
42
+ end
43
+ end
44
+
45
+ def to_run
46
+ @command
47
+ end
48
+
49
+ def wrap!(wrapper)
50
+ if Symbol === wrapper
51
+ wrap_method = :"wrap_for_#{wrapper}"
52
+ raise ArgumentError, "#{self} cannot wrap for #{wrapper}" unless respond_to? wrap_method
53
+
54
+ wrapper = send wrap_method
55
+ end
56
+
57
+ @command = wrapper % @command
58
+ self
59
+ end
60
+
61
+ def run
62
+ display_banner
63
+ Kernel.system env, @command unless Workon.config[:dry_run]
64
+ end
65
+
66
+ def capture
67
+ display_banner
68
+ _cmd = [ expanded_env, @command ].compact.join ';'
69
+ %x(#{_cmd}) unless Workon.config[:dry_run]
70
+ end
71
+
72
+ def display_banner(banner = BANNERS[:running])
73
+ puts (@banner || banner) % @command
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,65 @@
1
+ module Workon::Command::Wrappers
2
+ include Workon::Helpers::Assertable
3
+
4
+ @@default_open = nil
5
+ @@tmux_initialized = false
6
+
7
+ def wrap_for_bundler
8
+ 'bundle exec %s'
9
+ end
10
+
11
+ def wrap_for_default_open
12
+ @@default_open ||= has_command?('xdg-open') ? 'xdg-open %s' : 'open %s'
13
+ end
14
+
15
+ def wrap_for_rvm
16
+ project_has_file?('.rvmrc') ? "rvm --with-rubies default-with-rvmrc exec %s" : '%s'
17
+ end
18
+
19
+ def wrap_for_mux
20
+ $has_tmux ||= has_command? 'tmux'
21
+ wrap! :rvm
22
+
23
+ $has_tmux ? _tmux : _screen
24
+ end
25
+
26
+ def _screen
27
+ identifier = mux_scope
28
+
29
+ puts %(Reconnect with `screen -r #{identifier}')
30
+ %(screen -dmS #{identifier} %s)
31
+ end
32
+
33
+ def _tmux
34
+ initialize_tmux
35
+
36
+ %(tmux attach-session -t #{mux_session} \\; new-window -d -n #{mux_window} '%s' \\; detach-client)
37
+ end
38
+
39
+ def initialize_tmux
40
+ return if @@tmux_initialized
41
+
42
+ tmux_commands = [
43
+ "new-session -s #{mux_session}",
44
+ "set-option -t #{mux_session} set-remain-on-exit on",
45
+ "detach-client"
46
+ ].join ' \; '
47
+
48
+ initializer = Workon::Command.new "tmux #{tmux_commands}"#, banner: 'Initializing tmux session ...'
49
+ initializer.run
50
+
51
+ @@tmux_initialized = true
52
+ end
53
+
54
+ def mux_scope
55
+ [ mux_session, mux_window ].join '.'
56
+ end
57
+
58
+ def mux_session
59
+ Workon.project_name.downcase
60
+ end
61
+
62
+ def mux_window
63
+ @mux_window.downcase
64
+ end
65
+ end
@@ -6,7 +6,7 @@ module Workon
6
6
  attr_reader :options
7
7
  attr_reader :parser
8
8
 
9
- def initialize(options = nil)
9
+ def initialize(_options = nil)
10
10
  @options = {
11
11
  show_project: false,
12
12
  without: [],
@@ -17,7 +17,7 @@ module Workon
17
17
  show_help: false
18
18
  }
19
19
 
20
- merge_options options unless blank? options
20
+ merge_options _options unless blank? _options
21
21
  end
22
22
 
23
23
  def merge_options(args)
@@ -86,7 +86,7 @@ module Workon
86
86
  end
87
87
 
88
88
  o.on_tail('-v', '--version', 'Show version information') do
89
- puts Workon::VERSION
89
+ puts Workon::Version::STRING
90
90
  exit
91
91
  end
92
92
 
@@ -0,0 +1,5 @@
1
+ module Workon::Helpers
2
+ autoload :Assertable, 'workon/helpers/assertable'
3
+ autoload :Commandable, 'workon/helpers/commandable'
4
+ autoload :Configurable, 'workon/helpers/configurable'
5
+ end
@@ -0,0 +1,17 @@
1
+ module Workon::Helpers::Assertable
2
+ def has_command?(command)
3
+ !`command -v '#{command}'`.empty?
4
+ end
5
+
6
+ def project_has_file?(file)
7
+ !Dir[file].empty?
8
+ end
9
+
10
+ def project_has_one_of?(*files)
11
+ files.any? { |f| project_has_file? f }
12
+ end
13
+
14
+ def project_has_folder?(folder)
15
+ File.directory? folder
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ module Workon::Helpers::Commandable
2
+ def run(command, *wrappers)
3
+ interpret_command(command, *wrappers)
4
+ end
5
+
6
+ def mux(command, *wrappers)
7
+ wrappers, env = wrappers_and_env(wrappers)
8
+ env[:mux_window] = env.delete(:mux_window) || self.class.actor_name
9
+
10
+ interpret_command(command, *wrappers, env).wrap!(:mux)
11
+ end
12
+
13
+ def default_open(command, *wrappers)
14
+ interpret_command(command, *wrappers).wrap!(:default_open)
15
+ end
16
+
17
+ private
18
+ def interpret_command(command, *wrappers)
19
+ wrappers, env = wrappers_and_env wrappers
20
+ command = Workon::Command === command ? command : Workon::Command.new(command)
21
+
22
+ command.update_env env
23
+ wrappers.each do |wrapper|
24
+ command.wrap! wrapper
25
+ end
26
+
27
+ command
28
+ end
29
+
30
+ def wrappers_and_env(wrappers)
31
+ env = Hash === wrappers.last ? wrappers.pop : Hash.new
32
+
33
+ [ wrappers, env ]
34
+ end
35
+ end
@@ -1,4 +1,4 @@
1
- module Workon::Actor::Helpers::Configurable
1
+ module Workon::Helpers::Configurable
2
2
  module ClassMethods
3
3
  def option(*args, &block)
4
4
  Workon.config.parser.on(*args) do |v|
@@ -26,7 +26,7 @@ module Workon::Actor::Helpers::Configurable
26
26
  end
27
27
 
28
28
  def self.included(receiver)
29
- receiver.extend ClassMethods
30
- receiver.send :include, InstanceMethods
29
+ receiver.extend ClassMethods
30
+ receiver.send :include, InstanceMethods
31
31
  end
32
32
  end
@@ -7,5 +7,17 @@ module Workon
7
7
  subject.stub(:project_rc_exists?).and_return true
8
8
  subject.stub(:project_rc_path).and_return fixture_path
9
9
  end
10
+
11
+ def stub_directories!(dirs = %w(/code/foo /code/bar))
12
+ Workon.stub(:all_directories) { dirs }
13
+ end
14
+
15
+ def clear_workon_config!
16
+ Workon.instance_eval { @config = nil }
17
+ end
18
+
19
+ def disable_banners!
20
+ STDOUT.stub :puts
21
+ end
10
22
  end
11
23
  end
@@ -1,3 +1,8 @@
1
1
  module Workon
2
- VERSION = "0.0.15"
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ STRING = [ MAJOR, MINOR, PATCH ].join '.'
7
+ end
3
8
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ class ActorBase < Workon::Actor::Base
4
+ def command; nil; end
5
+ end
6
+
7
+ describe ActorBase do
8
+ subject { described_class.new '/code/foo' }
9
+
10
+ it "has shorthands for running commands" do
11
+ subject.run('date').should be_a(Workon::Command)
12
+ end
13
+
14
+ it "has a shorthand for wrapping" do
15
+ command = Workon::Command.new 'date'
16
+ command.should_receive(:wrap!).with(:bundler).ordered
17
+ command.should_receive(:wrap!).with(:rvm).ordered
18
+
19
+ subject.run command, :bundler, :rvm, banner: 'test banner'
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Workon::Actor::Finder do
4
+ before { disable_banners! }
5
+ let(:project_dir) { '/code/foo' }
6
+ subject { described_class.new project_dir }
7
+
8
+ it 'lets you browse your project' do
9
+ Kernel.should_receive(:system).with Hash.new, 'open /code/foo'
10
+ subject.commit
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Workon::Actor::Guard do
4
+ before { disable_banners! }
5
+ subject { described_class.new '/code/foo' }
6
+
7
+ it 'runs when ./Guardfile exists' do
8
+ Workon::Command.any_instance.stub(:mux_session).and_return 'foo'
9
+ Workon.config.merge_options dry_run: true
10
+ subject.should_receive(:has_guardfile?).and_return true
11
+ subject.command.to_run.should =~ /guard/
12
+ end
13
+
14
+ it 'does nothing otherwise' do
15
+ Workon.config.merge_options dry_run: true
16
+ subject.should_receive(:has_guardfile?).and_return false
17
+ subject.command.should be_nil
18
+ end
19
+ end
@@ -5,6 +5,6 @@ describe Workon::Actor::Server do
5
5
  subject { described_class.new '/Users/mike/Work/ruby/henceforth' }
6
6
 
7
7
  it "works?" do
8
- subject.commit
8
+ # subject.commit
9
9
  end
10
10
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Workon::Actor::Watchr do
4
+ before { disable_banners! }
5
+ subject { described_class.new '/code/foo' }
6
+
7
+ it 'runs when *.watchr exists' do
8
+ Workon.config.merge_options dry_run: true
9
+ subject.should_receive(:watchr_file_exists?).and_return true
10
+ Workon.stub(:project_name).and_return 'foo'
11
+ subject.command.to_run.should =~ /watchr/
12
+ end
13
+
14
+ it 'does nothing otherwise' do
15
+ Workon.config.merge_options dry_run: true
16
+ subject.should_receive(:watchr_file_exists?).and_return false
17
+ subject.command.should be_nil
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Workon::Actor::WebBrowser do
4
+ subject { described_class.new Workon.project_path }
5
+
6
+ it "simply opens the URL" do
7
+ host = 'somehost'
8
+ port = 3000
9
+
10
+ Workon.config[:host] = host
11
+ Workon.config[:port] = port
12
+
13
+ subject.command.to_run.should == "open http://#{host}:#{port}"
14
+ end
15
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'workon/cli'
3
3
 
4
4
  describe Workon::CLI do
5
- before(:each) { Workon.instance_eval { @config = nil } }
5
+ before(:each) { clear_workon_config! }
6
6
 
7
7
  it "shows help when asked" do
8
8
  Workon.config show_help: true
@@ -27,4 +27,10 @@ describe Workon::CLI do
27
27
  described_class.should_receive(:dump_configuration).and_return { exit }
28
28
  expect { described_class.execute }.to raise_error SystemExit
29
29
  end
30
+
31
+ it "fails without a project" do
32
+ described_class.stub(:cli_options).and_return []
33
+ Workon.config.merge_options project: nil
34
+ expect { described_class.execute }.to raise_error OptionParser::MissingArgument
35
+ end
30
36
  end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Workon::Command do
4
+ before { disable_banners! }
5
+
6
+ it "runs a command" do
7
+ cmd = described_class.new 'date'
8
+ Kernel.should_receive(:system).with({}, 'date')
9
+ cmd.run
10
+ end
11
+
12
+ it "displays a banner" do
13
+ cmd = 'date'
14
+ banner = 'foo'
15
+ command = described_class.new cmd, banner: banner
16
+
17
+ STDOUT.should_receive(:puts).with(banner)
18
+ Kernel.should_receive :system
19
+
20
+ command.run
21
+ end
22
+
23
+ it "can capture commands" do
24
+ string = 'foo'
25
+ command = described_class.new "echo #{string}"
26
+
27
+ command.capture.chomp.should == string
28
+ end
29
+
30
+ it "can wrap itself for bundler, etc" do
31
+ command = described_class.new "date"
32
+ Kernel.should_receive(:system).with Hash.new, 'bar foo date'
33
+
34
+ command.wrap!('foo %s').wrap! 'bar %s'
35
+ command.run
36
+ end
37
+
38
+ it 'knows to wrap using a method when symbol passed' do
39
+ command = described_class.new 'date'
40
+ Kernel.should_receive(:system).with Hash.new, 'bundle exec date'
41
+
42
+ command.wrap! :bundler
43
+ command.run
44
+ end
45
+
46
+ describe "sets the ENV" do
47
+ let(:sample_env) { { foo: 'bar' } }
48
+ subject { described_class.new 'echo $foo', sample_env }
49
+
50
+ it "stringifies the ENVs keys" do
51
+ subject.env['foo'].should == sample_env[:foo]
52
+ end
53
+
54
+ it "expands ENV for when hash not applicable" do
55
+ subject.expanded_env.should == 'foo=bar'
56
+ end
57
+
58
+ it "accepts an ENV hash" do
59
+ subject.capture.chomp.should == sample_env[:foo]
60
+ end
61
+ end
62
+ end
@@ -2,10 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe Workon do
4
4
  before do
5
- Workon.stub(:all_directories) { %w(/code/foo /code/bar) }
5
+ stub_directories!
6
+ disable_banners!
6
7
  end
7
8
 
8
- before(:each) { Workon.instance_eval { @config = nil } }
9
+ before(:each) { clear_workon_config! }
9
10
 
10
11
  it "finds a project" do
11
12
  Workon.config[:project] = 'foo'
@@ -28,7 +29,7 @@ describe Workon do
28
29
  it "ignores things in --without" do
29
30
  Dir.stub(:chdir).with(Workon.project_path)
30
31
  Workon::Actor::Server.should_not_receive :new
31
- Workon.config project: 'foo', without: 'Server', dry_run: true
32
+ Workon.config project: 'foo', without: ['Server'], dry_run: true
32
33
  Workon.find_project
33
34
  Workon.commit!
34
35
  end
@@ -4,20 +4,20 @@ require "workon/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "workon"
7
- s.version = Workon::VERSION
7
+ s.version = Workon::Version::STRING
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Mike Wyatt"]
10
10
  s.email = ["wyatt.mike@gmail.com"]
11
11
  s.homepage = ""
12
12
  s.summary = %q{Runs actions based on directories}
13
13
  s.description = %q{Runs actions based on directories}
14
-
15
- # s.add_dependency "activesupport"
14
+
15
+ s.add_dependency "rake"
16
16
  s.add_development_dependency "rspec"
17
17
  s.add_development_dependency "guard"
18
18
  s.add_development_dependency "guard-rspec"
19
19
  s.add_development_dependency "rb-fsevent" if RUBY_PLATFORM =~ /darwin/
20
-
20
+
21
21
  s.rubyforge_project = "workon"
22
22
 
23
23
  s.files = `git ls-files`.split("\n")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-24 00:00:00.000000000 -02:30
12
+ date: 2011-09-08 00:00:00.000000000 -02:30
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: &70158795306580 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70158795306580
15
26
  - !ruby/object:Gem::Dependency
16
27
  name: rspec
17
- requirement: &70248633807960 !ruby/object:Gem::Requirement
28
+ requirement: &70158795305980 !ruby/object:Gem::Requirement
18
29
  none: false
19
30
  requirements:
20
31
  - - ! '>='
@@ -22,10 +33,10 @@ dependencies:
22
33
  version: '0'
23
34
  type: :development
24
35
  prerelease: false
25
- version_requirements: *70248633807960
36
+ version_requirements: *70158795305980
26
37
  - !ruby/object:Gem::Dependency
27
38
  name: guard
28
- requirement: &70248633807540 !ruby/object:Gem::Requirement
39
+ requirement: &70158795305320 !ruby/object:Gem::Requirement
29
40
  none: false
30
41
  requirements:
31
42
  - - ! '>='
@@ -33,10 +44,10 @@ dependencies:
33
44
  version: '0'
34
45
  type: :development
35
46
  prerelease: false
36
- version_requirements: *70248633807540
47
+ version_requirements: *70158795305320
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: guard-rspec
39
- requirement: &70248633807120 !ruby/object:Gem::Requirement
50
+ requirement: &70158795304440 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ! '>='
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: '0'
45
56
  type: :development
46
57
  prerelease: false
47
- version_requirements: *70248633807120
58
+ version_requirements: *70158795304440
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: rb-fsevent
50
- requirement: &70248633806660 !ruby/object:Gem::Requirement
61
+ requirement: &70158795303280 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ! '>='
@@ -55,7 +66,7 @@ dependencies:
55
66
  version: '0'
56
67
  type: :development
57
68
  prerelease: false
58
- version_requirements: *70248633806660
69
+ version_requirements: *70158795303280
59
70
  description: Runs actions based on directories
60
71
  email:
61
72
  - wyatt.mike@gmail.com
@@ -68,7 +79,7 @@ files:
68
79
  - .rvmrc
69
80
  - Gemfile
70
81
  - Guardfile
71
- - README.md
82
+ - README.markdown
72
83
  - Rakefile
73
84
  - bin/workon
74
85
  - lib/workon.rb
@@ -78,25 +89,29 @@ files:
78
89
  - lib/workon/actor/finder.rb
79
90
  - lib/workon/actor/git.rb
80
91
  - 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
86
- - lib/workon/actor/middleman.rb
87
- - lib/workon/actor/passenger.rb
88
92
  - lib/workon/actor/server.rb
89
- - lib/workon/actor/unicorn.rb
90
93
  - lib/workon/actor/watchr.rb
91
94
  - lib/workon/actor/web_browser.rb
92
95
  - lib/workon/cli.rb
93
96
  - lib/workon/cli/commands.rb
97
+ - lib/workon/command.rb
98
+ - lib/workon/command/wrappers.rb
94
99
  - lib/workon/configuration.rb
100
+ - lib/workon/helpers.rb
101
+ - lib/workon/helpers/assertable.rb
102
+ - lib/workon/helpers/commandable.rb
103
+ - lib/workon/helpers/configurable.rb
95
104
  - lib/workon/rspec_helpers.rb
96
105
  - lib/workon/version.rb
97
106
  - spec/fixtures/projectrc.yml
107
+ - spec/lib/workon/actor/base_spec.rb
108
+ - spec/lib/workon/actor/finder_spec.rb
109
+ - spec/lib/workon/actor/guard_spec.rb
98
110
  - spec/lib/workon/actor/server_spec.rb
111
+ - spec/lib/workon/actor/watchr_spec.rb
112
+ - spec/lib/workon/actor/web_browser_spec.rb
99
113
  - spec/lib/workon/cli_spec.rb
114
+ - spec/lib/workon/command_spec.rb
100
115
  - spec/lib/workon/configuration_spec.rb
101
116
  - spec/lib/workon_spec.rb
102
117
  - spec/spec_helper.rb
@@ -114,12 +129,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
129
  - - ! '>='
115
130
  - !ruby/object:Gem::Version
116
131
  version: '0'
132
+ segments:
133
+ - 0
134
+ hash: 1771416793962210850
117
135
  required_rubygems_version: !ruby/object:Gem::Requirement
118
136
  none: false
119
137
  requirements:
120
138
  - - ! '>='
121
139
  - !ruby/object:Gem::Version
122
140
  version: '0'
141
+ segments:
142
+ - 0
143
+ hash: 1771416793962210850
123
144
  requirements: []
124
145
  rubyforge_project: workon
125
146
  rubygems_version: 1.6.2
@@ -128,8 +149,14 @@ specification_version: 3
128
149
  summary: Runs actions based on directories
129
150
  test_files:
130
151
  - spec/fixtures/projectrc.yml
152
+ - spec/lib/workon/actor/base_spec.rb
153
+ - spec/lib/workon/actor/finder_spec.rb
154
+ - spec/lib/workon/actor/guard_spec.rb
131
155
  - spec/lib/workon/actor/server_spec.rb
156
+ - spec/lib/workon/actor/watchr_spec.rb
157
+ - spec/lib/workon/actor/web_browser_spec.rb
132
158
  - spec/lib/workon/cli_spec.rb
159
+ - spec/lib/workon/command_spec.rb
133
160
  - spec/lib/workon/configuration_spec.rb
134
161
  - spec/lib/workon_spec.rb
135
162
  - spec/spec_helper.rb
data/README.md DELETED
@@ -1,27 +0,0 @@
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 ...
@@ -1,10 +0,0 @@
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
@@ -1,9 +0,0 @@
1
- module Workon::Actor::Helpers::Bundler
2
- def bundle_command(command)
3
- project_uses_bundler? ? "bundle exec #{command}" : command
4
- end
5
-
6
- def project_uses_bundler?
7
- $project_uses_bundler ||= File.exists? './Gemfile'
8
- end
9
- end
@@ -1,16 +0,0 @@
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
@@ -1,45 +0,0 @@
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
@@ -1,15 +0,0 @@
1
- module Workon
2
- module Actor
3
- class Middleman < Base
4
- before :WebBrowser
5
- option('--middleman', 'Start mm-server') { |v| options[:middleman] = true }
6
-
7
- def commit
8
- if fetch_option :middleman, false
9
- port = fetch_option :port, 4567
10
- screen bundle_command("mm-server --port #{port}")
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,22 +0,0 @@
1
- module Workon
2
- module Actor
3
- class Passenger < Base
4
- before :WebBrowser
5
-
6
- def is_rack_app?
7
- project_has_file? 'config.ru'
8
- end
9
-
10
- def passenger_standalone_available?
11
- has_command? 'passenger'
12
- end
13
-
14
- def commit
15
- if is_rack_app? && passenger_standalone_available?
16
- port = fetch_option :port, 3000
17
- screen bundle_command("passenger start --port #{port}")
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,19 +0,0 @@
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
-