spinny_rb 0.1.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c9f0c42c9c22056403200244f6fca682a2bec1cf
4
+ data.tar.gz: e2d6005d1e1d783090b18225d227e86d25b3c6e5
5
+ SHA512:
6
+ metadata.gz: b73983a3e5eff331ff9934f49f3e07fc0c6e913d2ef67927f6bc3d8bb0db0cec6f54ddb3848430625fbf4a1ae7396800a23e0ba4784bb6f959b60fcf5bae56de
7
+ data.tar.gz: b5d15799f5b0a7b40df787cc4dbc1b223113762c7bc6e2445f1029736c9e05322a0bfd89a1c8809ba68348bacd8af30b794b3978f2f5bd68b59abf9c0f60e801
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spinny.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Spinny
2
+
3
+ a lightweight, unopinionated ruby application pre-loader
4
+
5
+ ## Description
6
+
7
+ Spinny is influenced by projects like Spring and Spin and tries to make your workflow more efficient.
8
+ It differs from those projects in the sense that it is designed to be lighter and does not try to
9
+ create special cases for certain technologies like Rails or particular test runners.
10
+ Small, light, and modular is the name of the game.
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ gem install spinny_rb
16
+ ```
17
+
18
+ ## How It Works
19
+
20
+ Spinny works using a client-server model.
21
+ The server will pre-load some code that you give it and then start listening on a TCP port.
22
+ When it receives a connection it will fork off new process and run the code passed in the TCP message.
23
+
24
+ ## Usage
25
+
26
+ First, you'll need to start your server.
27
+ In this example, we spin up a `Spinny::Server` using the `spinny-serve` executable.
28
+
29
+ ```sh
30
+ # Add the 'test' directory to the $LOAD_PATH and pre-load 'test_helper'
31
+ spinny-serve -Itest test_helper
32
+
33
+ # Pre-loading your typical Rails app
34
+ spinny-serve config/environment
35
+ ```
36
+
37
+ Now we need a client to push code to our running server.
38
+ Spinny comes with several clients out of the box:
39
+
40
+ * `Spinny::InteractiveClient` is a REPL that will push arbitrary code to the server
41
+ * `Spinny::LoadClient` takes a bunch of files and pushes them to the server to be loaded (e.g. running tests)
42
+ * `Spinny::ListenClient` is inspired by Guard. It takes a bunch of filepaths and listens for OS file change events and then loads the changed files on the server
43
+
44
+ All of these can be used by loading the respective client into an IRB shell.
45
+ Spinny also provides some executables to make it easier to work with common use cases.
46
+
47
+ ### spinny-push
48
+
49
+ `spinny-push` will read a list of filenames from ARGV or STDIN and use `Spinny::LoadClient` to push them to the server:
50
+
51
+ ```sh
52
+ # Read from ARGV
53
+ spinny-push file_one.rb file_two.rb
54
+
55
+ # Read from STDIN
56
+ ls test/*_test.rb | spinny-push
57
+ ```
58
+
59
+ ### spinny-listen
60
+
61
+ `spinny-listen` will read a list of directories from ARGV or STDIN and use `Spinny::ListenClient` to watch for file changes and then will push them to the server via `Spinny::LoadClient`
62
+
63
+ ```sh
64
+ spinny-listen test
65
+ ```
66
+
67
+ ### spinny-guard
68
+
69
+ `spinny-guard` gives you [guard](https://github.com/guard/guard)-like functionality. This spins up `Spinny::ListenClient` and a `Spinny::Server` for you in one convenient command
70
+
71
+ ```sh
72
+ spinny-guard
73
+ ```
74
+
75
+ ### spinny-stop
76
+
77
+ Finally, there is `spinny-stop` for killing all of your Spinny processes:
78
+
79
+ ```sh
80
+ spinny-stop
81
+ ```
82
+
83
+ ## TODO
84
+
85
+ * Add regexp for spinny-listen
86
+ * Add spinny-reload for reloading the server
87
+ * Add spinny-reload for listening and reloading the server when certain things happen
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/spinny-guard ADDED
@@ -0,0 +1,31 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ bin_path = File.expand_path('../', __FILE__)
4
+
5
+ require 'optparse'
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = 'Usage: spinny-guard [options]'
10
+
11
+ # Defaults
12
+ options[:listen] = 'test'
13
+ options[:load_paths] = 'test'
14
+ options[:env] = 'test_helper'
15
+
16
+ opts.on('--listen DIR', "Listen to the given directory (default: #{options[:listen]})") do |dir|
17
+ options[:listen] = dir
18
+ end
19
+
20
+ opts.on('--env ENV_FILE', "Pre-load the given file (default: #{options[:env]})") do |file|
21
+ options[:env] = file
22
+ end
23
+
24
+ opts.on('-I[PATHS]', '--include=[PATHS]', "Colon-separated list of directories to add to the $LOAD_PATH (default: #{options[:load_paths]})") do |paths|
25
+ options[:load_paths] = paths
26
+ end
27
+ end.parse!
28
+
29
+ system "#{bin_path}/spinny-listen -d #{options[:listen]}"
30
+ puts "#{bin_path}/spinny-serve -I#{options[:load_paths]} #{options[:env]}"
31
+ system "#{bin_path}/spinny-serve -I#{options[:load_paths]} #{options[:env]}"
data/bin/spinny-listen ADDED
@@ -0,0 +1,24 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../../lib', __FILE__)
4
+ require 'spinny'
5
+ require 'optparse'
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = 'Usage: spinny-listen DIR1 DIR2 ...'
10
+
11
+ opts.on('-d', '--daemonize', 'Run the process in the background') do
12
+ options[:daemonize] = true
13
+ end
14
+ end.parse!
15
+
16
+ dirs = ARGV.empty? ? STDIN.read.split("\n") : ARGV
17
+
18
+ start_listener = proc { Spinny::ListenClient.new(dirs).start! }
19
+
20
+ if options[:daemonize]
21
+ Process.detach fork(&start_listener)
22
+ else
23
+ start_listener.call
24
+ end
data/bin/spinny-push ADDED
@@ -0,0 +1,13 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../../lib', __FILE__)
4
+ require 'spinny'
5
+ require 'optparse'
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = 'Usage: spinny-push FILE1 FILE2 ...'
10
+ end.parse!
11
+
12
+ filepaths = ARGV.empty? ? STDIN.read.split("\n") : ARGV
13
+ Spinny::LoadClient.new(filepaths).start!
data/bin/spinny-serve ADDED
@@ -0,0 +1,16 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../../lib', __FILE__)
4
+ require 'spinny'
5
+ require 'optparse'
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = 'Usage: spinny-serve [options] ENV_FILE'
10
+
11
+ opts.on('-I[PATHS]', '--include=[PATHS]', 'Colon-separated list of directories to add to the $LOAD_PATH') do |paths|
12
+ options[:load_paths] = paths.split(':')
13
+ end
14
+ end.parse!
15
+
16
+ Spinny.serve! ARGV[0], options[:load_paths]
data/bin/spinny-stop ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env sh
2
+
3
+ ps aux | grep spinny- | grep -v spinny-stop | grep -v grep | awk '{ print $2 }' | xargs kill -9
@@ -0,0 +1,16 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Spinny
5
+ class Connection
6
+ def initialize(port = Server::DEFAULT_PORT)
7
+ @port = port
8
+ end
9
+
10
+ def push(code)
11
+ # connect to port, send code over port
12
+ uri = URI("http://localhost:#{@port}/enqueue")
13
+ Net::HTTP.post_form(uri, "code" => code)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Spinny
2
+ # An simple REPL that will allow you to push code to
3
+ # run on a Spinny::Server
4
+ class InteractiveClient
5
+ def initialize
6
+ @connection = Server.connect
7
+ end
8
+
9
+ def start!
10
+ loop do
11
+ puts "Type code to eval in fork then hit enter..."
12
+ code = gets
13
+ @connection.push(code)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'listen'
2
+ require 'spinny/load_client'
3
+
4
+ module Spinny
5
+ class ListenClient
6
+ def initialize(dirs)
7
+ @listener = Listen.to(*dirs, only: /\.rb$/) do |modified, added, removed|
8
+ changed = modified + added
9
+ Spinny::LoadClient.new(changed).start!
10
+ end
11
+ end
12
+
13
+ def start!
14
+ @listener.start
15
+ sleep
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module Spinny
2
+ # A simple client that just loads files
3
+ # Can be used to run Minitest tests
4
+ class LoadClient
5
+ def initialize(filepaths)
6
+ @code = filepaths.map {|fp| "load '#{fp}'"}.join(';')
7
+ @connection = Server.connect
8
+ end
9
+
10
+ def start!
11
+ @connection.push(@code)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ require 'webrick'
2
+ require 'cgi'
3
+
4
+ Thread.abort_on_exception = true
5
+
6
+ module Spinny
7
+ # Responsible for forking off new code runs
8
+ class Server
9
+ DEFAULT_PORT = 8080
10
+
11
+ def self.connect(port = DEFAULT_PORT)
12
+ Connection.new(port)
13
+ end
14
+
15
+ def initialize(filepath)
16
+ @filepath = filepath
17
+ end
18
+
19
+ def start!
20
+ require @filepath
21
+ queue = Queue.new
22
+ start_http_listener(queue)
23
+ loop do
24
+ fork_code = queue.deq
25
+ pid = fork { eval fork_code }
26
+ Process.wait pid
27
+ end
28
+ end
29
+
30
+ def start_http_listener(queue)
31
+ Thread.new do
32
+ server = WEBrick::HTTPServer.new(:Port => DEFAULT_PORT)
33
+ server.mount_proc '/enqueue' do |req, res|
34
+ code = CGI.parse(req.body)['code'].first
35
+ queue.enq(code)
36
+ end
37
+ server.start
38
+ end
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,3 @@
1
+ module Spinny
2
+ VERSION = "0.1.0"
3
+ end
data/lib/spinny.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'spinny/version'
2
+ require 'spinny/server'
3
+ require 'spinny/connection'
4
+ require 'spinny/interactive_client'
5
+ require 'spinny/load_client'
6
+ require 'spinny/listen_client'
7
+
8
+ # A lighter, less opinionated Ruby pre-loader
9
+ module Spinny
10
+ # Block the current thread and boot up a server
11
+ def self.serve!(filepath, load_paths = [])
12
+ puts "Starting Spinny::Server..."
13
+ load_paths.each { |p| $: << p }
14
+ Server.new(filepath).start!
15
+ end
16
+ end
data/spinny_rb.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'spinny/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "spinny_rb"
8
+ spec.version = Spinny::VERSION
9
+ spec.authors = ["Josh Bodah"]
10
+ spec.email = ["jb3689@yahoo.com"]
11
+
12
+ spec.summary = %q{a lightweight, unopinionated ruby application pre-loader}
13
+ spec.description = %q{
14
+ Spinny is influenced by projects like Spring and Spin and tries to make your workflow more efficient.
15
+ It differs from those projects in the sense that it is designed to be lighter and does not try to
16
+ create special cases for certain technologies like Rails or particular test runners.
17
+ }
18
+ spec.homepage = "https://github.com/jbodah/spinny_rb"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "listen", "~> 3.0"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.10"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "minitest"
30
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spinny_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Josh Bodah
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: listen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
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
+ description: |2
70
+
71
+ Spinny is influenced by projects like Spring and Spin and tries to make your workflow more efficient.
72
+ It differs from those projects in the sense that it is designed to be lighter and does not try to
73
+ create special cases for certain technologies like Rails or particular test runners.
74
+ email:
75
+ - jb3689@yahoo.com
76
+ executables: []
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - ".gitignore"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - README.md
84
+ - Rakefile
85
+ - bin/spinny-guard
86
+ - bin/spinny-listen
87
+ - bin/spinny-push
88
+ - bin/spinny-serve
89
+ - bin/spinny-stop
90
+ - lib/spinny.rb
91
+ - lib/spinny/connection.rb
92
+ - lib/spinny/interactive_client.rb
93
+ - lib/spinny/listen_client.rb
94
+ - lib/spinny/load_client.rb
95
+ - lib/spinny/server.rb
96
+ - lib/spinny/version.rb
97
+ - spinny_rb.gemspec
98
+ homepage: https://github.com/jbodah/spinny_rb
99
+ licenses: []
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.4.8
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: a lightweight, unopinionated ruby application pre-loader
121
+ test_files: []