keminglabs-fox-rubby 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.
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/README.md +9 -0
- data/Rakefile +1 -0
- data/examples/minimal.rb +7 -0
- data/examples/web_example.rb +91 -0
- data/keminglabs-fox-rubby.gemspec +25 -0
- data/lib/keminglabs-fox-rubby/version.rb +3 -0
- data/lib/keminglabs-fox-rubby.rb +128 -0
- metadata +104 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/examples/minimal.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'fox'
|
|
2
|
+
require 'tilt'
|
|
3
|
+
require 'sass'
|
|
4
|
+
|
|
5
|
+
# A builder process that compiles CSS from SASS.
|
|
6
|
+
|
|
7
|
+
# Cases
|
|
8
|
+
# 1. Success: built
|
|
9
|
+
# 2. Fail: threw an exception
|
|
10
|
+
# 3. Abort: dependencies aren't there
|
|
11
|
+
def build_css(request)
|
|
12
|
+
# get source from target
|
|
13
|
+
source = "src/sass/" + request[:target].gsub(/\.css$/, '.sass')
|
|
14
|
+
|
|
15
|
+
# find out if theres dependencies
|
|
16
|
+
t = Tilt.new(source)
|
|
17
|
+
#Not sure if this is the right way to reach in and get the SASS engine...my Rubby-fu is weak.
|
|
18
|
+
dependencies = t.instance_variable_get(:@engine).dependencies.map{|x| x.options[:filename]}
|
|
19
|
+
|
|
20
|
+
# find out if all dependencies are met
|
|
21
|
+
if Fox.ensure(request[:socket], dependencies)
|
|
22
|
+
# Build it
|
|
23
|
+
begin
|
|
24
|
+
res = t.render nil
|
|
25
|
+
|
|
26
|
+
# Success
|
|
27
|
+
return {
|
|
28
|
+
:exit => :succeed,
|
|
29
|
+
# optional
|
|
30
|
+
:result => res,
|
|
31
|
+
:log => "Successfully built #{request[:target]}",
|
|
32
|
+
:tags => ["web"]
|
|
33
|
+
}
|
|
34
|
+
rescue
|
|
35
|
+
# Failure
|
|
36
|
+
return {
|
|
37
|
+
:exit => :fail,
|
|
38
|
+
# optional
|
|
39
|
+
:log => "Failed to build #{request[:target]}",
|
|
40
|
+
:tags => ["web"]
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
# Abort
|
|
45
|
+
return {
|
|
46
|
+
:exit => :abort,
|
|
47
|
+
# optional
|
|
48
|
+
:log => "Dependencies not met for #{request[:target]}",
|
|
49
|
+
:tags => ["web"]
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Example of registering a handler for a target
|
|
55
|
+
Fox.register "default.css" { |req| build_css(req) }
|
|
56
|
+
|
|
57
|
+
Fox.register "target name" do |req|
|
|
58
|
+
|
|
59
|
+
##Your build code
|
|
60
|
+
|
|
61
|
+
# general case: return a map:
|
|
62
|
+
#
|
|
63
|
+
# {
|
|
64
|
+
# :exit => :succeed,
|
|
65
|
+
# :result => "the built target...",
|
|
66
|
+
# # optional
|
|
67
|
+
# :log => "Dependencies not met for #{request[:target]}",
|
|
68
|
+
# :tags => ["web"]
|
|
69
|
+
# }
|
|
70
|
+
|
|
71
|
+
# specific case: return just a successful result or nil.
|
|
72
|
+
#
|
|
73
|
+
# "my result"
|
|
74
|
+
|
|
75
|
+
# specific case: succeed with log message
|
|
76
|
+
#
|
|
77
|
+
# "my result", "log..."
|
|
78
|
+
|
|
79
|
+
# If your code needs to ensure that dependencies exist before continuing, use this
|
|
80
|
+
#
|
|
81
|
+
# Fox.ensure socket, deps
|
|
82
|
+
#
|
|
83
|
+
# (It will throw an exception that's caught by the rubbygem, which will return an abort map on your behalf)
|
|
84
|
+
|
|
85
|
+
# If your build fails for some other reason, feel free to raise hell:
|
|
86
|
+
#
|
|
87
|
+
# raise "hell!"
|
|
88
|
+
#
|
|
89
|
+
# the rubbygem will catch and return a build failure map for you.
|
|
90
|
+
|
|
91
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'keminglabs-fox-rubby/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "keminglabs-fox-rubby"
|
|
8
|
+
spec.version = Fox::VERSION
|
|
9
|
+
spec.authors = ["Kevin J. Lynagh"]
|
|
10
|
+
spec.email = ["kevin@keminglabs.com"]
|
|
11
|
+
spec.description = "A rubbygem that makes it easy to write builder processes for the Fox build tool."
|
|
12
|
+
spec.summary = "Fox"
|
|
13
|
+
spec.homepage = "https://github.com/lynaghk/fox"
|
|
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_dependency "ffi-rzmq"
|
|
22
|
+
|
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
24
|
+
spec.add_development_dependency "rake"
|
|
25
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
require "keminglabs-fox-rubby/version"
|
|
2
|
+
require "ffi-rzmq"
|
|
3
|
+
require "json"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
module Fox
|
|
7
|
+
|
|
8
|
+
class Abort < Exception
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
SockPath = "fox"
|
|
12
|
+
Context = ZMQ::Context.new(1)
|
|
13
|
+
Poller = ZMQ::Poller.new
|
|
14
|
+
|
|
15
|
+
# Map of socket -> {path, handler}
|
|
16
|
+
@handlers = {}
|
|
17
|
+
|
|
18
|
+
#Connects to Fox server via ZeroMQ and ensures that all requested dependencies are met.
|
|
19
|
+
#If something isn't met, raises a special exception that's rescued by the main run loop and turned into an abort message.
|
|
20
|
+
def self._assert(raise_p, req, *dependencies)
|
|
21
|
+
deps = dependencies.flatten.uniq.compact
|
|
22
|
+
|
|
23
|
+
return true if deps.empty?
|
|
24
|
+
|
|
25
|
+
sock = Context.socket(ZMQ::REQ)
|
|
26
|
+
sock.connect req[:socket]
|
|
27
|
+
sock.send_string JSON.generate({target: req[:target], dependencies: deps})
|
|
28
|
+
|
|
29
|
+
res = ""
|
|
30
|
+
sock.recv_string res
|
|
31
|
+
if (res == "fox-abort")
|
|
32
|
+
if raise_p
|
|
33
|
+
raise Abort
|
|
34
|
+
else
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def self.assert(req, *dependencies)
|
|
44
|
+
self._assert true, req, dependencies
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def self.register(path, handler)
|
|
49
|
+
FileUtils.mkdir_p SockPath + "/" + File.dirname(path)
|
|
50
|
+
sock = Context.socket(ZMQ::REP)
|
|
51
|
+
sock.bind "ipc://#{SockPath}/#{path}.ipc"
|
|
52
|
+
@handlers[sock] = {handler: handler, path: path}
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def self.start!
|
|
58
|
+
@handlers.each do |sock, h|
|
|
59
|
+
$stderr.puts "Registering handler at: #{h[:path]}"
|
|
60
|
+
Poller.register(sock, ZMQ::POLLIN)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Signal.trap("INT") do
|
|
64
|
+
break
|
|
65
|
+
Context.terminate
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
loop do
|
|
69
|
+
Poller.poll(:blocking)
|
|
70
|
+
Poller.readables.each do |sock|
|
|
71
|
+
req = recv sock
|
|
72
|
+
msg = begin
|
|
73
|
+
parse_handler_response @handlers[sock][:handler].call(req)
|
|
74
|
+
rescue Abort => _
|
|
75
|
+
{exit: "abort"}
|
|
76
|
+
rescue Exception => e
|
|
77
|
+
pp e
|
|
78
|
+
$stderr.puts e
|
|
79
|
+
{exit: "fail", log: e.to_s}
|
|
80
|
+
end
|
|
81
|
+
$stderr.puts "#{msg[:exit]}: #{req[:target]}"
|
|
82
|
+
send! sock, msg
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#TODO: do I really want to make things private?
|
|
88
|
+
#This is just a documentation issue, really.
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def self.send!(sock, msg)
|
|
93
|
+
sock.send_string JSON.generate msg
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def self.recv(sock)
|
|
98
|
+
msg_str = ""
|
|
99
|
+
sock.recv_string msg_str
|
|
100
|
+
JSON.parse msg_str, symbolize_names: true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def self.parse_handler_response(res)
|
|
105
|
+
case res
|
|
106
|
+
when String # a successful build
|
|
107
|
+
{
|
|
108
|
+
exit: "succeed",
|
|
109
|
+
result: res
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
when Array # a successful build with log messages
|
|
113
|
+
{
|
|
114
|
+
exit: "succeed",
|
|
115
|
+
result: res[0],
|
|
116
|
+
log: res[1]
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
when Hash # a full map
|
|
120
|
+
if not (x.key?(:exit) or x.key?("exit"))
|
|
121
|
+
throw "Response needs :exit key with value one of (:succeed, :abort, :fail)"
|
|
122
|
+
end
|
|
123
|
+
res
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: keminglabs-fox-rubby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Kevin J. Lynagh
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-09-25 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: ffi-rzmq
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: bundler
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ~>
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '1.3'
|
|
38
|
+
type: :development
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '1.3'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rake
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
description: A rubbygem that makes it easy to write builder processes for the Fox
|
|
63
|
+
build tool.
|
|
64
|
+
email:
|
|
65
|
+
- kevin@keminglabs.com
|
|
66
|
+
executables: []
|
|
67
|
+
extensions: []
|
|
68
|
+
extra_rdoc_files: []
|
|
69
|
+
files:
|
|
70
|
+
- .gitignore
|
|
71
|
+
- Gemfile
|
|
72
|
+
- README.md
|
|
73
|
+
- Rakefile
|
|
74
|
+
- examples/minimal.rb
|
|
75
|
+
- examples/web_example.rb
|
|
76
|
+
- keminglabs-fox-rubby.gemspec
|
|
77
|
+
- lib/keminglabs-fox-rubby.rb
|
|
78
|
+
- lib/keminglabs-fox-rubby/version.rb
|
|
79
|
+
homepage: https://github.com/lynaghk/fox
|
|
80
|
+
licenses:
|
|
81
|
+
- MIT
|
|
82
|
+
post_install_message:
|
|
83
|
+
rdoc_options: []
|
|
84
|
+
require_paths:
|
|
85
|
+
- lib
|
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
|
+
none: false
|
|
88
|
+
requirements:
|
|
89
|
+
- - ! '>='
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '0'
|
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
|
+
none: false
|
|
94
|
+
requirements:
|
|
95
|
+
- - ! '>='
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '0'
|
|
98
|
+
requirements: []
|
|
99
|
+
rubyforge_project:
|
|
100
|
+
rubygems_version: 1.8.23
|
|
101
|
+
signing_key:
|
|
102
|
+
specification_version: 3
|
|
103
|
+
summary: Fox
|
|
104
|
+
test_files: []
|