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}

Parameters:

  • opts (Hash) (defaults to: {})

    the options hash, saved to #command_options after initialization.

Since:

  • 0.6.0



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

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.

Returns:

Since:

  • 0.6.0



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

def adapter
  @adapter
end

#bodyString

Returns the response body. Defaults to empty string.

Returns:

  • (String)

    the response body. Defaults to empty string.

Since:

  • 0.6.0



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

def body
  @body
end

#cachingBoolean

Returns whether to cache.

Returns:

  • (Boolean)

    whether to cache

Since:

  • 0.6.0



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

def caching
  @caching
end

#command_optionsHash

Returns the options passed to the command’s constructor.

Returns:

  • (Hash)

    the options passed to the command’s constructor

Since:

  • 0.6.0



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

def command_options
  @command_options
end

#headersHash{String => String}

Returns response headers.

Returns:

Since:

  • 0.6.0



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

def headers
  @headers
end

#pathString

Returns the path after the command base URI.

Returns:

  • (String)

    the path after the command base URI

Since:

  • 0.6.0



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

def path
  @path
end

#requestRequest

Returns request object.

Returns:

  • (Request)

    request object

Since:

  • 0.6.0



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

def request
  @request
end

#statusNumeric

Returns status code. Defaults to 200 per request.

Returns:

  • (Numeric)

    status code. Defaults to 200 per request

Since:

  • 0.6.0



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

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

Parameters:

  • data (String)

    the data to cache

Returns:

  • (String)

    the same cached data (for chaining)

See Also:

Since:

  • 0.6.0



159
160
161
162
163
164
165
166
167
168
# File 'lib/yard/server/commands/base.rb', line 159

def cache(data)
  if caching && adapter.document_root
    path = File.join(adapter.document_root, request.path.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.

Parameters:

  • request (Adapter Dependent)

    the request object

Returns:

  • (Array(Numeric,Hash,Array<String>))

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

Since:

  • 0.6.0



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

def call(request)
  self.request = request
  self.path ||= request.path[1..-1]
  self.headers = {'Content-Type' => 'text/html'}
  self.body = ''
  self.status = 200
  begin
    run
  rescue FinishRequest
  rescue NotFoundError => e
    self.body = e.message if e.message != e.class.to_s
    self.status = 404
  end
  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 (but not status) for a 404 response. Does nothing if the body is already set.

Since:

  • 0.6.0



174
175
176
177
178
179
# File 'lib/yard/server/commands/base.rb', line 174

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

#redirect(url) ⇒ Object (protected)

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

Parameters:

  • url (String)

    the URL to redirect to

Raises:

Since:

  • 0.6.0



184
185
186
187
188
# File 'lib/yard/server/commands/base.rb', line 184

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.

Parameters:

Returns:

  • (String)

    the resulting output to display

Since:

  • 0.6.0



138
139
140
141
142
143
144
145
146
147
# File 'lib/yard/server/commands/base.rb', line 138

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['Conten-Type'] = 'text/plain'
  end
end

Raises:

  • (NotImplementedError)

Since:

  • 0.6.0



122
123
124
# File 'lib/yard/server/commands/base.rb', line 122

def run
  raise NotImplementedError
end