styoe 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2MwNWU2NDFiOTg0ZjZiZDQyMmMyZGQ1YjA0MmIyODFmNDc0YmZmNg==
5
+ data.tar.gz: !binary |-
6
+ NzIwZWY4ZTNhMzMwMWM0ZGQ5OTlhZGVlYWJjZjQ4ZTgwODExODc4ZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YWY0MDE5OTdjZWYwNGU0OTM5ZWI0NGU1OWFiMThlMjI1YjUzYjMxMDc4NWFi
10
+ NGUwNzk4YzhkMzExZTQzYzJiODU0ZDdhNmYxODk4YjQ5MGEzMGEyYzc0N2Nj
11
+ MDIzMWMyZWIxYWIyNzBjOWQzNzY3Yjk1YzhlMWQ4ODVkZmVmMGY=
12
+ data.tar.gz: !binary |-
13
+ ODdmNDIzNjk5NmFiNTI2OWNhNzZkYTNmYTRhOWI2MGZlYjlhMzRmZGFmYzNj
14
+ ZDgyZDU0YjRlM2RkYTE0YzQwNmY3ZTgxNTJhMGVhOTk4MTMyYzQyZTIwYzYx
15
+ Mjk4OTEwOTYwZWYxMDg0N2JmMTE2NmUzODgwYTI1YmIxMTkwYjA=
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor/gems
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ env:
5
+ - TEST_SUITE=features
6
+ - TEST_SUITE=spec
7
+ script: bundle exec rake $TEST_SUITE
8
+ notifications:
9
+ email: false
10
+ deploy:
11
+ provider: rubygems
12
+ api_key:
13
+ secure: U+yl3U672sFSWS8TrF6u3Neewojr1ExV9KXVJSeZrnIyh16Dx0dYrPzxYG5rePKyAuJ5gq61zK2uYFH80Sr9tlj4qRiKDLoRC6mHLvcx+KVnTcknfM476UYMUOgtaUT9sbEoCx1ERKswZA6PsoCJrN8os4Qu8+eTZ7OmYnSS0Ng=
14
+ gem: styoe
15
+ on:
16
+ tags: true
17
+ repo: as-cii/styoe
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Antonio Scandurra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # styoe (Start Your Engines!)
2
+
3
+ Start Your Engines™.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ $ gem install styoe
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Create a `.engines` file on your home directory, and write a yaml-formatted file
14
+ with the applications you would like to start:
15
+
16
+ ```yaml
17
+ skype: "/Applications/Skype.app/Contents/MacOS/Skype"
18
+ sublime-text: "/Applications/Sublime Text.app/Contents/MacOS/Sublime Text"
19
+ flint: "/Applications/Flint.app/Contents/MacOS/Flint"
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ ```bash
25
+ styoe
26
+ ```
27
+
28
+ Your applications will be up and running in seconds. When you are done with them
29
+ just execute:
30
+
31
+ ```bash
32
+ styoe --stop
33
+ ```
34
+
35
+ And they will disappear. For other great functionalities, please check
36
+ [features](features).
37
+
38
+ ## Contributing
39
+
40
+ 1. Fork it
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+
6
+ Cucumber::Rake::Task.new(:features) do |t|
7
+ t.cucumber_opts = "features --format pretty"
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ desc "Test"
13
+ task default: :spec
data/bin/styoe ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'styoe'
4
+
5
+ launcher = Styoe::Launcher.new
6
+
7
+ case ARGV[0]
8
+ when '--stop'
9
+ launcher.stop
10
+ else
11
+ launcher.start
12
+ end
@@ -0,0 +1,19 @@
1
+ Feature: Applications closing
2
+
3
+ Scenario: User closes open applications
4
+ Given a file named ".engines" with:
5
+ """
6
+ test: 'ruby process.rb'
7
+ """
8
+ And a file named "process.rb" with:
9
+ """
10
+ trap("INT") do
11
+ File.write("closed", "")
12
+ exit
13
+ end
14
+
15
+ gets
16
+ """
17
+ When I successfully run `styoe`
18
+ And I successfully run `styoe --stop`
19
+ Then a file named "closed" should exist
@@ -0,0 +1,33 @@
1
+ Feature: Application launching
2
+
3
+ Scenario: User writes configuration on current directory
4
+ Given a file named ".engines" with:
5
+ """
6
+ app1: 'touch x'
7
+ app2: 'touch y'
8
+ """
9
+ When I run `styoe`
10
+ Then the exit status should be 0
11
+ And a file named "x" should exist
12
+ And a file named "y" should exist
13
+
14
+ Scenario: User writes configuration on parent directory
15
+ Given a file named ".engines" with:
16
+ """
17
+ app1: 'touch x'
18
+ app2: 'touch y'
19
+ """
20
+ And a directory named "sub/directory"
21
+ When I cd to "sub/directory"
22
+ And I run `styoe`
23
+ Then the exit status should be 0
24
+ And a file named "x" should exist
25
+ And a file named "y" should exist
26
+
27
+ Scenario: User has no configuration
28
+ When I run `styoe`
29
+ Then the exit status should be 1
30
+ And the output should contain:
31
+ """
32
+ No configuration found. Are you sure you have created a .engines file?
33
+ """
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -0,0 +1,48 @@
1
+ require 'yaml'
2
+
3
+ module Styoe
4
+ DOT_FILE = '.engines'
5
+ PID_FILE = '.engines.pids'
6
+
7
+ class ConfigurationNotFound < StandardError; end
8
+
9
+ class ConfigurationResolver
10
+ def initialize(options = {})
11
+ @stop_at = options[:stop_at] || '/'
12
+ end
13
+
14
+ def active_processes(path = PID_FILE)
15
+ raise ConfigurationNotFound if stop?(path)
16
+ return active_processes("../#{path}") unless File.exist?(path)
17
+
18
+ parse_values(path)
19
+ end
20
+
21
+ def processes(path = DOT_FILE)
22
+ raise ConfigurationNotFound if stop?(path)
23
+ return processes("../#{path}") unless File.exist?(path)
24
+
25
+ parse_values(path)
26
+ end
27
+
28
+ def dump_pids(pids, path = DOT_FILE)
29
+ raise ConfigurationNotFound if stop?(path)
30
+ return dump_pids(pids, "../#{path}") unless File.exist?(path)
31
+
32
+ file = File.open(path.gsub(DOT_FILE, PID_FILE), "w")
33
+ file.write(YAML.dump pids)
34
+ file.close
35
+ end
36
+
37
+ private
38
+
39
+ def parse_values(path)
40
+ contents = File.read(path)
41
+ YAML.load(contents).values
42
+ end
43
+
44
+ def stop?(path)
45
+ File.dirname(File.absolute_path path) == @stop_at
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ module Styoe
2
+ class ProcessLauncher
3
+ def launch(process)
4
+ Process.spawn(process)
5
+ end
6
+
7
+ def stop(pid)
8
+ Process.kill("INT", pid)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Styoe
2
+ VERSION = "0.0.1"
3
+ end
data/lib/styoe.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'styoe/version'
2
+ require 'styoe/configuration_resolver'
3
+ require 'styoe/process_launcher'
4
+
5
+ module Styoe
6
+ class Launcher
7
+ def initialize(config_resolver = nil, process_launcher = nil)
8
+ @config_resolver = config_resolver || ConfigurationResolver.new
9
+ @process_launcher = process_launcher || ProcessLauncher.new
10
+ end
11
+
12
+ def start
13
+ begin
14
+ processes = Hash[*run_processes]
15
+ @config_resolver.dump_pids(processes)
16
+ rescue ConfigurationNotFound
17
+ $stderr.puts 'No configuration found. Are you sure you have created a .engines file?'
18
+ exit(1)
19
+ end
20
+ end
21
+
22
+ def stop
23
+ @config_resolver.active_processes.each do |pid|
24
+ @process_launcher.stop(pid)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def run_processes
31
+ @config_resolver.processes.map do |process|
32
+ [process, @process_launcher.launch(process)]
33
+ end.flatten
34
+ end
35
+ end
36
+ end
data/script/bootstrap ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ echo "Installing required gems..."
4
+ bundle install --path vendor/gems
data/spec/.gitkeep ADDED
File without changes
@@ -0,0 +1,84 @@
1
+ require 'styoe/configuration_resolver'
2
+
3
+ describe Styoe::ConfigurationResolver do
4
+
5
+ let(:pids) { { application1: 1, application2: 2 } }
6
+ let(:pid_file) { instance_double(File) }
7
+
8
+ it 'resolves and parses a configuration file' do
9
+ allow_file_to_exist_and_return("#{Styoe::DOT_FILE}", sample_configuration)
10
+
11
+ expect(subject.processes).to eq(['hello', 'world'])
12
+ end
13
+
14
+ it 'searches configuration recursively in parent directories' do
15
+ allow_file_to_exist_and_return("../../#{Styoe::DOT_FILE}", sample_configuration)
16
+
17
+ expect(subject.processes).to eq(['hello', 'world'])
18
+ end
19
+
20
+ it 'stops searching configuration when root is reached' do
21
+ subject = described_class.new(stop_at: '/')
22
+ allow(File).to receive(:dirname).and_return('/')
23
+
24
+ expect { subject.processes }.to raise_error(Styoe::ConfigurationNotFound)
25
+ end
26
+
27
+ it 'searches active processes' do
28
+ allow_file_to_exist_and_return("#{Styoe::PID_FILE}", sample_pids)
29
+
30
+ expect(subject.active_processes).to eq([ 1, 2 ])
31
+ end
32
+
33
+ it 'searches active processes recursively' do
34
+ allow_file_to_exist_and_return("../../#{Styoe::PID_FILE}", sample_pids)
35
+
36
+ expect(subject.active_processes).to eq([ 1, 2 ])
37
+ end
38
+
39
+ it 'stops searching active processes when root is reached' do
40
+ subject = described_class.new(stop_at: '/')
41
+ allow(File).to receive(:dirname).and_return('/')
42
+
43
+ expect { subject.active_processes }.to raise_error(Styoe::ConfigurationNotFound)
44
+ end
45
+
46
+ it "dumps active processes on the same path of #{Styoe::DOT_FILE}" do
47
+ pid_file = double
48
+ pids = { application1: 1, application2: 2 }
49
+ allow(File).to receive(:exist?).and_return(false, false, true)
50
+ allow(File).to receive(:open).with("../../#{Styoe::PID_FILE}", "w").and_return(pid_file)
51
+ allow(YAML).to receive(:dump).with(pids).and_return(sample_pids)
52
+ allow(pid_file).to receive(:write)
53
+ allow(pid_file).to receive(:close)
54
+
55
+ subject.dump_pids(pids)
56
+
57
+ expect(pid_file).to have_received(:write).with(sample_pids)
58
+ expect(pid_file).to have_received(:close)
59
+ end
60
+
61
+ def allow_file_to_exist_and_return(path, read_file)
62
+ allow_file_to_exist(path)
63
+ allow(File).to receive(:read).with(path).and_return(read_file)
64
+ end
65
+
66
+ def allow_file_to_exist(path)
67
+ allow(File).to receive(:exist?).and_return(false)
68
+ allow(File).to receive(:exist?).with(path).and_return(true)
69
+ end
70
+
71
+ def sample_configuration
72
+ <<-config
73
+ application1: hello
74
+ application2: world
75
+ config
76
+ end
77
+
78
+ def sample_pids
79
+ <<-pids
80
+ application1: 1
81
+ application2: 2
82
+ pids
83
+ end
84
+ end
data/spec/fire_spec.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'styoe'
2
+
3
+ describe Styoe::Launcher do
4
+ let(:configuration_resolver) { instance_double(Styoe::ConfigurationResolver) }
5
+ let(:process_launcher) { instance_double(Styoe::ProcessLauncher) }
6
+ let(:processes) { [ "app1", "app2", "app3" ] }
7
+ let(:pids) { [ 1, 2, 3 ] }
8
+ let(:running_processes) { Hash[*processes.zip(pids).flatten] }
9
+
10
+ subject { Styoe::Launcher.new(configuration_resolver, process_launcher) }
11
+
12
+ it "launches configuration processes and remembers open pids" do
13
+ allow(configuration_resolver).to receive(:processes).and_return(processes)
14
+ allow(configuration_resolver).to receive(:dump_pids)
15
+ stub_processes_launch
16
+
17
+ subject.start
18
+
19
+ expect(configuration_resolver).to have_received(:dump_pids).with(running_processes)
20
+ end
21
+
22
+ it 'stops active processes' do
23
+ allow(configuration_resolver).to receive(:active_processes).and_return(pids)
24
+ allow(process_launcher).to receive(:stop)
25
+
26
+ subject.stop
27
+
28
+ expect_processes_stopped
29
+ end
30
+
31
+ private
32
+
33
+ def stub_processes_launch
34
+ processes.zip(pids).each do |process, pid|
35
+ allow(process_launcher).to receive(:launch).with(process).and_return(pid)
36
+ end
37
+ end
38
+
39
+ def expect_processes_stopped
40
+ pids.each do |pid|
41
+ expect(process_launcher).to have_received(:stop).with(pid)
42
+ end
43
+ end
44
+ end
data/styoe.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'styoe/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "styoe"
8
+ spec.version = Styoe::VERSION
9
+ spec.authors = ["Antonio Scandurra"]
10
+ spec.email = ["as-cii@outlook.com"]
11
+ spec.description = %q{Start your engines.}
12
+ spec.summary = spec.description
13
+ spec.homepage = "https://github.com/as-cii/styoe"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 3.0.0.beta2"
24
+ spec.add_development_dependency "cucumber"
25
+ spec.add_development_dependency "aruba"
26
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: styoe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Antonio Scandurra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0.beta2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0.beta2
55
+ - !ruby/object:Gem::Dependency
56
+ name: cucumber
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: aruba
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Start your engines.
84
+ email:
85
+ - as-cii@outlook.com
86
+ executables:
87
+ - styoe
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - .ruby-version
93
+ - .travis.yml
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/styoe
99
+ - features/applications_closing.feature
100
+ - features/applications_launch.feature
101
+ - features/support/env.rb
102
+ - lib/styoe.rb
103
+ - lib/styoe/configuration_resolver.rb
104
+ - lib/styoe/process_launcher.rb
105
+ - lib/styoe/version.rb
106
+ - script/bootstrap
107
+ - spec/.gitkeep
108
+ - spec/configuration_resolver_spec.rb
109
+ - spec/fire_spec.rb
110
+ - styoe.gemspec
111
+ homepage: https://github.com/as-cii/styoe
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.2.2
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Start your engines.
135
+ test_files:
136
+ - features/applications_closing.feature
137
+ - features/applications_launch.feature
138
+ - features/support/env.rb
139
+ - spec/.gitkeep
140
+ - spec/configuration_resolver_spec.rb
141
+ - spec/fire_spec.rb