work-on 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,39 @@
1
1
  = work-on
2
2
 
3
- Description goes here.
4
-
5
- == Contributing to work-on
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
- * Fork the project
10
- * Start a feature/bugfix branch
11
- * Commit and push until you are happy with your contribution
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
3
+ A utility to manage your projects and make working on them as seemless as possible.
4
+ Basically you edit a small yaml file where you specify your project directory and the terminal windows and tabs
5
+ you want to open.
6
+
7
+ = Example
8
+
9
+ this is the actual config file i use for work-on:
10
+
11
+ work-on:
12
+ project-dir: ~/Projects/work-on
13
+ tab1:
14
+ - git status
15
+ tab2:
16
+ - mvim
17
+
18
+ this opens 2 new tabs and executes above commands
19
+ you can also open new windows
20
+
21
+ work-on:
22
+ project-dir: ~/Projects/work-on
23
+ window1:
24
+ tab1:
25
+ - ls
26
+ tab2:
27
+ - git status
28
+ window2:
29
+ tab1:
30
+ - mvim
31
+
32
+ You can guess what the above would do.
33
+
34
+ NOTE: At the moment only Mac OS X is supported, but support for linux is coming real soon.
35
+
36
+ = Copyright
16
37
 
17
38
  Copyright (c) 2011 Toon Willems. See LICENSE.txt for
18
39
  further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.1.0
@@ -3,7 +3,7 @@ module WorkOn
3
3
  autoload :AbstractTerminal , 'work_on/terminal.rb'
4
4
  autoload :MacTerminal , 'work_on/terminals/mac_terminal.rb'
5
5
  autoload :Config , 'work_on/config.rb'
6
+ autoload :YAMLConfig , 'work_on/config.rb'
6
7
  autoload :Project , 'work_on/project.rb'
7
8
  autoload :Cli , 'work_on/cli.rb'
8
-
9
9
  end
@@ -5,7 +5,7 @@ module WorkOn
5
5
 
6
6
  desc "start PROJECT", "start working on the given project"
7
7
  def start(project_name)
8
- Config.default[project_name].work!
8
+ Project.new(Config.new(project_name)).work!
9
9
  end
10
10
 
11
11
  # use method_missing to start the project
@@ -1,30 +1,93 @@
1
1
  require 'yaml'
2
+ require 'abstract'
2
3
 
3
4
  module WorkOn
4
5
 
5
6
  class Config
6
7
 
7
- def self.default
8
- @default ||= Config.new(File.expand_path '~/.config/work_on')
8
+ def self.default_dir
9
+ File.expand_path '~/.config/work-on/'
9
10
  end
10
11
 
11
- attr_reader :file_name
12
+ def initialize(project_name)
13
+ file_name = find_file(project_name)
14
+ raise "No config file found" unless file_name
15
+ @config = find_config(file_name)
16
+ end
17
+
18
+ def windows
19
+ @config.windows
20
+ end
21
+
22
+ def project_dir
23
+ @config.project_dir
24
+ end
25
+
26
+ private
27
+
28
+ def find_config(file_name)
29
+ case File.extname(file_name)
30
+ when ".rb", ""
31
+ DSLConfig.new(file_name)
32
+ when ".yml", ".yaml"
33
+ YAMLConfig.new(file_name)
34
+ else
35
+ raise "Don't know how to parse #{file_name}"
36
+ end
37
+ end
38
+
39
+ def find_file(name)
40
+ base_name = File.join(self.class.default_dir, name)
41
+ files = Dir.glob(base_name + '.*')
42
+ # pick the first one
43
+ files.first
44
+ end
45
+
46
+ end
47
+
48
+ class ConfigParser
49
+
50
+ # windows is an hash which looks like this
51
+ # {:tabs => [['ls -al', 'ls'], ['ls']]}
52
+ # the above hash would open 2 tabs
53
+ #
54
+ # if additional windows need to be opened
55
+ # you can specify the windows key (and provide and array of tab
56
+ # hashes)
57
+ # {:windows => {[{:tabs => []}, {:tabs =>[]}]}}
58
+ attr_accessor :windows
59
+
60
+ # should be set to the complete and expanded path to the project
61
+ attr_reader :project_dir
12
62
 
13
63
  def initialize(file_name)
14
- self.file_name = file_name
64
+ @windows = {}
65
+ parse(file_name)
15
66
  end
16
67
 
17
- def file_name=(file_name)
18
- @file_name = file_name
19
- @hash = YAML.load_file file_name
68
+ # It does no harm to expand a path multiple times and prevents somebody from forgetting it
69
+ def project_dir=(dir)
70
+ @project_dir = File.expand_path(dir)
20
71
  end
21
72
 
22
- def [](project)
23
- config = @hash[project]
24
- raise ArgumentError, "No config found for that project" unless config
25
- Project.new project, config
73
+ # this method should read and parse the file
74
+ # will be called when initialized
75
+ # implementations should set @windows and @project_dir
76
+ def parse(file_name)
77
+ not_implemented
26
78
  end
79
+ end
27
80
 
81
+ class YAMLConfig < ConfigParser
82
+ def parse(file_name)
83
+ hash = YAML.load_file(file_name)
84
+ self.project_dir = hash['project-dir']
85
+
86
+ windows = hash.select {|k,v| /window/ === k}
87
+ tabs = hash.select {|k,v| /tab/ === k}
88
+ self.windows[:tabs] = tabs.values
89
+ self.windows[:windows] = windows.values.map {|hash| {:tabs => hash.values}}
90
+ end
28
91
  end
29
92
 
30
93
  end
@@ -2,13 +2,15 @@ module WorkOn
2
2
 
3
3
  class Project
4
4
 
5
- def initialize(name, config)
6
- @name = name
5
+ def initialize(config)
7
6
  @config = config
8
- @project_dir = @config['project-dir']
9
7
  @terminal = Terminal.instance
10
8
  end
11
9
 
10
+ def project_dir
11
+ @config.project_dir
12
+ end
13
+
12
14
  # Start working on this project
13
15
  def work!
14
16
  initialize_windows
@@ -18,16 +20,13 @@ module WorkOn
18
20
 
19
21
  # Sets up the terminal according the config file
20
22
  def initialize_windows
21
- windows = @config.select {|k,v| /window/ === k }
22
- # if there is no window specified, i will assume the users wants to open the tabs in the current
23
- # terminal window
24
- if windows.empty?
25
- tabs = @config.select {|k,v| /tab/ === k }
26
- create_tabs(@terminal.selected_window, tabs, false)
27
- else
28
- windows.each do |window, tabs_hash|
29
- create_window(tabs_hash)
30
- end
23
+ # first create the tabs
24
+ tabs = @config.windows[:tabs]
25
+ create_tabs(@terminal.selected_window, tabs, false)
26
+
27
+ # then the windows
28
+ @config.windows[:windows].each do |tabs_hash|
29
+ create_window(tabs_hash[:tabs])
31
30
  end
32
31
  end
33
32
 
@@ -37,10 +36,10 @@ module WorkOn
37
36
  create_tabs(window, tabs)
38
37
  end
39
38
 
40
- def create_tabs(window, hash, use_current = true)
39
+ def create_tabs(window, array, use_current = true)
41
40
  # create as many tabs as needed
42
41
  # if use_current is true, create one less and use the current one
43
- count = hash.keys.size
42
+ count = array.size
44
43
  if use_current
45
44
  count -= 1
46
45
  first_tab = window.selected_tab
@@ -48,8 +47,8 @@ module WorkOn
48
47
  tabs = count.times.map { window.new_tab }
49
48
  tabs.unshift first_tab if use_current
50
49
 
51
- hash.values.each.with_index do |commands, i|
52
- tabs[i].execute "cd #{@project_dir}"
50
+ array.each.with_index do |commands, i|
51
+ tabs[i].execute "cd #{project_dir}"
53
52
  commands.each do |command|
54
53
  tabs[i].execute(command)
55
54
  end
@@ -1,17 +1,50 @@
1
1
  require 'teststrap'
2
2
  require 'yaml' # otherwise mock fails
3
3
 
4
- context "Config" do
4
+ context "YAMLConfig" do
5
+ helper(:basic_config) do
6
+ {"project-dir"=>"~/Projects/work-on", "window1"=>{"tab1"=>["rails server"], "tab2"=>["rails console"], "tab3"=>["git status", "mvim"]}}
7
+ end
5
8
  setup do
6
- mock(YAML).load_file("test_name") do
7
- {'test' => {'project-dir' => 'test-dir'}}
8
- end
9
- WorkOn::Config.new("test_name")
9
+ mock(YAML).load_file("test_name.yml") { basic_config }
10
+ WorkOn::YAMLConfig.new("test_name.yml")
11
+ end
12
+
13
+ asserts(:project_dir).equals(Dir.home + "/Projects/work-on")
14
+
15
+ context "windows hash" do
16
+ setup { topic.windows[:windows] }
17
+ asserts(:first).equals({:tabs => [['rails server'], ['rails console'], ['git status', 'mvim']]})
10
18
  end
11
19
 
12
- denies(:[], 'test').nil
13
- asserts_topic.assigns(:file_name)
20
+ context 'with multiple windows' do
21
+ helper(:complex_config) do
22
+ {"project-dir"=>"~/Projects/work-on",
23
+ "window1"=>{"tab1"=>["rails server"], "tab2"=>["rails console"], "tab3"=>["git status", "mvim"]},
24
+ "window2"=>{"tab1"=>["rails server"], "tab2"=>["rails console"], "tab3"=>["git status", "mvim"]},
25
+ "tab1"=>["rails server"], "tab2"=>["rails console"], "tab3"=>["git status", "mvim"]
26
+ }
27
+ end
28
+ setup do
29
+ mock(YAML).load_file("test_name.yml") { complex_config }
30
+ WorkOn::YAMLConfig.new("test_name.yml")
31
+ end
32
+
33
+ asserts(:project_dir).equals(Dir.home + "/Projects/work-on")
14
34
 
15
- asserts(:[], 'blah').raises(ArgumentError)
35
+ context "window hash" do
36
+ setup { topic.windows[:windows] }
16
37
 
38
+ asserts(:first).equals({:tabs => [['rails server'], ['rails console'], ['git status', 'mvim']]})
39
+ asserts("both windows have the same config") { topic.first == topic.last }
40
+
41
+ end
42
+
43
+ context "tab hash" do
44
+ setup { topic.windows[:tabs] }
45
+
46
+ asserts_topic.equals([['rails server'], ['rails console'], ['git status', 'mvim']])
47
+ end
48
+
49
+ end
17
50
  end
@@ -1,12 +1,17 @@
1
+ require 'yaml'
2
+
1
3
  context "Project" do
2
- helper(:config_hash) do
3
- {'project-dir' => '~/test',
4
- 'tab1' => [],
5
- 'tab2' => []
6
- }
4
+ helper(:config) do
5
+ mock(YAML).load_file('test.yml') do
6
+ {'project-dir' => '~/test',
7
+ 'tab1' => [],
8
+ 'tab2' => []
9
+ }
10
+ end
11
+ WorkOn::YAMLConfig.new('test.yml')
7
12
  end
8
13
 
9
- setup { WorkOn::Project.new 'test', config_hash }
14
+ setup { WorkOn::Project.new config }
10
15
 
11
16
  hookup do
12
17
  terminal = stub(WorkOn::Terminal.instance)
@@ -15,6 +20,6 @@ context "Project" do
15
20
  topic.work!
16
21
  end
17
22
 
18
- asserts_topic.assigns(:project_dir, '~/test')
23
+ asserts(:project_dir).equals(Dir.home + '/test')
19
24
 
20
25
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{work-on}
8
- s.version = "0.0.2"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Toon Willems}]
12
- s.date = %q{2011-09-19}
12
+ s.date = %q{2011-09-20}
13
13
  s.description = %q{utility to manage projects and the terminal windows you open when you work on them.}
14
14
  s.email = %q{willemstoon@gmail.com}
15
15
  s.executables = [%q{work-on}]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: work-on
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-19 00:00:00.000000000Z
12
+ date: 2011-09-20 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: abstract
16
- requirement: &70327813960780 !ruby/object:Gem::Requirement
16
+ requirement: &70198776254500 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70327813960780
24
+ version_requirements: *70198776254500
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rb-appscript
27
- requirement: &70327813960020 !ruby/object:Gem::Requirement
27
+ requirement: &70198776252800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70327813960020
35
+ version_requirements: *70198776252800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: riot
38
- requirement: &70327813959420 !ruby/object:Gem::Requirement
38
+ requirement: &70198776251720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70327813959420
46
+ version_requirements: *70198776251720
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70327813958520 !ruby/object:Gem::Requirement
49
+ requirement: &70198776234500 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70327813958520
57
+ version_requirements: *70198776234500
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &70327813957680 !ruby/object:Gem::Requirement
60
+ requirement: &70198776233260 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.6.4
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70327813957680
68
+ version_requirements: *70198776233260
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &70327813956380 !ruby/object:Gem::Requirement
71
+ requirement: &70198776231900 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70327813956380
79
+ version_requirements: *70198776231900
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rdoc
82
- requirement: &70327813955680 !ruby/object:Gem::Requirement
82
+ requirement: &70198776230820 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70327813955680
90
+ version_requirements: *70198776230820
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rr
93
- requirement: &70327813954700 !ruby/object:Gem::Requirement
93
+ requirement: &70198776229620 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70327813954700
101
+ version_requirements: *70198776229620
102
102
  description: utility to manage projects and the terminal windows you open when you
103
103
  work on them.
104
104
  email: willemstoon@gmail.com
@@ -143,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
143
  version: '0'
144
144
  segments:
145
145
  - 0
146
- hash: -3114304915361326102
146
+ hash: -4148861926533244809
147
147
  required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  none: false
149
149
  requirements: