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