Class: YARD::Server::Commands::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/yard/server/commands/base.rb

Overview

This class is abstract.

This is the base command class used to implement custom commands for a server. A command will be routed to by the Router class and return a Rack-style response.

Attribute Initializers

All attributes can be initialized via options passed into the #initialize method. When creating a custom command, the Adapter#options will automatically be mapped to attributes by the same name on your class.

class MyCommand < Base
  attr_accessor :myattr
end

Adapter.new(libs, {:myattr => 'foo'}).start

# when a request comes in, cmd.myattr == 'foo'

Subclassing Notes

To implement a custom command, override the #run method, not #call. In your implementation, you should set the body and status for requests. See details in the #run method documentation.

Note that if your command deals directly with libraries, you should consider subclassing the more specific LibraryCommand class instead.

See Also:

Since:

  • 0.6.0

Basic Command and Adapter Options collapse

Attributes Set Per Request collapse

Instance Method Summary collapse

Abstract Methods collapse

Helper Methods collapse

Constructor Details

#initialize(opts = {}) ⇒ Base

Creates a new command object, setting attributes named by keys in the options hash. After initialization, the options hash is saved in #command_options for further inspection.

Examples:

Creating a Command

cmd = DisplayObjectCommand.new(:caching => true, :library => mylib)
cmd.library # => mylib
cmd.command_options # => {:caching => true, :library => mylib}

Since:

  • 0.6.0

Parameters:

  • (defaults to: {})

    the options hash, saved to #command_options after initialization.



75
76
77
78
79
80
# File 'lib/yard/server/commands/base.rb', line 75

def initialize(opts = {})
  opts.each do |key, value|
    send("#{key}=", value) if respond_to?("#{key}=")
  end
  self.command_options = opts
end

Instance Attribute Details

#adapterAdapter

Returns the server adapter.

Since:

  • 0.6.0

Returns:

  • the server adapter



41
42
43
# File 'lib/yard/server/commands/base.rb', line 41

def adapter
  @adapter
end

#bodyString

Returns the response body. Defaults to empty string.

Since:

  • 0.6.0

Returns:

  • the response body. Defaults to empty string.



61
62
63
# File 'lib/yard/server/commands/base.rb', line 61

def body
  @body
end

#cachingBoolean

Returns whether to cache.

Since:

  • 0.6.0

Returns:

  • whether to cache



44
45
46
# File 'lib/yard/server/commands/base.rb', line 44

def caching
  @caching
end

#command_optionsHash

Returns the options passed to the command’s constructor.

Since:

  • 0.6.0

Returns:

  • the options passed to the command’s constructor



38
39
40
# File 'lib/yard/server/commands/base.rb', line 38

def command_options
  @command_options
end

#headersHash{String => String}

Returns response headers.

Since:

  • 0.6.0

Returns:

  • response headers



55
56
57
# File 'lib/yard/server/commands/base.rb', line 55

def headers
  @headers
end

#pathString

Returns the path after the command base URI.

Since:

  • 0.6.0

Returns:

  • the path after the command base URI



52
53
54
# File 'lib/yard/server/commands/base.rb', line 52

def path
  @path
end

#requestRack::Request

Returns request object.

Since:

  • 0.6.0

Returns:

  • request object



49
50
51
# File 'lib/yard/server/commands/base.rb', line 49

def request
  @request
end

#statusNumeric

Returns status code. Defaults to 200 per request.

Since:

  • 0.6.0

Returns:

  • status code. Defaults to 200 per request



58
59
60
# File 'lib/yard/server/commands/base.rb', line 58

def status
  @status
end

Instance Method Details

#cache(data) ⇒ String (protected)

Override this method to implement custom caching mechanisms for

Examples:

Caching to memory

$memory_cache = {}
def cache(data)
  $memory_cache[path] = data
end

See Also:

Since:

  • 0.6.0

Parameters:

  • the data to cache

Returns:

  • the same cached data (for chaining)



165
166
167
168
169
170
171
172
173
174
# File 'lib/yard/server/commands/base.rb', line 165

def cache(data)
  if caching && adapter.document_root
    path = File.join(adapter.document_root, request.path_info.sub(/\.html$/, '') + '.html')
    path = path.sub(%r{/\.html$}, '.html')
    FileUtils.mkdir_p(File.dirname(path))
    log.debug "Caching data to #{path}"
    File.open(path, 'wb') {|f| f.write(data) }
  end
  self.body = data
end

#call(request) ⇒ Array(Numeric,Hash,Array<String>)

Note:

This command should not be overridden by subclasses. Implement the callback method #run instead.

The main method called by a router with a request object.

Since:

  • 0.6.0

Parameters:

  • the request object

Returns:

  • a Rack-style response of status, headers, and body wrapped in an array.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/yard/server/commands/base.rb', line 89

def call(request)
  self.request = request
  self.path ||= request.path_info[1..-1]
  self.headers = {'Content-Type' => 'text/html'}
  self.body = ''
  self.status = 200
  add_cache_control
  begin
    run
  rescue FinishRequest
    nil # noop
  rescue NotFoundError => e
    self.body = e.message if e.message != e.class.to_s
    not_found
  end

  # keep this to support commands setting status manually.
  not_found if status == 404

  [status, headers, body.is_a?(Array) ? body : [body]]
end

#not_foundvoid (protected)

This method returns an undefined value.

Sets the body and headers for a 404 response. Does not modify the body if already set.

Since:

  • 0.6.0



180
181
182
183
184
185
186
187
# File 'lib/yard/server/commands/base.rb', line 180

def not_found
  self.status = 404
  return unless body.empty?
  self.body = "Not found: #{request.path}"
  headers['Content-Type'] = 'text/plain'
  headers['X-Cascade'] = 'pass'
  headers['Cache-Control'] = 'nocache'
end

#redirect(url) ⇒ Object (protected)

Sets the headers and status code for a redirection to a given URL

Raises:

  • causes the request to terminate.

Since:

  • 0.6.0

Parameters:

  • the URL to redirect to



192
193
194
195
196
# File 'lib/yard/server/commands/base.rb', line 192

def redirect(url)
  headers['Location'] = url
  self.status = 302
  raise FinishRequest
end

#render(object = nil) ⇒ String (protected)

TODO:

This method is dependent on #options, it should be in LibraryCommand.

Renders a specific object if provided, or a regular template rendering if object is not provided.

Since:

  • 0.6.0

Parameters:

Returns:

  • the resulting output to display



144
145
146
147
148
149
150
151
152
153
# File 'lib/yard/server/commands/base.rb', line 144

def render(object = nil)
  case object
  when CodeObjects::Base
    cache object.format(options)
  when nil
    cache Templates::Engine.render(options)
  else
    cache object
  end
end

#runvoid

This method is abstract.

This method returns an undefined value.

Subclass this method to implement a custom command. This method should set the #status and #body, and optionally modify the #headers. Note that #status defaults to 200.

Examples:

A custom command

class ErrorCommand < Base
  def run
    self.body = 'ERROR! The System is down!'
    self.status = 500
    self.headers['Content-Type'] = 'text/plain'
  end
end

Raises:

Since:

  • 0.6.0



128
129
130
# File 'lib/yard/server/commands/base.rb', line 128

def run
  raise NotImplementedError
end