divide 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/README.md +56 -11
- data/Rakefile +12 -0
- data/bin/divide +3 -1
- data/divide.gemspec +10 -6
- data/lib/divide.rb +4 -26
- data/lib/divide/cli.rb +72 -0
- data/lib/divide/extractor.rb +46 -22
- data/lib/divide/terminal_bridge.rb +57 -29
- data/lib/divide/terminal_bridge/iterm.rb +13 -0
- data/lib/divide/terminal_bridge/terminal.rb +13 -0
- data/lib/divide/version.rb +1 -1
- metadata +38 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2638293acbd8a4d7977f9f41d0efd5f503317ac
|
4
|
+
data.tar.gz: 972a61cb4e0c8037faefc8b2103a6e1cbed4159a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89c9dd0d15666f6953e29dc3f7c80fcba32e3ff728a5ea30eec616b43f4086229c33621090425e5e96701c696bce24a1b2d37aa739c30eded6dd12276f5e221c
|
7
|
+
data.tar.gz: fb17df6ab1db78fa3043e054333d0e548e80d2028153e01d98e7cc40921b6466075352951610c48654ff9377e344121e043d022fe2658ec98387fb09bbf61cc9
|
data/README.md
CHANGED
@@ -1,25 +1,70 @@
|
|
1
1
|
# Divide
|
2
|
-
Start Procfile processes in different Terminal
|
2
|
+
Start `Procfile` processes in different Terminal/iTerm tabs.
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
I’m well aware of [foreman][], but it starts all processes in the same tab which can be inconvenient.<br>
|
5
|
+
I’m well aware of [tmux][], but obviously not everyone’s using it (if you do, check out [teamocil][]).
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
```sh
|
6
9
|
$ gem install divide
|
10
|
+
$ divide
|
7
11
|
```
|
8
12
|
|
9
|
-
##
|
13
|
+
## Options
|
14
|
+
**Divide** is option-free. You may however overwrite any options of your `Procfile` processes by passing them to `divide`.
|
15
|
+
|
16
|
+
```
|
17
|
+
# Procfile
|
18
|
+
web: bundle exec unicorn -c ./config/unicorn.rb
|
19
|
+
```
|
20
|
+
|
21
|
+
```sh
|
22
|
+
$ divide -c ./another_folder/unicorn.rb
|
23
|
+
# => bundle exec unicorn -c ./another_folder/unicorn.rb
|
24
|
+
```
|
25
|
+
|
26
|
+
### ENV
|
27
|
+
**Divide** automatically loads `.env` file and overwrite any `$VARIABLE` of your processes.
|
28
|
+
|
29
|
+
```
|
30
|
+
# .env
|
31
|
+
PORT=1337
|
32
|
+
RACK_ENV=development
|
33
|
+
```
|
10
34
|
```
|
35
|
+
# Procfile
|
36
|
+
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb -E $RACK_ENV
|
37
|
+
```
|
38
|
+
|
39
|
+
```sh
|
11
40
|
$ divide
|
12
|
-
|
41
|
+
# => bundle exec unicorn -p 1337 -c ./config/unicorn.rb -E development
|
13
42
|
```
|
14
|
-
## License
|
15
|
-
MIT (See [LICENSE][])
|
16
43
|
|
17
|
-
|
44
|
+
### $PORT
|
45
|
+
If you don’t specify a port, **Divide** will overwrite `$PORT` with 5000.
|
18
46
|
|
19
|
-
|
20
|
-
|
47
|
+
```
|
48
|
+
# Procfile
|
49
|
+
web: bundle exec rails s -p $PORT
|
50
|
+
```
|
51
|
+
|
52
|
+
```sh
|
53
|
+
$ divide
|
54
|
+
# => bundle exec rails s -p 5000
|
55
|
+
```
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
Why yes! You’re welcome to submit any [issue][] or [pull request][] as long as everything’s green when you `bundle exec rake spec`. Meanwhile, you can give these folks a tap on the back for helping out:
|
59
|
+
|
60
|
+
- [@remiprev](https://github.com/remiprev)
|
61
|
+
|
62
|
+
## License
|
63
|
+
Copyright © 2013 Etienne Lemay. See [LICENSE][] for details.
|
21
64
|
|
22
|
-
[LICENSE]: /LICENSE.md
|
23
65
|
[foreman]: https://github.com/dollar/foreman
|
24
66
|
[tmux]: http://tmux.sourceforge.net
|
25
67
|
[teamocil]: https://github.com/remiprev/teamocil
|
68
|
+
[issue]: https://github.com/EtienneLem/divide/issues
|
69
|
+
[pull request]: https://github.com/EtienneLem/divide/pulls
|
70
|
+
[LICENSE]: /LICENSE.md
|
data/Rakefile
CHANGED
@@ -1,3 +1,15 @@
|
|
1
1
|
# Rubygems
|
2
2
|
require 'bundler'
|
3
|
+
Bundler.require(:development)
|
4
|
+
|
3
5
|
Bundler::GemHelper.install_tasks
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
|
8
|
+
# RSpec
|
9
|
+
task :default => :spec
|
10
|
+
|
11
|
+
desc "Run all specs"
|
12
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
13
|
+
task.pattern = "spec/**/*_spec.rb"
|
14
|
+
task.rspec_opts = "--colour --format=documentation"
|
15
|
+
end
|
data/bin/divide
CHANGED
data/divide.gemspec
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require File.expand_path('../lib/divide/version', __FILE__)
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.author
|
6
|
-
s.email
|
7
|
-
s.homepage
|
8
|
-
s.
|
4
|
+
s.name = 'divide'
|
5
|
+
s.author = 'Etienne Lemay'
|
6
|
+
s.email = 'etienne@heliom.ca'
|
7
|
+
s.homepage = 'https://github.com/EtienneLem/'
|
8
|
+
s.license = 'MIT'
|
9
|
+
s.summary = 'Divide Procfile processes'
|
10
|
+
s.description = 'Start Procfile processes in different Terminal.app tabs'
|
9
11
|
|
10
|
-
s.version
|
12
|
+
s.version = Divide::VERSION
|
11
13
|
s.platform = Gem::Platform::RUBY
|
12
14
|
|
13
15
|
s.files = %w(LICENSE.md README.md Rakefile divide.gemspec)
|
@@ -18,4 +20,6 @@ spec = Gem::Specification.new do |s|
|
|
18
20
|
s.executables << 'divide'
|
19
21
|
|
20
22
|
s.require_paths << 'lib'
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.13'
|
21
25
|
end
|
data/lib/divide.rb
CHANGED
@@ -1,29 +1,7 @@
|
|
1
1
|
require 'divide/version'
|
2
2
|
require 'divide/extractor'
|
3
|
-
require 'divide/terminal_bridge'
|
3
|
+
require 'divide/terminal_bridge/terminal'
|
4
|
+
require 'divide/terminal_bridge/iterm'
|
5
|
+
require 'divide/cli'
|
4
6
|
|
5
|
-
module Divide
|
6
|
-
def self.run(argv)
|
7
|
-
@options = argv.each_slice(2).to_a
|
8
|
-
terminal.exec(processes)
|
9
|
-
1
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.processes
|
13
|
-
no_profile unless extracted_processes = extractor.extract_processes!
|
14
|
-
extracted_processes.to_a.map { |a| a[1] }
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.no_profile
|
18
|
-
puts "#{Dir.pwd}: There is no Procfile in this directory"
|
19
|
-
exit
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.terminal
|
23
|
-
@terminal ||= Divide::TerminalBridge.new
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.extractor
|
27
|
-
@extractor ||= Divide::Extractor.new(@options)
|
28
|
-
end
|
29
|
-
end
|
7
|
+
module Divide; end
|
data/lib/divide/cli.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Divide
|
2
|
+
class CLI
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(argv=[])
|
6
|
+
@options = argv.each_slice(2).to_a
|
7
|
+
|
8
|
+
show_version if argv.grep(/^-v|--version$/).any?
|
9
|
+
show_help if argv.grep(/^-h|--help$/).any?
|
10
|
+
|
11
|
+
error(:app_not_supported) unless terminal
|
12
|
+
|
13
|
+
processes = extract_processes
|
14
|
+
start_processes(processes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_processes(processes)
|
18
|
+
terminal.exec(processes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def extract_processes
|
22
|
+
error(:no_procfile) unless extracted_processes
|
23
|
+
extracted_processes.to_a.map { |a| a[1] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def error(type)
|
27
|
+
errors = {
|
28
|
+
no_procfile: "#{current_directory}: There is no Procfile in this directory",
|
29
|
+
app_not_supported: "#{current_app_name} is not yet supported, please fill in a request https://github.com/EtienneLem/divide/issues",
|
30
|
+
}
|
31
|
+
|
32
|
+
exit_with_message(errors[type], 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
def show_version
|
36
|
+
exit_with_message("Divide #{VERSION}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def show_help
|
40
|
+
exit_with_message("Usage: divide [options]")
|
41
|
+
end
|
42
|
+
|
43
|
+
def exit_with_message(message, code=0)
|
44
|
+
STDOUT.puts(message)
|
45
|
+
exit code
|
46
|
+
end
|
47
|
+
|
48
|
+
def current_app_name
|
49
|
+
@current_app_name ||= TerminalBridge.current_app_name
|
50
|
+
end
|
51
|
+
|
52
|
+
def extracted_processes
|
53
|
+
@extracted_processes ||= extractor.extract_processes!
|
54
|
+
end
|
55
|
+
|
56
|
+
def current_directory
|
57
|
+
@current_directory ||= Dir.pwd
|
58
|
+
end
|
59
|
+
|
60
|
+
def terminal
|
61
|
+
@terminal ||= case current_app_name.downcase
|
62
|
+
when 'terminal' then TerminalBridge::Terminal.new
|
63
|
+
when 'iterm' then TerminalBridge::ITerm.new
|
64
|
+
else nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def extractor
|
69
|
+
@extractor ||= Extractor.new(@options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/divide/extractor.rb
CHANGED
@@ -1,34 +1,58 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@options = options
|
3
|
+
module Divide
|
4
|
+
class Extractor
|
5
|
+
DEFAULT_ENV = { 'PORT' => '5000' }.merge(ENV)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def initialize(options=[])
|
8
|
+
@options = options
|
9
|
+
|
10
|
+
overwrite_env_variables
|
11
|
+
overwrite_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def procfile_content
|
15
|
+
@procfile_content ||= File.read('./Procfile') rescue ''
|
16
|
+
end
|
17
|
+
|
18
|
+
def env_content
|
19
|
+
@env_content ||= File.read('./.env') rescue ''
|
20
|
+
end
|
11
21
|
|
12
|
-
|
13
|
-
|
22
|
+
def overwrite_options
|
23
|
+
splitted_content = procfile_content.split(/\s/)
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
value = option[1]
|
25
|
+
@options.each do |option|
|
26
|
+
next if option.length < 2
|
18
27
|
|
19
|
-
|
20
|
-
|
28
|
+
key = option[0]
|
29
|
+
value = option[1]
|
21
30
|
|
22
|
-
|
31
|
+
if key_index = splitted_content.index(key)
|
32
|
+
value_to_overwrite = splitted_content[key_index + 1]
|
33
|
+
procfile_content.sub!(value_to_overwrite, value)
|
34
|
+
end
|
35
|
+
end
|
23
36
|
end
|
24
|
-
end
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
|
38
|
+
def extract_processes!
|
39
|
+
return nil if procfile_content.empty?
|
40
|
+
YAML.load(procfile_content)
|
41
|
+
end
|
29
42
|
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
def env_variables
|
44
|
+
@env_variables ||= begin
|
45
|
+
env_content.split(/\n/).inject({}) do |memo, line|
|
46
|
+
variable, value = line.split(/=/)
|
47
|
+
memo.merge variable => value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def overwrite_env_variables
|
53
|
+
DEFAULT_ENV.merge(env_variables).each do |variable, value|
|
54
|
+
procfile_content.gsub!("$#{variable}", value)
|
55
|
+
end
|
56
|
+
end
|
33
57
|
end
|
34
58
|
end
|
@@ -1,40 +1,68 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
`osascript -e '#{cmd}'`
|
5
|
-
end
|
1
|
+
module Divide
|
2
|
+
class TerminalBridge
|
3
|
+
attr_reader :app_name
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# Class methods
|
6
|
+
def self.execute(command)
|
7
|
+
`#{command}`
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def self.apple_script(command)
|
11
|
+
command = command.join("' -e '") if command.is_a?(Array)
|
12
|
+
execute("osascript -e '#{command}'")
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
def self.current_app_name
|
16
|
+
@current_app_name ||= apple_script('tell app "System Events" to get name of the first process whose frontmost is true').strip
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
modifier_key = nil
|
23
|
-
key = splits[0]
|
19
|
+
# Instance methods
|
20
|
+
def initialize
|
21
|
+
@app_name = bridge.current_app_name
|
24
22
|
end
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
def bridge
|
25
|
+
@bridge ||= Divide::TerminalBridge
|
26
|
+
end
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
def tell_current_app(cmd)
|
29
|
+
%(tell app "#{@app_name}" to #{cmd})
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
|
32
|
+
def open_new_tab_in_current_directory
|
33
|
+
[open_new_tab, go_to_current_directory]
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
36
|
+
def go_to_current_directory
|
37
|
+
do_script "cd #{Dir.pwd}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def keystroke(key)
|
41
|
+
splits = key.split('+')
|
42
|
+
|
43
|
+
if splits.length > 1
|
44
|
+
modifier_key = splits[0]
|
45
|
+
key = splits[1]
|
46
|
+
else
|
47
|
+
modifier_key = nil
|
48
|
+
key = splits[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
modifier = modifier_key ? " using #{modifier_key} down" : ''
|
52
|
+
%(tell app "System Events" to tell process "#{@app_name}" to keystroke "#{key}"#{modifier})
|
53
|
+
end
|
54
|
+
|
55
|
+
def exec(commands)
|
56
|
+
commands = Array(commands)
|
57
|
+
|
58
|
+
scripts = commands.map { |c| do_script(c) }
|
59
|
+
scripts_with_new_tabs = insert_between(scripts, open_new_tab_in_current_directory).flatten
|
60
|
+
|
61
|
+
bridge.apple_script(scripts_with_new_tabs)
|
62
|
+
end
|
63
|
+
|
64
|
+
def insert_between(array, insert_between)
|
65
|
+
array.flat_map { |a| [a, insert_between] }[0...-1]
|
66
|
+
end
|
39
67
|
end
|
40
68
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'divide/terminal_bridge'
|
2
|
+
|
3
|
+
module Divide
|
4
|
+
class TerminalBridge::ITerm < TerminalBridge
|
5
|
+
def do_script(script)
|
6
|
+
tell_current_app %(tell the first terminal to tell the last session to write text "#{script}")
|
7
|
+
end
|
8
|
+
|
9
|
+
def open_new_tab
|
10
|
+
tell_current_app %(tell the first terminal to launch session "Default Session")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'divide/terminal_bridge'
|
2
|
+
|
3
|
+
module Divide
|
4
|
+
class TerminalBridge::Terminal < TerminalBridge
|
5
|
+
def do_script(script)
|
6
|
+
tell_current_app %(do script "#{script}" in front window)
|
7
|
+
end
|
8
|
+
|
9
|
+
def open_new_tab
|
10
|
+
keystroke 'command+t'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/divide/version.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: divide
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Etienne Lemay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2013-05-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.13'
|
41
|
+
description: Start Procfile processes in different Terminal.app tabs
|
14
42
|
email: etienne@heliom.ca
|
15
43
|
executables:
|
16
44
|
- divide
|
@@ -21,13 +49,17 @@ files:
|
|
21
49
|
- README.md
|
22
50
|
- Rakefile
|
23
51
|
- divide.gemspec
|
52
|
+
- lib/divide/cli.rb
|
24
53
|
- lib/divide/extractor.rb
|
54
|
+
- lib/divide/terminal_bridge/iterm.rb
|
55
|
+
- lib/divide/terminal_bridge/terminal.rb
|
25
56
|
- lib/divide/terminal_bridge.rb
|
26
57
|
- lib/divide/version.rb
|
27
58
|
- lib/divide.rb
|
28
59
|
- bin/divide
|
29
60
|
homepage: https://github.com/EtienneLem/
|
30
|
-
licenses:
|
61
|
+
licenses:
|
62
|
+
- MIT
|
31
63
|
metadata: {}
|
32
64
|
post_install_message:
|
33
65
|
rdoc_options: []
|
@@ -49,5 +81,5 @@ rubyforge_project:
|
|
49
81
|
rubygems_version: 2.0.0
|
50
82
|
signing_key:
|
51
83
|
specification_version: 4
|
52
|
-
summary:
|
84
|
+
summary: Divide Procfile processes
|
53
85
|
test_files: []
|