hawkins 0.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,116 +0,0 @@
1
- require 'pathname'
2
- require 'rack'
3
- require 'safe_yaml/load'
4
- require 'set'
5
-
6
- module Hawkins
7
- class IsolationInjector
8
- attr_reader :site_root
9
- attr_reader :isolation_file
10
-
11
- def initialize(options={})
12
- @options = options
13
- @site_root = @options[:site_root] || Jekyll.configuration({})['destination']
14
- @isolation_file = @options[:isolation_file] || Hawkins::ISOLATION_FILE
15
- SafeYAML::OPTIONS[:default_mode] = :safe
16
- end
17
-
18
- def call(env)
19
- req = Rack::Request.new(env)
20
- path = Pathname.new(req.path_info).relative_path_from(Pathname.new('/'))
21
- path = File.join(site_root, path.to_s)
22
-
23
- path = File.join(path, "index.html") if File.directory?(path)
24
- path = Pathname.new(path).cleanpath.to_s
25
-
26
- files = Dir[File.join(site_root, "**/*")]
27
- if files.include?(path)
28
- mime = mime(path)
29
- file = file_info(path)
30
- body = file[:body]
31
- time = file[:time]
32
- hdrs = {'Last-Modified' => time}
33
-
34
- if time == req.env['HTTP_IF_MODIFIED_SINCE']
35
- [304, hdrs, []]
36
- else
37
- hdrs.update(
38
- 'Content-length' => body.bytesize.to_s,
39
- 'Content-Type' => mime
40
- )
41
- [200, hdrs, [body]]
42
- end
43
- else
44
- handle_404(req, path)
45
- end
46
- end
47
-
48
- def handle_404(req, true_path)
49
- if File.exist?(isolation_file)
50
- file = true_path
51
- # Use a wildcard since the origin file could be anything
52
- file = "#{File.basename(file, File.extname(file))}.*".force_encoding('utf-8')
53
-
54
- config = SafeYAML.load_file(isolation_file)
55
-
56
- file_set = Set.new(config['include'])
57
-
58
- # Prevent loops. If it's already in 'include'
59
- # then we've gone through here before.
60
- return static_error if file_set.include?(file)
61
-
62
- config['include'] = file_set.add(file).to_a
63
-
64
- File.open(isolation_file, 'w') do |f|
65
- YAML.dump(config, f)
66
- end
67
-
68
- response = <<-PAGE.gsub(/^\s*/, '')
69
- <!DOCTYPE HTML>
70
- <html lang="en-US">
71
- <head>
72
- <meta charset="UTF-8">
73
- <title>Rendering #{req.path_info}</title>
74
- </head>
75
- <body>
76
- <h1>Hold on while I render that page for you!</h1>
77
- </body>
78
- PAGE
79
-
80
- headers = {}
81
- headers['Content-Length'] = response.bytesize.to_s
82
- headers['Content-Type'] = 'text/html'
83
- headers['Connection'] = 'keep-alive'
84
- [200, headers, [response]]
85
- else
86
- static_error
87
- end
88
- end
89
-
90
- def static_error
91
- error_page = File.join(site_root, "404.html")
92
- if File.exist?(error_page)
93
- body = file_info(error_page)[:body]
94
- mime = mime(error_page)
95
- else
96
- body = "Not found"
97
- mime = "text/plain"
98
- end
99
- [404, {"Content-Type" => mime, "Content-length" => body.bytesize.to_s}, [body]]
100
- end
101
-
102
- def mime(path_info)
103
- Rack::Mime.mime_type(File.extname(path_info))
104
- end
105
-
106
- def file_info(path)
107
- File.open(path, 'r') do |f|
108
- {
109
- :body => f.read,
110
- :time => f.mtime.httpdate,
111
- :expand_path => path
112
- }
113
- end
114
- end
115
- end
116
- end
data/test/test_hawkins.rb DELETED
@@ -1,134 +0,0 @@
1
- module Hawkins
2
- RSpec.describe "Hawkins" do
3
- context "when creating a post" do
4
- before(:each) do
5
- default_config = Jekyll::Configuration[Jekyll::Configuration::DEFAULTS]
6
- allow_any_instance_of(Jekyll::Configuration).to receive(:[]).and_return(default_config)
7
- allow_any_instance_of(Jekyll::Configuration).to receive(:config_files).and_return([])
8
- allow_any_instance_of(Jekyll::Configuration).to receive(:read_config_files).and_return(default_config)
9
- end
10
-
11
- let(:date) do
12
- Time.now.strftime('%Y-%m-%d')
13
- end
14
-
15
- let(:cli_spy) do
16
- spy('Cli')
17
- end
18
-
19
- it 'fails on a bad post date' do
20
- _, err = capture_io do
21
- expect do
22
- Cli.start(%w(post --date BAD_DATE title))
23
- end.to raise_error(SystemExit)
24
- end
25
-
26
- expect(err).to match(/Could not parse/)
27
- end
28
-
29
- it 'fails on a missing title' do
30
- _, err = capture_io do
31
- expect do
32
- Cli.start(%w(post))
33
- end.to raise_error(SystemExit)
34
- end
35
- expect(err).to match(/called with no arguments/)
36
- end
37
-
38
- # TODO There is a lot of redundancy here. There's got to be a better way.
39
- # Look at http://betterspecs.org for ideas.
40
- it 'uses a provided date' do
41
- title = "Party Like It's 1999"
42
- expected_body =<<-BODY.gsub(/^\s*/,'')
43
- ---
44
- title: #{title}
45
- ---
46
- BODY
47
- expected_file="_posts/1999-12-31-#{title.to_url}.md"
48
- # Required to keep Thor from printing warning about undescribed commands.
49
- cli_spy.no_commands do
50
- expect(cli_spy).to receive(:empty_directory)
51
- expect(cli_spy).to receive(:create_file).with(expected_file, expected_body)
52
- expect(cli_spy).to receive(:exec)
53
- end
54
-
55
- cli_spy.start(%W(post --date 1999-12-31 #{title}))
56
- end
57
-
58
- it 'uses today as the default date' do
59
- title = "Raspberry Beret"
60
- expected_body =<<-BODY.gsub(/^\s*/,'')
61
- ---
62
- title: #{title}
63
- ---
64
- BODY
65
- expected_file="_posts/#{date}-#{title.to_url}.md"
66
- cli_spy.no_commands do
67
- expect(cli_spy).to receive(:empty_directory)
68
- expect(cli_spy).to receive(:create_file).with(expected_file, expected_body)
69
- expect(cli_spy).to receive(:exec)
70
- end
71
-
72
- cli_spy.start(%W(post #{title}))
73
- end
74
-
75
- it 'uses a provided editor' do
76
- title = "Little Red Corvette"
77
- expected_file="_posts/#{date}-#{title.to_url}.md"
78
- cli_spy.no_commands do
79
- expect(cli_spy).to receive(:empty_directory)
80
- expect(cli_spy).to receive(:create_file).with(expected_file, expected_body)
81
- expect(cli_spy).to receive(:exec).with('foo', expected_file)
82
- end
83
-
84
- cli_spy.start(%W(post --editor foo #{title}))
85
- end
86
-
87
- it 'uses the editor from the environment' do
88
- title = "Let's Go Crazy"
89
- expected_file="_posts/#{date}-#{title.to_url}.md"
90
-
91
- stub_const("ENV", ENV.to_h.tap { |h| h['VISUAL'] = 'default' })
92
- cli_spy.no_commands do
93
- expect(cli_spy).to receive(:empty_directory)
94
- expect(cli_spy).to receive(:create_file)
95
- expect(cli_spy).to receive(:exec).with('default', expected_file)
96
- end
97
-
98
- cli_spy.start(%W(post #{title}))
99
- end
100
-
101
- it 'sets correct vim options' do
102
- title = "When Doves Cry"
103
- expected_file="_posts/#{date}-#{title.to_url}.md"
104
-
105
- ['gvim', 'vim'].each do |editor|
106
- stub_const("ENV", ENV.to_h.tap { |h| h['VISUAL'] = editor })
107
- cli_spy.no_commands do
108
- expect(cli_spy).to receive(:empty_directory)
109
- expect(cli_spy).to receive(:create_file)
110
- expect(cli_spy).to receive(:exec).with(editor, '+', expected_file)
111
- end
112
-
113
- cli_spy.start(%W(post #{title}))
114
- end
115
- end
116
-
117
- it 'sets correct emacs options' do
118
- title = "Purple Rain"
119
- expected_file="_posts/#{date}-#{title.to_url}.md"
120
-
121
- ['xemacs', 'emacs'].each do |editor|
122
- stub_const("ENV", ENV.to_h.tap { |h| h['VISUAL'] = editor })
123
- cli_spy.no_commands do
124
- expect(cli_spy).to receive(:empty_directory)
125
- expect(cli_spy).to receive(:create_file)
126
- expect(cli_spy).to receive(:exec).with(editor, '+3', expected_file)
127
- end
128
-
129
- cli_spy.start(%W(post #{title}))
130
- end
131
- end
132
- end
133
- end
134
- end