workon 0.0.15 → 0.1.0

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.
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
-