widow 0.1.0 → 0.2.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 +4 -4
- data/bin/widow +18 -121
- data/lib/widow.rb +160 -0
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35ef838be5110f77688f4f4cb226ac2635d7daba
|
4
|
+
data.tar.gz: 64948953b16fe1a60bcf135089a480e4becbe836
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7e929dcb1861b2c5389f5aea8e11a7d9d99ee9a8fce67d98826d6264b8d4a438411005e346318c80e1f6b3c54ee289de0bd282b7457596dbe5cdcfa1e222836
|
7
|
+
data.tar.gz: bea70a334096a54e2334aeea16c98731aa18a7b2d341425672cf91e8be22c215ac856f7609bf38663ab145003f2292ad2716bd839b585a726b1466542064444b
|
data/bin/widow
CHANGED
@@ -1,127 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize args = {}
|
14
|
-
opts = args[:opts]
|
15
|
-
return if opts.empty?
|
16
|
-
|
17
|
-
case opts.first
|
18
|
-
when /cut/
|
19
|
-
if opts[1]
|
20
|
-
cut *opts[1].split(':')
|
21
|
-
else
|
22
|
-
cut
|
23
|
-
end
|
24
|
-
when /spin/
|
25
|
-
if opts[1]
|
26
|
-
spin *opts[1].split(':')
|
27
|
-
else
|
28
|
-
cut
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def cut from = Dir.pwd, to = Dir.pwd
|
34
|
-
puts from = Pathname.new(from)
|
35
|
-
puts to = Pathname.new(to)
|
36
|
-
Find.find from do |path|
|
37
|
-
path = Pathname.new path
|
38
|
-
next if path == from
|
39
|
-
make from, path.relative_path_from(from), to
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def spin src = Dir.pwd, bin = Dir.pwd
|
44
|
-
src = Pathname.new src
|
45
|
-
bin = Pathname.new bin
|
46
|
-
|
47
|
-
allowed_templates = Tilt.lazy_map.map do |ext, _|
|
48
|
-
begin
|
49
|
-
Tilt[ext]
|
50
|
-
next ext
|
51
|
-
rescue LoadError
|
52
|
-
next nil
|
53
|
-
end
|
54
|
-
end.compact
|
55
|
-
|
56
|
-
Rack::Handler.default.run(
|
57
|
-
Proc.new do |env|
|
58
|
-
name = Pathname.new env["PATH_INFO"][1..-1]
|
59
|
-
file = bin + name
|
60
|
-
original = src + name
|
61
|
-
puts original
|
62
|
-
unless original.exist?
|
63
|
-
matching_templates = allowed_templates.select do |ext|
|
64
|
-
next Tilt[ext].metadata[:mime_type] == case name.extname[1..-1]
|
65
|
-
when 'js' then 'application/javascript'
|
66
|
-
when 'css' then 'text/css'
|
67
|
-
when 'html' then 'text/html'
|
68
|
-
else nil
|
69
|
-
end
|
70
|
-
end
|
71
|
-
original = Pathname.glob(src + "#{name.basename name.extname}.{#{matching_templates.join ?,}}").first
|
72
|
-
end
|
73
|
-
puts original
|
74
|
-
next [404, {'Content-Type' => 'text/html'}, ["File not found!"]] if original.nil? || !original.exist?
|
75
|
-
|
76
|
-
begin
|
77
|
-
make src, original.relative_path_from(src), bin if !file.exist? || file.mtime < original.mtime
|
78
|
-
next [200, {'Content-Type' => 'text/html'}, [file.file? ? file.read : '']]
|
79
|
-
rescue RuntimeError, LoadError => e
|
80
|
-
next [502, {'Content-Type' => 'text/html'}, [e.message]]
|
81
|
-
end
|
82
|
-
end,
|
83
|
-
Port: 8888
|
84
|
-
)
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
# proxies or renders a file based on it's properties and tilt capacity
|
89
|
-
def make root, file, to
|
90
|
-
unless Tilt.registered? file.extname[1..-1].to_s
|
91
|
-
proxy root, file, to
|
92
|
-
return
|
93
|
-
end
|
94
|
-
|
95
|
-
begin
|
96
|
-
render root, file, to
|
97
|
-
rescue RuntimeError, LoadError => e
|
98
|
-
puts e.message
|
99
|
-
proxy root, file, to
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# creates a carbon copy of a file elsewhere
|
104
|
-
def proxy root, file, to
|
105
|
-
to.mkpath unless to.exist?
|
106
|
-
obj = to + file
|
107
|
-
src = root + file
|
108
|
-
if src.directory?
|
109
|
-
obj.mkpath unless obj.exist?
|
110
|
-
elsif src.file?
|
111
|
-
FileUtils.cp src, obj
|
112
|
-
end
|
2
|
+
require 'thor'
|
3
|
+
require 'widow'
|
4
|
+
|
5
|
+
class Spiderling < Thor
|
6
|
+
desc "cut", "Compile files from current directory into current directory. Copies files that cannot be processed by tilt"
|
7
|
+
method_option :from, type: :string, desc: "Defaults to current directory"
|
8
|
+
method_option :to, type: :string, desc: "Defaults to current directory"
|
9
|
+
def cut
|
10
|
+
Widow.new.cut options
|
113
11
|
end
|
114
12
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
File.write to + "#{file.basename file.extname}.#{type}", tilt.render
|
13
|
+
|
14
|
+
|
15
|
+
desc "spin", "Start a webserver on localhost and serve files from the destination forlder, compiling them as necessary"
|
16
|
+
method_option :from, type: :string, desc: "Defaults to current directory"
|
17
|
+
method_option :to, type: :string, desc: "Defaults to current directory"
|
18
|
+
method_option :port, type: :numeric, desc: "Defaults to 8888"
|
19
|
+
def spin
|
20
|
+
Widow.new.spin options
|
124
21
|
end
|
125
22
|
end
|
126
23
|
|
127
|
-
|
24
|
+
Spiderling.start
|
data/lib/widow.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'tilt'
|
3
|
+
require 'find'
|
4
|
+
require 'pathname'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'rack'
|
7
|
+
|
8
|
+
class Widow
|
9
|
+
class CompileError < Exception
|
10
|
+
def initialize filename, exception
|
11
|
+
super "#{filename} failed to compile:\n#{exception.message}\n\t#{exception.backtrace.join "\n\t"}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def cut options = {}
|
16
|
+
options = {from: Pathname.pwd, to: Pathname.pwd}.merge options
|
17
|
+
from = Pathname.new(options[:from])
|
18
|
+
to = Pathname.new(options[:to])
|
19
|
+
exclude = Exclude.new from
|
20
|
+
|
21
|
+
Find.find from do |path|
|
22
|
+
path = Pathname.new path
|
23
|
+
next if path == from
|
24
|
+
if exclude.ingnored? path
|
25
|
+
log info: "#{path} ignored"
|
26
|
+
next
|
27
|
+
end
|
28
|
+
begin
|
29
|
+
make from, path.relative_path_from(from), to
|
30
|
+
rescue CompileError
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
def spin options = {}
|
37
|
+
options = {from: Pathname.pwd, to: Pathname.pwd, port: 8888}.merge options
|
38
|
+
from = Pathname.new(options[:from])
|
39
|
+
to = Pathname.new(options[:to])
|
40
|
+
exclude = Exclude.new from
|
41
|
+
|
42
|
+
allowed_templates = Tilt.lazy_map.map do |ext, _|
|
43
|
+
begin
|
44
|
+
Tilt[ext]
|
45
|
+
next ext
|
46
|
+
rescue LoadError
|
47
|
+
next
|
48
|
+
end
|
49
|
+
end.compact
|
50
|
+
|
51
|
+
Rack::Handler.default.run(
|
52
|
+
Proc.new do |env|
|
53
|
+
name = Pathname.new env["PATH_INFO"][1..-1]
|
54
|
+
log info: "#{name} requested"
|
55
|
+
file = bin + name
|
56
|
+
original = src + name
|
57
|
+
unless original.exist?
|
58
|
+
matching_templates = allowed_templates.select do |ext|
|
59
|
+
next Tilt[ext].metadata[:mime_type] == case name.extname[1..-1]
|
60
|
+
when 'js' then 'application/javascript'
|
61
|
+
when 'css' then 'text/css'
|
62
|
+
when 'html' then 'text/html'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
original = Pathname.glob(src + "#{name.basename name.extname}.{#{matching_templates.join ?,}}").first
|
66
|
+
end
|
67
|
+
next [404, {'Content-Type' => 'text/html'}, ["File not found!"]] if exclude.ingnored?(original) || original.nil? || !original.exist?
|
68
|
+
|
69
|
+
begin
|
70
|
+
make src, original.relative_path_from(src), bin if !file.exist? || file.mtime < original.mtime
|
71
|
+
next [200, {'Content-Type' => 'text/html'}, [file.file? ? file.read : '']]
|
72
|
+
rescue CompileError => e
|
73
|
+
next [502, {'Content-Type' => 'text/html'}, [e.message]]
|
74
|
+
end
|
75
|
+
end,
|
76
|
+
Port: options[:port]
|
77
|
+
)
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
class Exclude
|
83
|
+
def initialize root_dir
|
84
|
+
@patterns = Pathname.glob("#{root_dir}/**/.widowignore").map do |file|
|
85
|
+
next [file, File.readlines(file)]
|
86
|
+
end.to_h.map do |file, lines|
|
87
|
+
lines.map do |line|
|
88
|
+
/^#{file.dirname}\/#{line}/ unless line =~ /^\s*$/
|
89
|
+
end.compact
|
90
|
+
end.flatten(1) << /.*\/\.widowignore$/
|
91
|
+
end
|
92
|
+
|
93
|
+
def ingnored? file
|
94
|
+
return @patterns.any? do |pattern|
|
95
|
+
file.to_s =~ pattern
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# proxies or renders a file based on it's properties and tilt capacity
|
101
|
+
# throws a CompileError when the file fails to compile
|
102
|
+
def make root, file, to
|
103
|
+
unless Tilt.registered? file.extname[1..-1].to_s
|
104
|
+
proxy root, file, to
|
105
|
+
return
|
106
|
+
end
|
107
|
+
|
108
|
+
begin
|
109
|
+
render root, file, to
|
110
|
+
rescue LoadError
|
111
|
+
log warning: "#{file} has a Tilt template that cannot be loaded"
|
112
|
+
proxy root, file, to
|
113
|
+
rescue CompileError => e
|
114
|
+
log error: e
|
115
|
+
raise e
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# creates a carbon copy of a file elsewhere
|
120
|
+
def proxy root, file, to
|
121
|
+
to.mkpath unless to.exist?
|
122
|
+
obj = to + file
|
123
|
+
src = root + file
|
124
|
+
return if src == obj
|
125
|
+
if src.directory?
|
126
|
+
obj.mkpath unless obj.exist?
|
127
|
+
elsif src.file?
|
128
|
+
FileUtils.cp src, obj
|
129
|
+
end
|
130
|
+
log info: "\t#{src} => #{src}"
|
131
|
+
end
|
132
|
+
|
133
|
+
# Takes a file and tries to render it through tilt to the destination directory
|
134
|
+
# Throws load error when tilt template is not resolvable
|
135
|
+
# Throws a BuildError when on an internal error
|
136
|
+
def render root, file, to
|
137
|
+
tilt = Tilt.new root + file
|
138
|
+
type = case tilt.metadata[:mime_type]
|
139
|
+
when 'application/javascript' then 'js'
|
140
|
+
when 'text/css' then 'css'
|
141
|
+
else 'html'
|
142
|
+
end
|
143
|
+
|
144
|
+
begin
|
145
|
+
dest = to + "#{file.basename file.extname}.#{type}"
|
146
|
+
File.write dest, tilt.render
|
147
|
+
log info: "\t#{tilt.file} => #{dest}"
|
148
|
+
rescue LoadError => e
|
149
|
+
raise e
|
150
|
+
rescue Exception => e
|
151
|
+
raise CompileError.new root + file, e
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def log line
|
156
|
+
line.each do |level , string|
|
157
|
+
puts "#{level}: #{string}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: widow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Victorovich Matveev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,7 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.14'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.19'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tilt
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - "~>"
|
@@ -39,7 +53,7 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '2.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: rack
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
@@ -61,6 +75,7 @@ extensions: []
|
|
61
75
|
extra_rdoc_files: []
|
62
76
|
files:
|
63
77
|
- bin/widow
|
78
|
+
- lib/widow.rb
|
64
79
|
homepage: https://github.com/strigonLeader/widow
|
65
80
|
licenses:
|
66
81
|
- MIT
|