brief 1.5.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1e4078f005e4ba5a99b045a245a897ca71683dc
4
- data.tar.gz: d810cae63f5c24786b5a48b4af515b33a3fdf36c
3
+ metadata.gz: 9a7fdb09f6012e32e84d8dbd2389b556d43e2ebd
4
+ data.tar.gz: 2ac225ed8670e6eba082bac6e548b931bd9d8666
5
5
  SHA512:
6
- metadata.gz: 833e064d7b2aa8d619c5c8fce6a9bc401c3b4a070f71f1e75f41053d22fb7dd22d533403a82ad76ac8341b50cdd914ad989529c848b6d33c97dc3dfcbee12e18
7
- data.tar.gz: 679d1d73a557be8df6a4a0891506cce9c2bc17510bb2db44d8fb1a53988847133d45fde71586cff46d2a4e895dcd6df31e59729bd28b373be848fa78ade9608f
6
+ metadata.gz: bbad8b3c8b85ea4fe27bb4f56063f7f24f0ce977d7a247b80d719c4d443660ba7ee3cd20dd46f51cde66f4b71eb08401f22c9187fd461f5b6e21248bd3649d61
7
+ data.tar.gz: 458f15c26bc5c647a7024c9f339cb63d574a98a836a984241ff14de831e6c35cf70e76c77d5f4d4ae3c6285314e36cff6374332474fd556dd62a6c11ead700e7
@@ -121,3 +121,7 @@ attributes.
121
121
  ### 1.4.5
122
122
  - Introducing a new DSL to define aggregator methods on the briefcase
123
123
  - Aggregators have a REST interface
124
+
125
+ ### 1.6.0
126
+ - Introducing the apps repository for shared model code
127
+ - Added capability to pull out yaml blocks from the document as deserialized hashes on our models
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brief (1.5.1)
4
+ brief (1.5.2)
5
5
  activemodel
6
6
  activesupport
7
7
  commander
@@ -0,0 +1,7 @@
1
+ view(:summary) do |briefcase, params|
2
+ briefcase.present(:default, params).tap do |hash|
3
+ if summary = where(title:"Summary",type:"page").first
4
+ hash.merge!(summary: summary.to_model.as_json(:rendered=>true, :content=>true))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,68 @@
1
+ class Brief::Apps::Blueprint::Epic
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title
6
+ subheading
7
+ status String, :in => %w(draft published)
8
+ end
9
+
10
+ example <<-EOF
11
+ ---
12
+ type: epic
13
+ status: draft
14
+ ---
15
+
16
+ # Epic Title
17
+
18
+ Write a description for your epic.
19
+
20
+ # User Stories
21
+
22
+ ## User Story Title
23
+
24
+ As a **PERSONA** I would like to **BEHAVIOR** so that I can **GOAL**
25
+ EOF
26
+
27
+ template <<-EOF
28
+ # <%= object.title %>
29
+ # User Stories
30
+ <% Array(object.user_stories).each do |user_story| %>
31
+ ## <%= user_story.title %>
32
+ As a **User** I would like to **Do this** so that I can **succeed**
33
+ <% end %>
34
+ EOF
35
+
36
+ content do
37
+ title "h1:first-of-type"
38
+ define_section "User Stories" do
39
+ each("h2").has(:title => "h2",
40
+ :paragraph => "p:first-of-type",
41
+ :components => "p:first-of-type strong"
42
+ )
43
+
44
+ each("h2").is_a :user_story
45
+ end
46
+ end
47
+
48
+ helpers do
49
+ def user_stories
50
+ sections.user_stories.items.map do |item|
51
+ item.components = Array(item.components)
52
+
53
+ item.merge(goal: item.components[2],
54
+ persona: item.components[0],
55
+ behavior: item.components[1])
56
+ end
57
+ end
58
+ end
59
+
60
+ actions do
61
+ def publish_to_github
62
+ end
63
+
64
+ def custom_action
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,16 @@
1
+ class Brief::Apps::Blueprint::Page
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title
6
+ category
7
+ tags Array
8
+ end
9
+
10
+ content do
11
+ title "h1:first-of-type"
12
+ tagline "h2:first-of-type"
13
+ paragraph "p:first-of-type"
14
+ yaml_data "code.yaml:first-of-type", :serialize => :yaml
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class Brief::Apps::Blueprint::Persona
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title
6
+ end
7
+
8
+ content do
9
+ title "h1:first-of-type"
10
+ temp "h1:first-of-type"
11
+ paragraph "p:first-of-type"
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ class Brief::Apps::Blueprint::UserStory
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title
6
+ status :in => %w(draft published)
7
+ epic_title
8
+ end
9
+
10
+ template :file => "user_story.md.erb"
11
+
12
+ content do
13
+ persona "p strong:first-child"
14
+ behavior "p strong:second-child"
15
+ goal "p strong:third-child"
16
+ end
17
+
18
+ actions do
19
+ def sync_with_github
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ class Brief::Apps::Blueprint::Wireframe
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title
6
+ parent_title
7
+ category
8
+ tags
9
+ annotations Hash
10
+ end
11
+ end
@@ -60,7 +60,10 @@ module Brief
60
60
  end
61
61
 
62
62
  def self.load_modules_from(folder)
63
- Dir[folder.join('**/*.rb')].each { |f| require(f) }
63
+ Dir[folder.join('**/*.rb')].each do |f|
64
+ #puts "Loading model from #{ f }"
65
+ require(f)
66
+ end
64
67
  end
65
68
 
66
69
  # Adapters for Rails, Middleman, or Jekyll apps
@@ -93,3 +96,6 @@ require 'brief/model/serializers'
93
96
  require 'brief/dsl'
94
97
  require 'brief/server'
95
98
  require 'brief/briefcase'
99
+ require 'brief/apps'
100
+
101
+ Brief::Apps.create_namespaces()
@@ -0,0 +1,48 @@
1
+ module Brief
2
+ class Apps
3
+ def self.default_path
4
+ Brief.gem_root.join("..","apps")
5
+ end
6
+
7
+ def self.search_paths
8
+ paths = [default_path]
9
+
10
+ if custom_path = ENV['BRIEF_APPS_PATH']
11
+ custom_path = custom_path.to_s.to_pathname
12
+ paths << custom_path if (custom_path.exist? rescue nil)
13
+ end
14
+
15
+ paths
16
+ end
17
+
18
+ def self.app_paths
19
+ search_paths.map do |base|
20
+ base.children.select do |child|
21
+ child.join("config.rb").exist?
22
+ end
23
+ end.flatten
24
+ end
25
+
26
+ def self.available?(app_name)
27
+ available_apps.include?(app_name.to_s)
28
+ end
29
+
30
+ def self.path_for(app_name)
31
+ app_paths.detect {|b| b.basename.to_s == app_name }
32
+ end
33
+
34
+ def self.available_apps
35
+ app_paths.map(&:basename).map(&:to_s)
36
+ end
37
+
38
+ def self.create_namespaces
39
+ available_apps.map(&:camelize).each do |namespace|
40
+ const_set(namespace, Module.new)
41
+ end
42
+ end
43
+
44
+ def self.find_namespace(app_name)
45
+ Brief::Apps.const_get(app_name.to_s.camelize)
46
+ end
47
+ end
48
+ end
@@ -9,6 +9,8 @@ module Brief
9
9
  @options = options.to_mash
10
10
 
11
11
  load_configuration
12
+ use(:app, options[:app]) if options[:app]
13
+
12
14
  load_model_definitions
13
15
 
14
16
  if Brief.case.nil?
@@ -71,12 +73,10 @@ module Brief
71
73
  end
72
74
 
73
75
  def use(module_type=:app, module_id)
74
- if module_type == :app && apps_path.join(module_id).exist?
75
- config = module_type.join("config.rb")
76
- models = module_type.join("models")
76
+ options[:app] = module_id.to_s
77
77
 
78
- instance_eval(config.read) if config.exist?
79
- Brief.load_modules_from(models) if models.exist?
78
+ if app_path && app_path.exist?
79
+ instance_eval(app_config_path.read)
80
80
  end
81
81
  end
82
82
 
@@ -103,21 +103,37 @@ module Brief
103
103
  config_path = root.join(config_path)
104
104
  end
105
105
 
106
- if uses_app?
107
- instance_eval(app_path.join("config.rb").read)
108
- end
109
-
110
106
  if config_path.exist?
111
107
  instance_eval(config_path.read) rescue nil
112
108
  end
113
109
  end
114
110
 
115
111
  def uses_app?
116
- options.key?(:app) && Brief.apps_path.join(options[:app]).exist?
112
+ options.key?(:app) && Brief::Apps.available?(options[:app].to_s)
117
113
  end
118
114
 
119
115
  def app_path
120
- uses_app? && Brief.apps_path.join(options[:app])
116
+ uses_app? && Brief::Apps.path_for(options[:app]).to_pathname
117
+ end
118
+
119
+ def app_config_path
120
+ uses_app? && app_path.join("config.rb")
121
+ end
122
+
123
+ def app_models_folder
124
+ uses_app? && app_path.join("models")
125
+ end
126
+
127
+ def model_class_for(document_type)
128
+ return generic_model_class_for(document_type) unless uses_app?
129
+
130
+ namespace = Brief::Apps.find_namespace(options[:app])
131
+ classes = namespace.constants.map {|c| namespace.const_get(c) }
132
+ classes.find {|k| k.type_alias == document_type }
133
+ end
134
+
135
+ def generic_model_class_for(document)
136
+ Brief::Model.for_type(document.document_type) || Brief::Model.for_folder_name(document.parent_folder_name)
121
137
  end
122
138
 
123
139
  def load_model_definitions
@@ -9,3 +9,9 @@ class String
9
9
  Pathname(self)
10
10
  end
11
11
  end
12
+
13
+ class Pathname
14
+ def to_pathname
15
+ self
16
+ end
17
+ end
@@ -25,12 +25,6 @@ module Brief
25
25
  elsif options[:contents]
26
26
  @raw_content = options[:contents]
27
27
  end
28
-
29
- register_model_instance if self.path && self.path.exist?
30
- end
31
-
32
- def register_model_instance
33
- model_class.try(:models).try(:<<, to_model) unless model_instance_registered?
34
28
  end
35
29
 
36
30
  def raw= val
@@ -171,6 +165,8 @@ module Brief
171
165
  case
172
166
  when @model_class
173
167
  @model_class
168
+ when briefcase
169
+ briefcase.model_class_for(self)
174
170
  when data && data.type
175
171
  Brief::Model.for_type(data.type)
176
172
  when parent_folder_name.length > 0
@@ -8,7 +8,7 @@ module Brief
8
8
  attr_reader :document
9
9
 
10
10
  def model_class
11
- Brief::Model.for_type(@model_type)
11
+ document.model_class
12
12
  end
13
13
 
14
14
  def content_schema_attributes
@@ -39,6 +39,25 @@ module Brief
39
39
  else
40
40
  matches.first.try(:text)
41
41
  end
42
+ elsif settings.args.first.to_s.match(/code/i) && (settings.args.last.serialize rescue nil)
43
+ selector = settings.args.first
44
+ opts = settings.args.last
45
+
46
+ matches = document.css(selector)
47
+
48
+ val = if matches.length > 1
49
+ selector.match(/first-of-type/) ? matches.first.text : matches.map(&:text)
50
+ else
51
+ matches.first.try(:text)
52
+ end
53
+
54
+ if val && opts.serialize == :yaml
55
+ return (YAML.load(val) rescue {}).to_mash
56
+ end
57
+
58
+ if val && opts.serialize == :json
59
+ return (JSON.parse(val) rescue {}).to_mash
60
+ end
42
61
  end
43
62
  end
44
63
  end
@@ -25,7 +25,7 @@ module Brief
25
25
  fenced_code_blocks: true,
26
26
  footnotes: true)
27
27
 
28
- ::Redcarpet::Markdown.new(r)
28
+ ::Redcarpet::Markdown.new(r, :tables => true, :autolink => true, :gh_blockcode => true, :fenced_code_blocks => true, :footnotes => true)
29
29
  end
30
30
  end
31
31
  end
@@ -108,8 +108,8 @@ module Brief
108
108
  end
109
109
 
110
110
  module ClassMethods
111
- def purge
112
- models.reject! {|model| !model.document.path.exist? }
111
+ def ==(other)
112
+ type_alias && type_alias == other.type_alias
113
113
  end
114
114
 
115
115
  def to_schema
@@ -16,6 +16,25 @@ module Brief
16
16
  load_documents
17
17
  end
18
18
 
19
+ def respond_to?(meth)
20
+ super || model_groups.include?(meth.to_s)
21
+ end
22
+
23
+ def method_missing(meth, *args, &block)
24
+ if model_groups.include?(meth.to_s)
25
+ find_models_by_type(meth)
26
+ end
27
+ end
28
+
29
+ def find_models_by_type(group_name)
30
+ type = group_name.to_s.singularize
31
+ all_models_by_type.fetch(type) { [] }
32
+ end
33
+
34
+ def model_groups
35
+ documents.map(&:document_type).tap {|l| l.compact!; l.uniq!; l.map! {|i| i.pluralize } }
36
+ end
37
+
19
38
  def document_at(path)
20
39
  path = normalize_path(path)
21
40
  found = documents.find {|doc| doc.path == path }
@@ -74,46 +93,35 @@ module Brief
74
93
  end
75
94
 
76
95
  def all_models
77
- list = documents.select(&:refresh!).map(&:to_model)
78
- list.compact!
79
- list.select!(&:exists?)
96
+ @all_models ||= begin
97
+ list = documents.select(&:refresh!).map(&:to_model)
98
+ list.compact!
99
+ list.select!(&:exists?)
80
100
 
81
- list
101
+ list
102
+ end
82
103
  end
83
104
 
84
105
  def all_models_by_type
85
- all_models.reduce({}) do |memo, model|
86
- (memo[model.class.type_alias] ||= []) << model if model.exists?
87
- memo
88
- end
106
+ @all_models_by_type ||= begin
107
+ all_models.reduce({}) do |memo, model|
108
+ (memo[model.class.type_alias.to_s] ||= []) << model if model.exists?
109
+ memo
110
+ end
111
+ end
89
112
  end
90
113
 
91
114
  def purge(model_type=nil)
92
- if model_type
93
- plural = model_type.to_s.pluralize
94
-
95
- if instance_variable_get("@#{ plural }")
96
- instance_variable_set("@#{plural}",nil)
97
- end
98
- end
99
-
100
- documents.reject! {|doc| !doc.path.exist? }
115
+ load_documents
116
+ @all_models_by_type = nil
117
+ @all_models = nil
101
118
  end
102
119
 
103
120
  def self.define_document_finder_methods
104
121
  # Create a finder method on the repository
105
122
  # which lets us find instances of models by their class name
106
123
  Brief::Model.table.keys.each do |type|
107
- plural = type.to_s.pluralize
108
-
109
- define_method("#{ plural }") do
110
- instance_variable_get("@#{ plural }") || send("#{ plural }!")
111
- end
112
124
 
113
- define_method("#{ plural }!") do
114
- instance_variable_set("@#{plural}", Brief::Model.existing_models_for_type(type))
115
- instance_variable_get("@#{ plural }")
116
- end
117
125
  end
118
126
  end
119
127
  end
@@ -1,3 +1,3 @@
1
1
  module Brief
2
- VERSION = '1.5.2'
2
+ VERSION = '1.6.0'
3
3
  end
File without changes
@@ -8,3 +8,7 @@ title: Summary
8
8
  The Blueprint by Architects.io is a functional specifications and requirements document that joins together various materials produced by Software Architects, Domain Modelers, Researchers, UX and UI Designers, Engineers, and Product Managers. The overall purpose is to communicate design intent, vision, and goals, along with the strategy and logistics of implementation.
9
9
 
10
10
  Our aim is to reduce the overall communication effort required to deliver products whose results more closely match the intent and goals. This requires more effective communication tools, a more effortless feedback loop, and a methodology for validating and refining the goals themselves as everyone's understanding develops.
11
+
12
+ ```yaml
13
+ nested: structure
14
+ ```
@@ -8,5 +8,6 @@ class Brief::Page
8
8
  content do
9
9
  title "h1:first-of-type"
10
10
  paragraph "p:first-of-type"
11
+ yaml_data "code.yaml:first-of-type", :serialize => :yaml
11
12
  end
12
13
  end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe "Packaged Apps" do
4
+ let(:sample) do
5
+ Brief::Briefcase.new(app: "sample")
6
+ end
7
+
8
+ let(:blueprint) do
9
+ Brief::Briefcase.new(app: "blueprint")
10
+ end
11
+
12
+ it "should find the right path for an app name" do
13
+ expect(Brief::Apps.path_for("blueprint")).to be_exist
14
+ end
15
+
16
+ it "should be using the blueprint app" do
17
+ expect(blueprint).to be_uses_app
18
+ end
19
+
20
+ it "should pick up the view defined" do
21
+ expect(Brief.views.key?(:summary)).to eq(true)
22
+ end
23
+
24
+ it "should be using the blueprint app" do
25
+ expect(sample).to be_uses_app
26
+ end
27
+
28
+ it "should find the test app, and the gem apps" do
29
+ expect(Brief::Apps.available_apps).to include("blueprint","sample")
30
+ end
31
+ end
@@ -19,13 +19,14 @@ describe "The Briefcase" do
19
19
  expect(briefcase.settings.settings).to be_present
20
20
  end
21
21
 
22
+ # Need to improve this
22
23
  context "Model Loading" do
23
- it "loads the model definitions from the models folder" do
24
- expect(Brief::Model.classes.length).to eq(4)
24
+ it "loads the model definitions from the models and the apps folder" do
25
+ expect(Brief::Model.classes).not_to be_empty
25
26
  end
26
27
 
27
28
  it "loads the model definitions from the DSL in the config file" do
28
- expect(Brief::Model.classes.length).to eq(4)
29
+ expect(Brief::Model.classes).not_to be_empty
29
30
  end
30
31
 
31
32
  it "caches the output" do
@@ -40,7 +40,7 @@ describe "The Brief Document" do
40
40
  end
41
41
 
42
42
  it "can resolve the model type using the parent folder name if possible" do
43
- expect(Brief::Model.for_folder_name(sample.parent_folder_name)).to eq(Brief::Epic)
43
+ expect(Brief::Model.for_folder_name(sample.parent_folder_name).type_alias).to eq("epic")
44
44
  end
45
45
 
46
46
  context "Content Extraction" do
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe "Serializing From Docs" do
4
+ let(:page) {
5
+ Brief.testcase.pages.first
6
+ }
7
+
8
+ it "should serialize the yaml" do
9
+ expect(page.yaml_data.nested).to eq("structure")
10
+ end
11
+ end
@@ -33,3 +33,5 @@ RSpec.configure do |config|
33
33
  config.include Rack::Test::Methods
34
34
  config.include TestHelpers
35
35
  end
36
+
37
+ ENV['BRIEF_APPS_PATH'] = Brief.spec_root.join("fixtures","apps").to_s
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brief
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Soeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-24 00:00:00.000000000 Z
11
+ date: 2015-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -237,6 +237,12 @@ files:
237
237
  - README.md
238
238
  - Rakefile
239
239
  - TUTORIAL.md
240
+ - apps/blueprint/config.rb
241
+ - apps/blueprint/models/epic.rb
242
+ - apps/blueprint/models/page.rb
243
+ - apps/blueprint/models/persona.rb
244
+ - apps/blueprint/models/user_story.rb
245
+ - apps/blueprint/models/wireframe.rb
240
246
  - bin/brief
241
247
  - brief.gemspec
242
248
  - examples/blog/brief.rb
@@ -244,6 +250,7 @@ files:
244
250
  - lib/.DS_Store
245
251
  - lib/brief.rb
246
252
  - lib/brief/adapters/middleman.rb
253
+ - lib/brief/apps.rb
247
254
  - lib/brief/briefcase.rb
248
255
  - lib/brief/cli/change.rb
249
256
  - lib/brief/cli/init.rb
@@ -283,6 +290,7 @@ files:
283
290
  - spec/acceptance/modifying_spec.rb
284
291
  - spec/acceptance/schema_spec.rb
285
292
  - spec/acceptance/showing_spec.rb
293
+ - spec/fixtures/apps/sample/config.rb
286
294
  - spec/fixtures/example/brief.rb
287
295
  - spec/fixtures/example/docs/concept.html.md
288
296
  - spec/fixtures/example/docs/epics/epic.html.md
@@ -300,6 +308,7 @@ files:
300
308
  - spec/fixtures/structures/one.html.md
301
309
  - spec/fixtures/structures/three.html.md
302
310
  - spec/fixtures/structures/two.html.md
311
+ - spec/lib/brief/apps_spec.rb
303
312
  - spec/lib/brief/briefcase_spec.rb
304
313
  - spec/lib/brief/document_spec.rb
305
314
  - spec/lib/brief/dsl_spec.rb
@@ -309,6 +318,7 @@ files:
309
318
  - spec/lib/brief/rendering_spec.rb
310
319
  - spec/lib/brief/repository_spec.rb
311
320
  - spec/lib/brief/section_builder_spec.rb
321
+ - spec/lib/brief/serializers_spec.rb
312
322
  - spec/lib/brief/server/gateway_spec.rb
313
323
  - spec/lib/brief/server/route_spec.rb
314
324
  - spec/lib/brief/structure_spec.rb
@@ -346,6 +356,7 @@ test_files:
346
356
  - spec/acceptance/modifying_spec.rb
347
357
  - spec/acceptance/schema_spec.rb
348
358
  - spec/acceptance/showing_spec.rb
359
+ - spec/fixtures/apps/sample/config.rb
349
360
  - spec/fixtures/example/brief.rb
350
361
  - spec/fixtures/example/docs/concept.html.md
351
362
  - spec/fixtures/example/docs/epics/epic.html.md
@@ -363,6 +374,7 @@ test_files:
363
374
  - spec/fixtures/structures/one.html.md
364
375
  - spec/fixtures/structures/three.html.md
365
376
  - spec/fixtures/structures/two.html.md
377
+ - spec/lib/brief/apps_spec.rb
366
378
  - spec/lib/brief/briefcase_spec.rb
367
379
  - spec/lib/brief/document_spec.rb
368
380
  - spec/lib/brief/dsl_spec.rb
@@ -372,6 +384,7 @@ test_files:
372
384
  - spec/lib/brief/rendering_spec.rb
373
385
  - spec/lib/brief/repository_spec.rb
374
386
  - spec/lib/brief/section_builder_spec.rb
387
+ - spec/lib/brief/serializers_spec.rb
375
388
  - spec/lib/brief/server/gateway_spec.rb
376
389
  - spec/lib/brief/server/route_spec.rb
377
390
  - spec/lib/brief/structure_spec.rb