tabby 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tabby (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rspec (2.1.0)
11
+ rspec-core (~> 2.1.0)
12
+ rspec-expectations (~> 2.1.0)
13
+ rspec-mocks (~> 2.1.0)
14
+ rspec-core (2.1.0)
15
+ rspec-expectations (2.1.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.1.0)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ rspec (~> 2.1.0)
24
+ tabby!
@@ -0,0 +1,42 @@
1
+ # Tabby
2
+ Tabby is a simple iTerm2 environment configuration tool. It allows you to create different environments for different projects, each with their own set of tabs and command sets.
3
+
4
+ ## Usage
5
+
6
+ ### Defining Environments
7
+ Environments should be stored in `~/.tabby/`, using a simple and short name. We'll walk through building my `~/.tabby/blog.rb` environment.
8
+
9
+ Tabby environments are just regular Ruby classes. The filename and classname should match, with the classname following regular Ruby standards:
10
+
11
+ class Blog < Tabby::Base
12
+ end
13
+
14
+ Define your project's root directory with `basedir`:
15
+
16
+ class Blog < Tabby::Base
17
+ basedir "~/Dev/Blog"
18
+ end
19
+
20
+ Creating tabs is just a matter of creating methods. There should be one method per tab. The method name becomes the tab's title; replacing underscores with spaces.
21
+
22
+ class Blog < Tabby::Base
23
+ basedir "~/Dev/Blog"
24
+
25
+ def jekyll
26
+ exec "jekyll --auto --server"
27
+ end
28
+
29
+ def sass
30
+ exec "sass --watch public/css/main.sass:public/css/main.css"
31
+ end
32
+ end
33
+
34
+ Each tab will start off by `cd`'ing into the environment's `basedir`. Then it will execute it's list of commands in order.
35
+
36
+ ### Starting An Environment
37
+ tabby blog
38
+
39
+ ![tabby](https://github.com/mnoble/tabby/raw/master/screenshot.png)
40
+
41
+ ## License
42
+ See LICENSE
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ RSpec::Core::RakeTask.new do |spec|
6
+ spec.rspec_opts = ["--format=doc", "--fail-fast", "--color"]
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "tabby"
3
+ require "tabby/runner"
4
+ Tabby::Runner.new(ARGV.dup).start
@@ -0,0 +1,75 @@
1
+ require "erb"
2
+ require "tempfile"
3
+
4
+ module Tabby
5
+ class Base
6
+ class << self; attr_reader :_basedir; end
7
+
8
+ # Sets the project root directory.
9
+ #
10
+ # Parameters:
11
+ # dir Project's root directory path
12
+ #
13
+ def self.basedir(dir)
14
+ @_basedir = dir
15
+ end
16
+
17
+ # List of commands for the current tab to execute.
18
+ attr_accessor :commands
19
+
20
+ # Title of the current tab being created.
21
+ attr_accessor :title
22
+
23
+ # Rendered AppleScript source to be saved to a tempfile.
24
+ attr_accessor :template
25
+
26
+ def initialize
27
+ @commands = []
28
+ end
29
+
30
+ # Queue a command to be executed when the tab gets created.
31
+ #
32
+ # Parameters:
33
+ # command bash/zsh/etc command to be executed
34
+ #
35
+ def exec(command)
36
+ @commands << %{write text "#{command}"}
37
+ end
38
+
39
+ # Call each instance method and create a tab for each one.
40
+ # Method names become tab titles, with underscores replaced
41
+ # with spaces.
42
+ #
43
+ def call
44
+ self.class.instance_methods(false).each do |method|
45
+ @commands = []
46
+ @title = method
47
+ send(method)
48
+ create_tab
49
+ end
50
+ end
51
+
52
+ # Project's base directory. Each tab +cd+'s into this
53
+ # directory before executing commands.
54
+ #
55
+ def basedir
56
+ self.class._basedir
57
+ end
58
+
59
+ private
60
+
61
+ def create_tab
62
+ tempfile = Tempfile.new("tabby-#{@title}")
63
+ tempfile.write(render_script)
64
+ tempfile.close
65
+ Kernel.system("osascript #{tempfile.path}")
66
+ end
67
+
68
+ def render_script
69
+ osapath = File.expand_path("../../script/tabby.osa.erb", __FILE__)
70
+ template = ERB.new(File.read(osapath))
71
+ commands = @commands.join("\n")
72
+ @template = template.result(binding)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ module Tabby
2
+ class Runner
3
+ TABBYDIR = File.expand_path("~/.tabby")
4
+
5
+ # Project name, should be the filename in ~/.tabby.
6
+ attr_reader :project
7
+
8
+ def initialize(argv)
9
+ @project = argv[0]
10
+ @klass = @project.split("_").map { |p| p.capitalize }.join.to_sym
11
+ end
12
+
13
+ # Loads the environment file (from ~/.tabby), finds the class
14
+ # which matches the filename and +call+s it.
15
+ #
16
+ def start
17
+ require File.join(TABBYDIR, "#{@project}.rb")
18
+ ObjectSpace.class.const_get(@klass).new.call
19
+ rescue LoadError
20
+ puts "=> ERROR: Project (#{TABBYDIR}/#{@project}.rb) does not exist."
21
+ rescue NameError
22
+ puts "=> ERROR: Project filename/classname mismatch."
23
+ puts " Filename is: #{@project}.rb"
24
+ puts " Classname should be: #{@klass}"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Tabby
2
+ VERSION = "0.0.1"
3
+ end
Binary file
@@ -0,0 +1,21 @@
1
+ tell application "iTerm"
2
+ if (count of terminals) is equal to 0 then
3
+ set term to (make new terminal)
4
+ else
5
+ set term to (current terminal)
6
+ end if
7
+
8
+ tell term
9
+ tell (current session)
10
+ write text "cd <%= basedir %>"
11
+ write text "clear"
12
+ end tell
13
+
14
+ tell (launch session "Default")
15
+ set name to "<%= title %>"
16
+ write text "cd <%= basedir %>"
17
+ write text "clear"
18
+ <%= commands %>
19
+ end tell
20
+ end tell
21
+ end tell
@@ -0,0 +1,11 @@
1
+ class SpecBlog < Tabby::Base
2
+ basedir "~/Dev/Blog"
3
+
4
+ def jekyll
5
+ exec "jekyll --auto --server"
6
+ end
7
+
8
+ def sass
9
+ exec "sass --watch public/css/main.sass:public/css/main.css"
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+ require File.expand_path("../.tabby/spec_blog", __FILE__)
3
+
4
+ describe Tabby::Runner do
5
+ subject { Tabby::Runner.new(["blog"]) }
6
+
7
+ before :each do
8
+ Kernel.stub(:system)
9
+ end
10
+
11
+ it "should tell the user when the project file is missing" do
12
+ with_stubbed_stdout do |output|
13
+ subject.should_receive(:require).and_raise(LoadError)
14
+ subject.start
15
+ output.should include "does not exist"
16
+ end
17
+ end
18
+
19
+ it "should tell the user when the filename and classname don't match" do
20
+ with_stubbed_stdout do |output|
21
+ ObjectSpace.class.should_receive(:const_get).and_raise(NameError)
22
+ subject.start
23
+ output.should include "mismatch"
24
+ end
25
+ end
26
+
27
+ it "should call the Tabby class" do
28
+ Tabby::Runner.with_constants :TABBYDIR => expand("../.tabby", __FILE__) do
29
+ blog = SpecBlog.new
30
+ blog.should_receive(:call)
31
+ SpecBlog.stub(:new) { blog }
32
+ runner = Tabby::Runner.new(["spec_blog"])
33
+ runner.start
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ require "rspec"
2
+ require "stringio"
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
5
+ require "tabby"
6
+ require "tabby/runner"
7
+ require "support/with_constants"
8
+ require "support/with_stubbed_stdout"
9
+ require "support/expand"
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def expand(*args)
3
+ File.expand_path(*args)
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require "stringio"
2
+
3
+ class Object
4
+ def self.with_constants(constants, &block)
5
+ old_constants = {}
6
+ stderr = $stderr
7
+ $stderr = StringIO.new
8
+
9
+ constants.each do |constant, val|
10
+ old_constants[constant] = const_get(constant)
11
+ const_set(constant, val)
12
+ end
13
+
14
+ block.call
15
+
16
+ old_constants.each do |constant, val|
17
+ const_set(constant, val)
18
+ end
19
+
20
+ $stderr = stderr
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ class Object
2
+ def with_stubbed_stdout(&block)
3
+ _stdout = $stdout
4
+ $stdout = stdout = StringIO.new
5
+ yield stdout.string
6
+ $stdout = _stdout
7
+ end
8
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ class TabbySpecBlog < Tabby::Base
4
+ basedir "~/Dev/Blog"
5
+ def foo
6
+ exec "whoami"
7
+ exec "pwd"
8
+ end
9
+ end
10
+
11
+ describe Tabby::Base do
12
+ before { Kernel.stub(:system) }
13
+ subject { TabbySpecBlog.new }
14
+
15
+ it "should set a base directory" do
16
+ subject.basedir.should == "~/Dev/Blog"
17
+ end
18
+
19
+ it "should queue commands to be executed" do
20
+ subject.exec("ls")
21
+ subject.commands.should include("write text \"ls\"")
22
+ end
23
+
24
+ it "should call all tab methods" do
25
+ subject.should_receive(:foo)
26
+ subject.call
27
+ end
28
+
29
+ it "should create actual iTerm2 tab before each method call" do
30
+ subject.call
31
+ subject.template.should match /launch session "Default"/
32
+ end
33
+
34
+ it "should set the title" do
35
+ subject.call
36
+ subject.template.should match /set name to "foo"/
37
+ end
38
+
39
+ it "should change directory into the base directory" do
40
+ subject.call
41
+ subject.template.should match %r{write text "cd ~/Dev/Blog"}
42
+ end
43
+
44
+ it "should execute all commands" do
45
+ subject.call
46
+ subject.template.should match /write text "whoami"/
47
+ end
48
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "tabby/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "tabby"
7
+ s.version = Tabby::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Matte Noble"]
10
+ s.email = ["me@mattenoble.com"]
11
+ s.homepage = "http://github.com/mnoble/tabby"
12
+ s.summary = %q{Simple iTerm2 project environment setup.}
13
+ s.description = %q{Simple iTerm2 project environment setup.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.extra_rdoc_files = ["README.markdown", "screenshot.png"]
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec", "~> 2.1.0"
22
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tabby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Matte Noble
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-27 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 1
31
+ - 0
32
+ version: 2.1.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Simple iTerm2 project environment setup.
36
+ email:
37
+ - me@mattenoble.com
38
+ executables:
39
+ - tabby
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - README.markdown
44
+ - screenshot.png
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - Gemfile.lock
49
+ - README.markdown
50
+ - Rakefile
51
+ - bin/tabby
52
+ - lib/tabby.rb
53
+ - lib/tabby/runner.rb
54
+ - lib/tabby/version.rb
55
+ - screenshot.png
56
+ - script/tabby.osa.erb
57
+ - spec/.tabby/spec_blog.rb
58
+ - spec/runner_spec.rb
59
+ - spec/spec_helper.rb
60
+ - spec/support/expand.rb
61
+ - spec/support/with_constants.rb
62
+ - spec/support/with_stubbed_stdout.rb
63
+ - spec/tabby_spec.rb
64
+ - tabby.gemspec
65
+ has_rdoc: true
66
+ homepage: http://github.com/mnoble/tabby
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.7
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Simple iTerm2 project environment setup.
97
+ test_files:
98
+ - spec/runner_spec.rb
99
+ - spec/spec_helper.rb
100
+ - spec/support/expand.rb
101
+ - spec/support/with_constants.rb
102
+ - spec/support/with_stubbed_stdout.rb
103
+ - spec/tabby_spec.rb