Class: Brief::Briefcase

Inherits:
Object
  • Object
show all
Includes:
Documentation, DSL
Defined in:
lib/brief/briefcase.rb,
lib/brief/briefcase/initializer.rb,
lib/brief/briefcase/documentation.rb

Defined Under Namespace

Modules: Documentation Classes: Initializer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Documentation

#render_documentation, #schema_map

Methods included from DSL

#action, #command, #define, #extend, #view

Constructor Details

#initialize(options = {}) ⇒ Briefcase

Returns a new instance of Briefcase.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/brief/briefcase.rb', line 12

def initialize(options = {})
  @options = options.to_mash

  load_configuration
  use(:app, options[:app]) if options[:app]

  load_model_definitions

  if Brief.case(false).nil?
    Brief.case = self
  end

  @href_builder = options.fetch(:href_builder) { Brief.href_builder }
  @asset_finder = options.fetch(:asset_finder) { method(:find_asset) }

  Brief.cases[root.basename.to_s] ||= self
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object



316
317
318
319
320
321
322
323
324
325
# File 'lib/brief/briefcase.rb', line 316

def method_missing(meth, *args, &block)
  if Brief.views.key?(meth.to_sym)
    block = Brief.views[meth.to_sym]
    block.call(self, args.extract_options!)
  elsif repository.respond_to?(meth)
    repository.send(meth, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#asset_finderObject

Returns the value of attribute asset_finder.



9
10
11
# File 'lib/brief/briefcase.rb', line 9

def asset_finder
  @asset_finder
end

#href_builderObject

Returns the value of attribute href_builder.



9
10
11
# File 'lib/brief/briefcase.rb', line 9

def href_builder
  @href_builder
end

#model_definitionsObject (readonly)

Returns the value of attribute model_definitions.



6
7
8
# File 'lib/brief/briefcase.rb', line 6

def model_definitions
  @model_definitions
end

#optionsObject (readonly)

Returns the value of attribute options.



6
7
8
# File 'lib/brief/briefcase.rb', line 6

def options
  @options
end

Class Method Details

.create_new_briefcase(options = {}) ⇒ Object



327
328
329
# File 'lib/brief/briefcase.rb', line 327

def self.create_new_briefcase(options={})
  Brief::Briefcase::Initializer.new(options).run
end

Instance Method Details

#app_config_pathObject



212
213
214
# File 'lib/brief/briefcase.rb', line 212

def app_config_path
  uses_app? && app_path.join("config.rb")
end

#app_modelsObject



224
225
226
# File 'lib/brief/briefcase.rb', line 224

def app_models
  app_namespace.constants.map {|c| app_namespace.const_get(c) }
end

#app_models_folderObject



216
217
218
# File 'lib/brief/briefcase.rb', line 216

def app_models_folder
  uses_app? && app_path.join("models")
end

#app_namespaceObject



220
221
222
# File 'lib/brief/briefcase.rb', line 220

def app_namespace
  Brief::Apps.find_namespace(options[:app])
end

#app_pathObject



208
209
210
# File 'lib/brief/briefcase.rb', line 208

def app_path
  uses_app? && Brief::Apps.path_for(options[:app]).to_pathname
end

#as_default(params = {}) ⇒ Object

TODO The serialization of an entire briefcase at once is important enough to be its own module



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/brief/briefcase.rb', line 110

def as_default(params={})
  params.symbolize_keys!

  base = info_hash

  if params[:include_data] || params[:data]
    base[:data] = data.as_json
  end

  if params[:include_schema] || params[:schema]
    base[:schema] = schema_map(!!(params[:include_schema] == "full"))
  end

  if params[:include_documentation] || params[:documentation]
    base[:documentation] = render_documentation
  end

  if params[:include_models] || params[:models]
    model_settings = {
      docs_path: docs_path
    }

    %w(urls content rendered attachments).each do |opt|
      model_settings[opt.to_sym] = !!(params[opt.to_sym] || params["include_#{opt}".to_sym])
    end

    all = all_models.compact

    base[:models] = all.map do |m|
      m.document.refresh! if params[:refresh_models]
      m.as_json(model_settings)
    end
  end

  base
end

#as_full_export(options = {}) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/brief/briefcase.rb', line 147

def as_full_export(options={})
  options.reverse_merge!(content: true,
                         rendered: true,
                         models: true,
                         schema: true,
                         documentation: true,
                         attachments: true)
  as_default(options)
end

#assets_pathObject



266
267
268
# File 'lib/brief/briefcase.rb', line 266

def assets_path
  root.join(options.fetch(:assets_path) { config.assets_path }).expand_path
end

#assets_trailObject



278
279
280
281
282
283
# File 'lib/brief/briefcase.rb', line 278

def assets_trail
  @assets_trail ||= Hike::Trail.new(assets_path).tap do |trail|
    trail.append_extensions '.svg', '.png', '.pdf', '.jpg', '.gif', '.mov'
    assets_path.children.select(&:directory?).each {|dir| trail.prepend_path(assets_path); trail.append_path(assets_path.join(dir)) }
  end
end

#cache_keyObject



62
63
64
# File 'lib/brief/briefcase.rb', line 62

def cache_key
  "#{slug}:#{repository.cache_key}"
end

#config(&block) ⇒ Object



171
172
173
174
175
# File 'lib/brief/briefcase.rb', line 171

def config(&block)
  Brief::Configuration.instance.tap do |cfg|
    cfg.instance_eval(&block) if block.respond_to?(:call)
  end
end

#dataObject



163
164
165
# File 'lib/brief/briefcase.rb', line 163

def data
  @data ||= data!
end

#data!Object



167
168
169
# File 'lib/brief/briefcase.rb', line 167

def data!
  @data = Brief::Data::Wrapper.new(root: data_path)
end

#data_pathObject



274
275
276
# File 'lib/brief/briefcase.rb', line 274

def data_path
  root.join(options.fetch(:data_path) { config.data_path }).expand_path
end

#data_trailObject



293
294
295
296
297
298
# File 'lib/brief/briefcase.rb', line 293

def data_trail
  @docs_trail ||= Hike::Trail.new(data_path).tap do |trail|
    trail.append_extensions '.yaml', '.js', '.json', '.xls', '.xlsx', '.csv', '.txt'
    trail.append_path(data_path)
  end
end

#docs_pathObject



270
271
272
# File 'lib/brief/briefcase.rb', line 270

def docs_path
  root.join(options.fetch(:docs_path) { config.docs_path }).expand_path
end

#docs_trailObject



285
286
287
288
289
290
# File 'lib/brief/briefcase.rb', line 285

def docs_trail
  @docs_trail ||= Hike::Trail.new(docs_path).tap do |trail|
    trail.append_extensions '.md', '.html.md', '.markdown'
    docs_path.children.select(&:directory?).each {|dir| trail.prepend_path(docs_path); trail.append_path(docs_path.join(dir)) }
  end
end

#find_asset(needle) ⇒ Object



261
262
263
264
# File 'lib/brief/briefcase.rb', line 261

def find_asset(needle)
  found = assets_trail.find(needle)
  found && Pathname(found)
end

#folder_nameObject



181
182
183
# File 'lib/brief/briefcase.rb', line 181

def folder_name
  root.basename
end

#generic_model_class_for(document) ⇒ Object



233
234
235
# File 'lib/brief/briefcase.rb', line 233

def generic_model_class_for(document)
  Brief::Model.for_type(document.document_type) || Brief::Model.for_folder_name(document.parent_folder_name)
end

#get_external_url_for(asset_path) ⇒ Object



103
104
105
# File 'lib/brief/briefcase.rb', line 103

def get_external_url_for(asset_path)
  asset_finder.call(asset_path)
end

#get_href_for(brief_uri) ⇒ Object



99
100
101
# File 'lib/brief/briefcase.rb', line 99

def get_href_for(brief_uri)
  href_builder.call(brief_uri)
end

#info_hashObject



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/brief/briefcase.rb', line 81

def info_hash
  {
    BRIEF_VERSION: Brief::VERSION,
    views: Brief.views.keys,
    key: folder_name.to_s.parameterize,
    name: folder_name.to_s.titlecase,
    settings: settings,
    cache_key: cache_key,
    root: root.to_s,
    paths:{
      docs_path: docs_path.to_s,
      assets_path: assets_path.to_s,
      models_path: models_path.to_s,
      data_path: data_path.to_s
    }
  }
end

#load_configurationObject

Loads the configuration for this briefcase, either from the current working directory or the configured path for the configuration file.



187
188
189
190
191
192
193
194
195
196
197
# File 'lib/brief/briefcase.rb', line 187

def load_configuration
  config_path = options.fetch(:config_path) do
    root.join('brief.rb')
  end

  if config_path.is_a?(String)
    config_path = root.join(config_path)
  end

  run(config_path) if config_path.exist?
end

#load_model_definitionsObject



237
238
239
240
241
242
243
244
# File 'lib/brief/briefcase.rb', line 237

def load_model_definitions
  if uses_app?
    Brief.load_modules_from(app_path.join("models"))
  end

  Brief.load_modules_from(models_path) if models_path.exist?
  Brief::Model.finalize
end

#model(name_or_type) ⇒ Object

Returns a model name by its human readable description or its type alias



247
248
249
250
251
252
253
254
255
# File 'lib/brief/briefcase.rb', line 247

def model(name_or_type)
  table = Brief::Model.table

  table.fetch(name_or_type) do
    table.values.find do |k|
      k.name == name_or_type
    end
  end
end

#model_class_for(document) ⇒ Object



228
229
230
231
# File 'lib/brief/briefcase.rb', line 228

def model_class_for(document)
  return generic_model_class_for(document) unless uses_app?
  app_models.find {|k| k.type_alias == document.document_type } || generic_model_class_for(document)
end

#models_pathObject



300
301
302
303
304
305
306
307
308
309
310
# File 'lib/brief/briefcase.rb', line 300

def models_path
  value = options.fetch(:models_path) { config.models_path }

  if value.to_s.match(/\./)
    Pathname(Brief.pwd).join(value)
  elsif value.to_s.match(/\//)
    Pathname(value)
  else
    root.join(value)
  end
end

#present(style = "default", params = {}) ⇒ Object

Returns a Hash object which presents some view of the briefcase. Accepts a params hash of options that will be passed to the presenter.

The default presenter is Brief::Briefcase#as_default



51
52
53
54
55
56
57
58
59
60
# File 'lib/brief/briefcase.rb', line 51

def present(style="default", params={})
  style = "default" if style.nil?

  if respond_to?("as_#{style}")
    send("as_#{style}", params)
  elsif Brief.views.key?(style.to_sym)
    block = Brief.views[style.to_sym]
    block.call(self, params)
  end
end

#repositoryObject



312
313
314
# File 'lib/brief/briefcase.rb', line 312

def repository
  @repository ||= Brief::Repository.new(self, options)
end

#rootObject



257
258
259
# File 'lib/brief/briefcase.rb', line 257

def root
  Pathname(options.fetch(:root) { Brief.pwd }).expand_path
end

#run(code_or_file) ⇒ Object



199
200
201
202
# File 'lib/brief/briefcase.rb', line 199

def run(code_or_file)
  code = code_or_file.is_a?(Pathname) ? code_or_file.read : code
  instance_eval(code) rescue nil
end

#run_command(name, *args) ⇒ Object

Runs a command

Commands are defined in the briefcase configuration.

You define a command by passing a block. This block will get called with the briefcase, and whatever other arguments



36
37
38
39
40
41
42
43
44
# File 'lib/brief/briefcase.rb', line 36

def run_command(name, *args)
  if handler = Brief.commands.fetch(name.to_sym)
    block = handler[:handler]
    args.unshift(self)
    block.call(*args)
  else
    raise 'Command not found'
  end
end

#server(options = {}) ⇒ Object



177
178
179
# File 'lib/brief/briefcase.rb', line 177

def server(options={})
  @server ||= Brief::Server.new(self, options)
end

#settingsObject



70
71
72
# File 'lib/brief/briefcase.rb', line 70

def settings
  @settings ||= settings!
end

#settings!Object



74
75
76
77
78
79
# File 'lib/brief/briefcase.rb', line 74

def settings!
  if root.join("settings.yml").exist?
    y = YAML.load(root.join("settings.yml").read) rescue nil
    (y || {}).to_mash
  end
end

#slugObject



66
67
68
# File 'lib/brief/briefcase.rb', line 66

def slug
  options.fetch(:slug) { root.basename.to_s.parameterize }
end

#use(module_type = :app, module_id) ⇒ Object



157
158
159
160
161
# File 'lib/brief/briefcase.rb', line 157

def use(module_type=:app, module_id)
  options[:app] = module_id.to_s

  run(app_config_path) if app_path.try(&:exist?)
end

#uses_app?Boolean

Returns:

  • (Boolean)


204
205
206
# File 'lib/brief/briefcase.rb', line 204

def uses_app?
  options.key?(:app) && Brief::Apps.available?(options[:app].to_s)
end