hawkins 0.1.0 → 2.0.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.
@@ -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