guides 0.5.0 → 0.6.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 +4 -0
- data/Gemfile +3 -0
- data/RELEASES.yml +6 -0
- data/Rakefile +33 -0
- data/guides.gemspec +1 -0
- data/lib/guides.rb +11 -1
- data/lib/guides/cli.rb +30 -2
- data/lib/guides/generator.rb +44 -4
- data/lib/guides/helpers.rb +5 -8
- data/lib/guides/preview.rb +50 -0
- data/lib/guides/templates/assets/stylesheets/main.css +2 -2
- data/lib/guides/templates/source/layout.html.erb +4 -0
- data/lib/guides/textile_extensions.rb +1 -1
- data/lib/guides/version.rb +1 -1
- data/spec/build_spec.rb +45 -0
- data/spec/new_spec.rb +18 -0
- data/spec/preview_spec.rb +35 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/cli.rb +113 -0
- data/spec/support/rack.rb +112 -0
- metadata +35 -6
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/RELEASES.yml
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
desc "Prep the release for PackageMaker"
|
2
|
+
task :pkg do
|
3
|
+
system "rm -rf Guides"
|
4
|
+
system "mkdir -p Guides/local/guides/lib"
|
5
|
+
|
6
|
+
`git ls-files -- lib`.split("\n").each do |file|
|
7
|
+
system "mkdir -p #{File.dirname("Guides/local/guides/#{file}")}"
|
8
|
+
system "cp #{file} Guides/local/guides/#{file}"
|
9
|
+
end
|
10
|
+
|
11
|
+
require "rbconfig"
|
12
|
+
|
13
|
+
unless Config::CONFIG["target_cpu"] == "universal"
|
14
|
+
puts "Please use a universal binary copy of ruby"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
unless RUBY_VERSION == "1.9.2"
|
19
|
+
puts "Please use Ruby 1.9.2"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "Regenerating the bundle."
|
24
|
+
|
25
|
+
system "rm -rf bundle"
|
26
|
+
system "bundle --standalone"
|
27
|
+
system "cp -R bundle Guides/local/guides/bundle"
|
28
|
+
|
29
|
+
guides = File.read("bin/guides").sub(/\A#.*/, "#!/usr/local/ruby1.9test/bin/ruby -I /usr/local/guides/bundle -r bundler/setup")
|
30
|
+
|
31
|
+
system "mkdir -p Guides/bin"
|
32
|
+
File.open("Guides/bin/guides", "w") { |file| file.puts guides }
|
33
|
+
end
|
data/guides.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency "rack", "~> 1.2.1"
|
23
23
|
s.add_dependency "RedCloth", "~> 4.1.1"
|
24
24
|
s.add_dependency "thor", "~> 0.14.6"
|
25
|
+
s.add_dependency "thin", "~> 1.2.7"
|
25
26
|
|
26
27
|
s.files = `git ls-files`.split("\n")
|
27
28
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/guides.rb
CHANGED
@@ -5,13 +5,23 @@ require "guides/textile_extensions"
|
|
5
5
|
require "guides/generator"
|
6
6
|
|
7
7
|
module Guides
|
8
|
+
class Error < StandardError
|
9
|
+
def self.status_code(code = nil)
|
10
|
+
define_method(:status_code) { code }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class FormatError < Error; status_code(2) ; end
|
15
|
+
|
8
16
|
class << self
|
9
17
|
def root
|
10
18
|
# TODO: Search for guides.yml
|
11
19
|
File.expand_path(Dir.pwd)
|
12
20
|
end
|
13
21
|
|
14
|
-
def meta
|
22
|
+
def meta(reload = false)
|
23
|
+
@meta = nil if reload
|
24
|
+
|
15
25
|
@meta ||= begin
|
16
26
|
if File.exist?("#{root}/guides.yml")
|
17
27
|
YAML.load_file("#{root}/guides.yml")
|
data/lib/guides/cli.rb
CHANGED
@@ -1,21 +1,27 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "guides/new"
|
3
|
+
require "guides/preview"
|
4
|
+
require "guides/version"
|
3
5
|
|
4
6
|
module Guides
|
5
7
|
class CLI < Thor
|
6
8
|
ASSETS_ROOT = File.expand_path("../assets", __FILE__)
|
7
9
|
SOURCE_ROOT = File.expand_path("../source", __FILE__)
|
8
10
|
|
11
|
+
def self.basename
|
12
|
+
"guides"
|
13
|
+
end
|
14
|
+
|
9
15
|
desc "new NAME", "create a new directory of guides"
|
10
16
|
method_option "name", :type => :string
|
11
17
|
def new(name)
|
12
18
|
invoke "guides:new:copy", [name, options[:name] || name]
|
13
19
|
end
|
14
20
|
|
15
|
-
desc "
|
21
|
+
desc "build", "build the guides output"
|
16
22
|
method_option "only", :type => :array
|
17
23
|
method_option "clean", :type => :boolean
|
18
|
-
def
|
24
|
+
def build
|
19
25
|
FileUtils.rm_rf("#{Guides.root}/output") if options[:clean]
|
20
26
|
require "guides/generator"
|
21
27
|
|
@@ -27,9 +33,31 @@ module Guides
|
|
27
33
|
generator.generate
|
28
34
|
end
|
29
35
|
|
36
|
+
map "-v" => "version"
|
37
|
+
map "--version" => "version"
|
38
|
+
|
39
|
+
desc "version", "print the current version"
|
40
|
+
def version
|
41
|
+
shell.say "Guides #{Guides::VERSION}", :green
|
42
|
+
end
|
43
|
+
|
30
44
|
desc "preview", "preview the guides as you work"
|
31
45
|
def preview
|
46
|
+
Preview.start
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "update", "when running from the pkg, updates the gem"
|
50
|
+
def update
|
51
|
+
Update.start
|
52
|
+
end
|
32
53
|
|
54
|
+
no_tasks do
|
55
|
+
def invoke_task(*)
|
56
|
+
super
|
57
|
+
rescue Guides::Error => e
|
58
|
+
shell.say e.message, :red
|
59
|
+
exit e.status_code
|
60
|
+
end
|
33
61
|
end
|
34
62
|
end
|
35
63
|
end
|
data/lib/guides/generator.rb
CHANGED
@@ -85,6 +85,33 @@ module Guides
|
|
85
85
|
copy_assets
|
86
86
|
end
|
87
87
|
|
88
|
+
def generate_guide(guide, output_file)
|
89
|
+
return unless generate?(guide, output_file)
|
90
|
+
|
91
|
+
puts "Generating #{output_file}"
|
92
|
+
File.open(File.join(output_dir, output_file), 'w') do |f|
|
93
|
+
view = ActionView::Base.new(source_dir, :edge => edge)
|
94
|
+
view.extend(Helpers)
|
95
|
+
|
96
|
+
if guide =~ /\.html\.erb$/
|
97
|
+
# Generate the special pages like the home.
|
98
|
+
view.render("sections")
|
99
|
+
type = @edge ? "edge" : "normal"
|
100
|
+
result = view.render(:layout => 'layout', :file => guide, :locals => {:guide_type => type})
|
101
|
+
else
|
102
|
+
body = File.read(File.join(source_dir, guide))
|
103
|
+
body = set_header_section(body, view)
|
104
|
+
body = set_index(body, view)
|
105
|
+
|
106
|
+
result = view.render(:layout => 'layout', :text => textile(body))
|
107
|
+
|
108
|
+
warn_about_broken_links(result) if @warnings
|
109
|
+
end
|
110
|
+
|
111
|
+
f.write result
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
88
115
|
private
|
89
116
|
def generate_guides
|
90
117
|
guides_to_generate.each do |guide|
|
@@ -114,6 +141,12 @@ module Guides
|
|
114
141
|
def generate?(source_file, output_file)
|
115
142
|
fin = File.join(source_dir, source_file)
|
116
143
|
fout = File.join(output_dir, output_file)
|
144
|
+
|
145
|
+
if File.exists?(fout) && File.mtime(fout) < File.mtime(File.join(Guides.root, "guides.yml"))
|
146
|
+
Guides.meta(true)
|
147
|
+
return true
|
148
|
+
end
|
149
|
+
|
117
150
|
all || !File.exists?(fout) || File.mtime(fout) < File.mtime(fin)
|
118
151
|
end
|
119
152
|
|
@@ -148,8 +181,15 @@ module Guides
|
|
148
181
|
new_body = body.gsub(/(.*?)endprologue\./m, '').strip
|
149
182
|
header = $1
|
150
183
|
|
151
|
-
header
|
152
|
-
|
184
|
+
unless header
|
185
|
+
raise FormatError, "A prologue is required. Use 'endprologue.' to separate the prologue from the main body."
|
186
|
+
end
|
187
|
+
|
188
|
+
if header =~ /h2\.(.*)/
|
189
|
+
page_title = "#{@meta["title"]}: #{$1.strip}"
|
190
|
+
else
|
191
|
+
raise FormatError, "A title is required. Use the 'h2.' declaration to denote the title."
|
192
|
+
end
|
153
193
|
|
154
194
|
header = textile(header)
|
155
195
|
|
@@ -192,8 +232,8 @@ module Guides
|
|
192
232
|
|
193
233
|
def textile(body, lite_mode=false)
|
194
234
|
# If the issue with notextile is fixed just remove the wrapper.
|
195
|
-
with_workaround_for_notextile(body) do |
|
196
|
-
t = RedCloth.new(
|
235
|
+
with_workaround_for_notextile(body) do |new_body|
|
236
|
+
t = RedCloth.new(new_body)
|
197
237
|
t.hard_breaks = false
|
198
238
|
t.lite_mode = lite_mode
|
199
239
|
t.to_html(:notestuff, :plusplus, :code, :tip)
|
data/lib/guides/helpers.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
module Guides
|
2
2
|
module Helpers
|
3
|
-
def full_index
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
3
|
def clickable_index
|
8
|
-
|
4
|
+
all_guides = Guides.meta["index"]
|
9
5
|
|
10
|
-
total_guides =
|
6
|
+
total_guides = all_guides.inject(0) do |sum, (name, guides)|
|
11
7
|
sum + guides.size
|
12
8
|
end
|
13
9
|
|
14
10
|
lgroup, rgroup, counted_guides = {}, {}, 0
|
15
11
|
|
16
|
-
|
12
|
+
all_guides.each do |name, guides|
|
17
13
|
if counted_guides > (total_guides / 2.0)
|
18
14
|
rgroup[name] = guides
|
19
15
|
else
|
@@ -39,7 +35,7 @@ module Guides
|
|
39
35
|
end
|
40
36
|
|
41
37
|
def author(name, nick, image = 'credits_pic_blank.gif', &block)
|
42
|
-
image = "images/#{image}"
|
38
|
+
image = "images/#{image}" unless image =~ /^http/
|
43
39
|
|
44
40
|
result = content_tag(:img, nil, :src => image, :class => 'left pic', :alt => name)
|
45
41
|
result << content_tag(:h3, name)
|
@@ -53,3 +49,4 @@ module Guides
|
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
52
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "rack"
|
2
|
+
|
3
|
+
module Guides
|
4
|
+
class App
|
5
|
+
LOCAL_ASSETS = File.expand_path("../templates/assets", __FILE__)
|
6
|
+
SOURCE_ASSETS = File.join(Guides.root, "assets")
|
7
|
+
SOURCE_TEMPLATES = File.join(Guides.root, "source")
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@local = Rack::File.new(LOCAL_ASSETS)
|
11
|
+
@source = Rack::File.new(SOURCE_ASSETS)
|
12
|
+
@output = Rack::File.new(File.join(Guides.root, "output"))
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
path = env["PATH_INFO"]
|
17
|
+
|
18
|
+
case path
|
19
|
+
when "/"
|
20
|
+
env["PATH_INFO"] = "/index.html"
|
21
|
+
return call(env)
|
22
|
+
when /(.*).html/
|
23
|
+
name = $1
|
24
|
+
generator = Guides::Generator.new({})
|
25
|
+
source_file = Dir["#{SOURCE_TEMPLATES}/#{name}.{html.erb,textile}"].first
|
26
|
+
|
27
|
+
unless source_file
|
28
|
+
return [404, {"Content-Type" => "text/html"}, ["#{name} not found"]]
|
29
|
+
end
|
30
|
+
|
31
|
+
generator.send(:generate_guide, File.basename(source_file), "#{name}.html")
|
32
|
+
return @output.call(env)
|
33
|
+
else
|
34
|
+
source = @source.call(env)
|
35
|
+
return source if source.first == 200
|
36
|
+
return @local.call(env)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Preview < Rack::Server
|
42
|
+
def self.start(*)
|
43
|
+
super :host => '0.0.0.0', :Port => 9292, :server => "thin"
|
44
|
+
end
|
45
|
+
|
46
|
+
def app
|
47
|
+
@app ||= App.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -24,7 +24,7 @@ dl dt { font-weight: bold; }
|
|
24
24
|
dd { margin-left: 1.5em;}
|
25
25
|
|
26
26
|
pre,code { margin: 1.5em 0; overflow: auto; color: #222;}
|
27
|
-
pre,code,tt {
|
27
|
+
pre,code,tt,ins {
|
28
28
|
font-size: 1em;
|
29
29
|
font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
|
30
30
|
line-height: 1.5;
|
@@ -384,7 +384,7 @@ div.code_container {
|
|
384
384
|
margin: 0.25em 0 1.5em 0;
|
385
385
|
}
|
386
386
|
|
387
|
-
.note tt, .info tt {border:none; background: none; padding: 0;}
|
387
|
+
.note tt, .note ins, .info tt, .note ins {border:none; background: none; padding: 0;}
|
388
388
|
|
389
389
|
#mainCol ul li {
|
390
390
|
list-style:none;
|
@@ -48,8 +48,12 @@
|
|
48
48
|
|
49
49
|
<div id="feature">
|
50
50
|
<div class="wrapper">
|
51
|
+
<% if header_section = yield(:header_section).presence %>
|
52
|
+
<%= header_section %>
|
53
|
+
<% else %>
|
51
54
|
<h2><%= Guides.meta["title"] %></h2>
|
52
55
|
<p><%= Guides.meta["description"] %></p>
|
56
|
+
<% end %>
|
53
57
|
</div>
|
54
58
|
</div>
|
55
59
|
|
data/lib/guides/version.rb
CHANGED
data/spec/build_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "guides build" do
|
4
|
+
before(:all) do
|
5
|
+
reset_tmp
|
6
|
+
guides "new", "sample" and wait
|
7
|
+
Dir.chdir tmp.join("sample")
|
8
|
+
guides "build" and wait
|
9
|
+
end
|
10
|
+
|
11
|
+
it "generates the app" do
|
12
|
+
out.should =~ /Generating contribute.html.*Generating credits.html.*Generating index.html/m
|
13
|
+
end
|
14
|
+
|
15
|
+
it "generates assets" do
|
16
|
+
files = Dir["output/*"]
|
17
|
+
|
18
|
+
File.directory?("output/images").should be_true
|
19
|
+
File.directory?("output/javascripts").should be_true
|
20
|
+
File.directory?("output/stylesheets").should be_true
|
21
|
+
File.file?("output/javascripts/guides.js").should be_true
|
22
|
+
File.file?("output/stylesheets/main.css").should be_true
|
23
|
+
File.file?("output/stylesheets/overrides.style.css").should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "does nothing if run twice in a row" do
|
27
|
+
guides "build"
|
28
|
+
out.should be_blank
|
29
|
+
end
|
30
|
+
|
31
|
+
it "re-runs if run with --clean" do
|
32
|
+
guides "build", "--clean"
|
33
|
+
out.should =~ /Generating contribute.html.*Generating credits.html.*Generating index.html/m
|
34
|
+
end
|
35
|
+
|
36
|
+
it "creates index.html" do
|
37
|
+
File.read("output/index.html").should =~ /<a href="contribute.html">/
|
38
|
+
end
|
39
|
+
|
40
|
+
it "creates contribute.html" do
|
41
|
+
contribute = File.read("output/contribute.html")
|
42
|
+
contribute.should =~ /<h2>Contribute<\/h2>/
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
data/spec/new_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "guides new" do
|
4
|
+
before(:each) do
|
5
|
+
reset_tmp
|
6
|
+
end
|
7
|
+
|
8
|
+
it "prints an error if new is called with no name" do
|
9
|
+
guides "new", :track_stderr => true
|
10
|
+
err.should =~ /"new" was called incorrectly/
|
11
|
+
end
|
12
|
+
|
13
|
+
it "generates an app if a name is given" do
|
14
|
+
guides "new", "sample"
|
15
|
+
out.should =~ /create.*guides\.yml/
|
16
|
+
tmp.join("sample", "guides.yml").read.should =~ /\Atitle: sample/
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "guides generate" do
|
4
|
+
before(:all) do
|
5
|
+
reset_tmp
|
6
|
+
guides "new", "sample" and wait
|
7
|
+
Dir.chdir tmp.join("sample")
|
8
|
+
guides "build" and wait
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
Dir.chdir(tmp)
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
host! :preview
|
17
|
+
launch_test_server
|
18
|
+
guides "preview"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "downloads the index at /" do
|
22
|
+
get "/"
|
23
|
+
should_respond_with 200, /<!DOCTYPE html PUBLIC.*>.*<h3>Start Here<\/h3>/m
|
24
|
+
end
|
25
|
+
|
26
|
+
it "downloads the index at /index.html" do
|
27
|
+
get "/"
|
28
|
+
should_respond_with 200, /<!DOCTYPE html PUBLIC.*>.*<h3>Start Here<\/h3>/m
|
29
|
+
end
|
30
|
+
|
31
|
+
it "downloads contribute at /contribute.html" do
|
32
|
+
get "/contribute.html"
|
33
|
+
should_respond_with 200, /<!DOCTYPE html PUBLIC.*>.*<h2>Contribute<\/h2>/m
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "pathname"
|
3
|
+
require "support/cli"
|
4
|
+
require "support/rack"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
include SpecHelpers
|
8
|
+
|
9
|
+
def tmp
|
10
|
+
@tmp ||= Pathname.new(File.expand_path("../../tmp", __FILE__))
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_tmp
|
14
|
+
FileUtils.rm_rf(tmp)
|
15
|
+
FileUtils.mkdir_p(tmp)
|
16
|
+
Dir.chdir(tmp)
|
17
|
+
end
|
18
|
+
|
19
|
+
config.before(:suite) do
|
20
|
+
reset_tmp
|
21
|
+
end
|
22
|
+
end
|
data/spec/support/cli.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require "guides"
|
2
|
+
require "guides/cli"
|
3
|
+
|
4
|
+
module SpecHelpers
|
5
|
+
attr_reader :stdin, :stdout, :stderr
|
6
|
+
|
7
|
+
def env
|
8
|
+
@env ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def guides(*argv)
|
12
|
+
opts = Hash === argv.last ? argv.pop : {}
|
13
|
+
|
14
|
+
kill!
|
15
|
+
create_pipes
|
16
|
+
|
17
|
+
@pid = Process.fork do
|
18
|
+
Dir.chdir opts[:chdir] if opts[:chdir]
|
19
|
+
|
20
|
+
@stdout.close
|
21
|
+
@stdin.close
|
22
|
+
@stderr.close
|
23
|
+
|
24
|
+
STDOUT.reopen @stdout_child
|
25
|
+
STDIN.reopen @stdin_child
|
26
|
+
|
27
|
+
if opts[:track_stderr] || argv.first == 'preview'
|
28
|
+
STDERR.reopen @stderr_child
|
29
|
+
end
|
30
|
+
|
31
|
+
env.each do |key, val|
|
32
|
+
ENV[key] = val
|
33
|
+
end
|
34
|
+
|
35
|
+
Guides::CLI.start(argv)
|
36
|
+
end
|
37
|
+
|
38
|
+
if argv.first == 'preview'
|
39
|
+
wait_for_preview_server
|
40
|
+
end
|
41
|
+
|
42
|
+
@stdout_child.close
|
43
|
+
@stdin_child.close
|
44
|
+
@stderr_child.close
|
45
|
+
@pid
|
46
|
+
end
|
47
|
+
|
48
|
+
def wait_for_preview_server
|
49
|
+
s = TCPSocket.new('0.0.0.0', 9292)
|
50
|
+
rescue Errno::ECONNREFUSED
|
51
|
+
sleep 0.2
|
52
|
+
retry
|
53
|
+
ensure
|
54
|
+
s.close
|
55
|
+
end
|
56
|
+
|
57
|
+
def out_until_block(io = stdout)
|
58
|
+
# read 1 first so we wait until the process is done processing the last write
|
59
|
+
chars = nil
|
60
|
+
|
61
|
+
IO.select( [ io ] )
|
62
|
+
|
63
|
+
chars = io.read(1)
|
64
|
+
sleep 0.05
|
65
|
+
|
66
|
+
loop do
|
67
|
+
chars << io.read_nonblock(1000)
|
68
|
+
sleep 0.05
|
69
|
+
end
|
70
|
+
rescue Errno::EAGAIN, EOFError => e
|
71
|
+
chars || ""
|
72
|
+
end
|
73
|
+
|
74
|
+
def input(line, opts = {})
|
75
|
+
if on = opts[:on]
|
76
|
+
should_block_on on
|
77
|
+
end
|
78
|
+
stdin << "#{line}\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
def wait
|
82
|
+
return unless @pid
|
83
|
+
|
84
|
+
pid, status = Process.wait2(@pid, 0)
|
85
|
+
|
86
|
+
@exit_status = status
|
87
|
+
@pid = nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def exit_status
|
91
|
+
wait
|
92
|
+
@exit_status
|
93
|
+
end
|
94
|
+
|
95
|
+
def kill!
|
96
|
+
Process.kill(9, @pid) if @pid
|
97
|
+
end
|
98
|
+
|
99
|
+
def out
|
100
|
+
stdout.read
|
101
|
+
end
|
102
|
+
|
103
|
+
def err
|
104
|
+
stderr.read
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_pipes
|
108
|
+
@stdout, @stdout_child = IO.pipe
|
109
|
+
@stdin_child, @stdin = IO.pipe
|
110
|
+
@stderr, @stderr_child = IO.pipe
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'faraday'
|
3
|
+
require 'rack'
|
4
|
+
require 'webrick'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
Thread.abort_on_exception = true
|
8
|
+
|
9
|
+
module SpecHelpers
|
10
|
+
RACK_ENV_KEYS = [ 'PATH_INFO', 'REQUEST_METHOD', 'QUERY_STRING', 'rack.input',
|
11
|
+
'HTTP_X_ZOMG' ]
|
12
|
+
|
13
|
+
def self.launch_test_server
|
14
|
+
@test_server ||= begin
|
15
|
+
app = lambda do |env|
|
16
|
+
ret = env.slice(*RACK_ENV_KEYS)
|
17
|
+
ret['rack.input'] = ret['rack.input'].read if ret['rack.input']
|
18
|
+
[ 200, { 'Content-Type' => 'text/plain' }, ret.inspect ]
|
19
|
+
end
|
20
|
+
|
21
|
+
t = Thread.new do
|
22
|
+
logger = WEBrick::Log.new(nil, WEBrick::BasicLog::WARN)
|
23
|
+
Rack::Handler::WEBrick.run(app, :Host => '0.0.0.0', :Port => 9293,
|
24
|
+
:Logger => logger, :AccessLog => [])
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
s = TCPSocket.new('0.0.0.0', 9293)
|
29
|
+
rescue Errno::ECONNREFUSED
|
30
|
+
sleep 0.2
|
31
|
+
retry
|
32
|
+
end
|
33
|
+
|
34
|
+
s.close
|
35
|
+
t
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def launch_test_server
|
40
|
+
SpecHelpers.launch_test_server
|
41
|
+
end
|
42
|
+
|
43
|
+
%w( get post put delete head ).each do |method|
|
44
|
+
class_eval <<-RUBY
|
45
|
+
def #{method}(uri, *args)
|
46
|
+
request(:#{method}, uri, *args)
|
47
|
+
end
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_reader :response
|
52
|
+
attr_reader :host
|
53
|
+
|
54
|
+
def host!(host)
|
55
|
+
@host = host
|
56
|
+
end
|
57
|
+
|
58
|
+
def request(method, uri, *args)
|
59
|
+
uri = URI(uri)
|
60
|
+
host = uri.host || @host
|
61
|
+
scheme = uri.scheme || 'http'
|
62
|
+
headers = Hash === args.last ? args.pop : {}
|
63
|
+
|
64
|
+
if host == :preview
|
65
|
+
ip = host = 'http://localhost:9292'
|
66
|
+
else
|
67
|
+
ip = ENV['STROBEAPP_URL']
|
68
|
+
end
|
69
|
+
|
70
|
+
headers['Host'] = host
|
71
|
+
headers['Authorization'] = 'basic x:x' # hac to bypass varnish
|
72
|
+
|
73
|
+
conn = Faraday::Connection.new(:url => ip) do |c|
|
74
|
+
c.use Faraday::Adapter::NetHttp
|
75
|
+
c.headers.merge! headers
|
76
|
+
end
|
77
|
+
|
78
|
+
path = uri.path
|
79
|
+
path = "#{path}?#{uri.query}" if uri.query
|
80
|
+
|
81
|
+
@response = conn.run_request(method, path, args.first, {})
|
82
|
+
end
|
83
|
+
|
84
|
+
def should_respond_with(status, body = nil, hdrs = {})
|
85
|
+
@response.status.should == status
|
86
|
+
|
87
|
+
if body.is_a?(Regexp)
|
88
|
+
@response.body.should =~ body
|
89
|
+
elsif body
|
90
|
+
@response.body.should == body
|
91
|
+
end
|
92
|
+
|
93
|
+
hdrs.each do |hdr, val|
|
94
|
+
@response.headers[hdr].should == val
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def should_have_env(env)
|
99
|
+
@response.status.should == 200
|
100
|
+
empty = RACK_ENV_KEYS - env.keys
|
101
|
+
actual = eval(@response.body)
|
102
|
+
|
103
|
+
env.each do |key, val|
|
104
|
+
actual[key].should == val
|
105
|
+
end
|
106
|
+
|
107
|
+
empty.each do |key|
|
108
|
+
actual[key].should be_blank
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 6
|
8
|
+
- 1
|
9
|
+
version: 0.6.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Yehuda Katz
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-13 00:00:00 -08:00
|
18
18
|
default_executable: guides
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -92,6 +92,21 @@ dependencies:
|
|
92
92
|
version: 0.14.6
|
93
93
|
type: :runtime
|
94
94
|
version_requirements: *id005
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: thin
|
97
|
+
prerelease: false
|
98
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
segments:
|
104
|
+
- 1
|
105
|
+
- 2
|
106
|
+
- 7
|
107
|
+
version: 1.2.7
|
108
|
+
type: :runtime
|
109
|
+
version_requirements: *id006
|
95
110
|
description: A tool for creating version controlled guides for open source projects, based on the Rails Guides framework
|
96
111
|
email:
|
97
112
|
- wycats@gmail.com
|
@@ -104,6 +119,8 @@ extra_rdoc_files: []
|
|
104
119
|
files:
|
105
120
|
- .gitignore
|
106
121
|
- Gemfile
|
122
|
+
- RELEASES.yml
|
123
|
+
- Rakefile
|
107
124
|
- bin/guides
|
108
125
|
- guides.gemspec
|
109
126
|
- lib/guides.rb
|
@@ -113,6 +130,7 @@ files:
|
|
113
130
|
- lib/guides/indexer.rb
|
114
131
|
- lib/guides/levenshtein.rb
|
115
132
|
- lib/guides/new.rb
|
133
|
+
- lib/guides/preview.rb
|
116
134
|
- lib/guides/templates/assets/images/book_icon.gif
|
117
135
|
- lib/guides/templates/assets/images/bullet.gif
|
118
136
|
- lib/guides/templates/assets/images/chapters_icon.gif
|
@@ -219,6 +237,12 @@ files:
|
|
219
237
|
- lib/guides/textile_extensions.rb
|
220
238
|
- lib/guides/version.rb
|
221
239
|
- lib/guides/w3c_validator.rb
|
240
|
+
- spec/build_spec.rb
|
241
|
+
- spec/new_spec.rb
|
242
|
+
- spec/preview_spec.rb
|
243
|
+
- spec/spec_helper.rb
|
244
|
+
- spec/support/cli.rb
|
245
|
+
- spec/support/rack.rb
|
222
246
|
has_rdoc: true
|
223
247
|
homepage: http://yehudakatz.com
|
224
248
|
licenses: []
|
@@ -253,5 +277,10 @@ rubygems_version: 1.3.7
|
|
253
277
|
signing_key:
|
254
278
|
specification_version: 3
|
255
279
|
summary: Extracting the Rails Guides framework for the rest of us
|
256
|
-
test_files:
|
257
|
-
|
280
|
+
test_files:
|
281
|
+
- spec/build_spec.rb
|
282
|
+
- spec/new_spec.rb
|
283
|
+
- spec/preview_spec.rb
|
284
|
+
- spec/spec_helper.rb
|
285
|
+
- spec/support/cli.rb
|
286
|
+
- spec/support/rack.rb
|