brief 1.9.9 → 1.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +16 -15
  3. data/README.md +39 -161
  4. data/Rakefile +5 -0
  5. data/apps/blueprint/config.rb +4 -0
  6. data/apps/blueprint/documentation/diagram.md +13 -0
  7. data/apps/blueprint/documentation/epic.md +10 -0
  8. data/apps/blueprint/documentation/milestone.md +4 -0
  9. data/apps/blueprint/documentation/outline.md +6 -0
  10. data/apps/blueprint/documentation/page.md +0 -0
  11. data/apps/blueprint/documentation/persona.md +0 -0
  12. data/apps/blueprint/documentation/project.md +0 -0
  13. data/apps/blueprint/documentation/release.md +0 -0
  14. data/apps/blueprint/documentation/roadmap.md +0 -0
  15. data/apps/blueprint/documentation/sitemap.md +0 -0
  16. data/apps/blueprint/documentation/user_story.md +0 -0
  17. data/apps/blueprint/documentation/wireframe.md +0 -0
  18. data/apps/blueprint/example/brief.rb +0 -0
  19. data/apps/blueprint/example/docs/diagrams/example-diagram.md +0 -0
  20. data/apps/blueprint/models/diagram.rb +3 -1
  21. data/apps/blueprint/models/epic.rb +2 -0
  22. data/apps/blueprint/models/milestone.rb +3 -1
  23. data/apps/blueprint/models/outline.rb +13 -0
  24. data/apps/blueprint/models/page.rb +2 -0
  25. data/apps/blueprint/models/persona.rb +2 -0
  26. data/apps/blueprint/models/project.rb +2 -0
  27. data/apps/blueprint/models/release.rb +2 -0
  28. data/apps/blueprint/models/roadmap.rb +2 -0
  29. data/apps/blueprint/models/sitemap.rb +2 -0
  30. data/apps/blueprint/models/user_story.rb +2 -0
  31. data/apps/blueprint/models/wireframe.rb +2 -0
  32. data/lib/brief.rb +4 -1
  33. data/lib/brief/briefcase.rb +8 -6
  34. data/lib/brief/briefcase/documentation.rb +36 -0
  35. data/lib/brief/cli/export.rb +0 -39
  36. data/lib/brief/document/attachments.rb +10 -1
  37. data/lib/brief/model.rb +36 -0
  38. data/lib/brief/model/definition.rb +19 -0
  39. data/lib/brief/model/serializers.rb +1 -0
  40. data/lib/brief/version.rb +1 -1
  41. data/spec/lib/brief/apps_spec.rb +6 -1
  42. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e5778cd99dfcb00c4420b4fedfb0e4e69b61d0b
4
- data.tar.gz: 1c551d49bf311134309dcff740d1492200deeea2
3
+ metadata.gz: 0df5a7957404e6281f7da3ea81daae61d24a2b42
4
+ data.tar.gz: eab76b0724000e106e08579e415570fd474a8139
5
5
  SHA512:
6
- metadata.gz: d23643282699bf917fb20805a229e82138abe51babef4454e137f90802ef3786d4d6b8ff61661a77b368a363fbf5b21d6871002e76d7b479458409111b7a4edd
7
- data.tar.gz: 861e4cc4df911860dcc481bd3e25d208f815f3f3ce078d05ae515e0d07408c71559c309d6cfb69cb898b613b150a2fd2fe18f4c7b3574bb495be70ec575e9808
6
+ metadata.gz: eabd297d3e1ee5ce7291156a91084a52e095aca03b798cbb1000c55fa1516c12801ceec9a8b1ec6d50f84b787057b4837d289efd67194bd967e47df262e53ae1
7
+ data.tar.gz: aebc6b9b3dc5974beda9cc6ca301bc0e65fd2e9009721f728258fdef68820a83660e790a6d7e454c01616e86033b18f6ed35d0129b9abb75276ef2293547dbb4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brief (1.9.8)
4
+ brief (1.9.11)
5
5
  activesupport (~> 4.0)
6
6
  commander (~> 4.3)
7
7
  em-websocket (= 0.5.1)
@@ -24,7 +24,7 @@ GEM
24
24
  minitest (~> 5.1)
25
25
  thread_safe (~> 0.3, >= 0.3.4)
26
26
  tzinfo (~> 1.1)
27
- addressable (2.3.7)
27
+ addressable (2.3.8)
28
28
  axiom-types (0.1.1)
29
29
  descendants_tracker (~> 0.0.4)
30
30
  ice_nine (~> 0.11.0)
@@ -32,7 +32,7 @@ GEM
32
32
  coderay (1.1.0)
33
33
  coercible (1.0.0)
34
34
  descendants_tracker (~> 0.0.1)
35
- commander (4.3.3)
35
+ commander (4.3.4)
36
36
  highline (~> 1.7.2)
37
37
  daemons (1.2.2)
38
38
  descendants_tracker (0.0.4)
@@ -70,22 +70,23 @@ GEM
70
70
  coderay (~> 1.1.0)
71
71
  method_source (~> 0.8.1)
72
72
  slop (~> 3.4)
73
- rack (1.6.0)
73
+ rack (1.6.1)
74
74
  rack-test (0.6.3)
75
75
  rack (>= 1.0)
76
76
  rake (0.9.6)
77
- rspec (3.1.0)
78
- rspec-core (~> 3.1.0)
79
- rspec-expectations (~> 3.1.0)
80
- rspec-mocks (~> 3.1.0)
81
- rspec-core (3.1.7)
82
- rspec-support (~> 3.1.0)
83
- rspec-expectations (3.1.2)
77
+ rspec (3.2.0)
78
+ rspec-core (~> 3.2.0)
79
+ rspec-expectations (~> 3.2.0)
80
+ rspec-mocks (~> 3.2.0)
81
+ rspec-core (3.2.3)
82
+ rspec-support (~> 3.2.0)
83
+ rspec-expectations (3.2.1)
84
84
  diff-lcs (>= 1.2.0, < 2.0)
85
- rspec-support (~> 3.1.0)
86
- rspec-mocks (3.1.3)
87
- rspec-support (~> 3.1.0)
88
- rspec-support (3.1.2)
85
+ rspec-support (~> 3.2.0)
86
+ rspec-mocks (3.2.1)
87
+ diff-lcs (>= 1.2.0, < 2.0)
88
+ rspec-support (~> 3.2.0)
89
+ rspec-support (3.2.2)
89
90
  sawyer (0.6.0)
90
91
  addressable (~> 2.3.5)
91
92
  faraday (~> 0.8, < 0.10)
data/README.md CHANGED
@@ -2,194 +2,72 @@
2
2
  [![Build
3
3
  Status](https://travis-ci.org/datapimp/brief.svg?branch=master)](https://travis-ci.org/datapimp/brief)
4
4
 
5
- Brief is a tool for building applications on top of collections of
6
- documents written in markdown.
5
+ ### Putting your writing to work
7
6
 
8
- Brief lets you define models very similar to how you would in
9
- ActiveRecord and Rails, but instead of rows in a database you are
10
- going to be working with files in a folder.
7
+ Brief lets writers build applications on top of collections of markdown
8
+ files. Brief lets you define different classes or types of documents, called
9
+ `Model`s.
11
10
 
12
- ### Getting Started
13
- ```
14
- gem install brief
15
- brief --help
16
- ```
17
-
18
- ### Hypothetical Example
11
+ These models turn the documents into objects, which can be
12
+ used to do things such as make API calls, or publish a blog post and
13
+ send an email campaign at the same time.
19
14
 
20
- ```
21
- brief init my-cookbook
22
- cd my-cookbook
23
- brief generate model Recipe # View the DOCUMENTATION for what you can do with a model
24
- brief write recipe # => opens up your $EDITOR with an example recipe
25
- ```
15
+ ### Turn documents into data
26
16
 
27
- Brief treats each markdown file as an active record style model object. It treats a folder of markdown files like a database.
17
+ The most basic way of combining writing with data, is through the use of
18
+ YAML Frontmatter as metadata for the document. For example:
28
19
 
29
- ### How does it work?
30
-
31
- Brief takes a markdown file which looks like:
32
-
33
- ```markdown
20
+ ```
34
21
  ---
35
22
  type: post
36
- status: active
23
+ status: draft
24
+ tags:
25
+ - help
26
+ - ruby
37
27
  ---
38
28
 
39
- # An introduction to brief
40
- ## Stop writing dead documents
29
+ # This is a title
30
+ ## This is a subtitle
41
31
 
42
- Brief is a tool which lets you define different patterns of markdown
43
- headings (h1,h2,h3 etc). This lets you work with collections of your
44
- writings, and treat each document as a database.
45
- ```
32
+ This is the first paragraph.
46
33
 
47
- And turns it into data, not only using the metadata up top, but also the information
48
- contained in the structure of the document itself. The headings, subheadings, pretty much
49
- anything you could query from the HTML using CSS can be turned into key value pairs that you can work
50
- with and build applications on top of.
51
-
52
- With your enhanced writing, you can do things like:
53
-
54
- ```ruby
55
- # Find all the posts which are active:
56
- posts = briefcase.posts.where(status:"published")
57
-
58
- # Get their titles, and subheadings:
59
- posts.map(&:title) #=>['An introduction to brief']
60
- posts.map(&:subheading) #=>['Stop writing dead documents']
61
-
62
- # Publish the post
63
- posts.first.publish()
64
-
65
- # Email the drafts to your editor
66
- posts.where(status:"draft").each &:mail_to_editors
34
+ This is another pargraph.
67
35
  ```
68
36
 
69
- From the Command line we can:
37
+ This YAML content at the top gets turned into data associated with the
38
+ document.
70
39
 
71
- ```bash
72
- brief publish posts
73
- brief write post #=> Opens your editor
40
+ ```
41
+ post = Post.new("/path/to/post.md")
42
+ post.status # => 'draft'
43
+ post.tags # => ['help','ruby']
74
44
  ```
75
45
 
76
- This type of interactivity is made possible by the `Brief::Model`
46
+ The YAML data is useful, but where the brief model system really shines
47
+ is in the ability to extract data and metadata from the writing itself.
77
48
 
78
- ### Documents as models
49
+ Each `Model` prescribes its own specific structure, usually
50
+ in the form of heading hierarchys (h1, h2, h3, etc). Any CSS selector
51
+ can be used against the rendered HTML produced by the markdown. A
52
+ model can define attributes that will be extracted from the writing, for
53
+ example:
79
54
 
80
55
  ```ruby
81
56
  define "Post" do
82
- meta do
83
- status
84
- end
85
-
86
57
  content do
87
58
  title "h1:first-of-type"
88
- subheading "h2:first-of-type"
89
- sample "p:first-of-type"
90
- end
91
-
92
- actions do
93
- def publish
94
- update_attributes(status: "published")
95
- end
96
- end
97
- end
98
- ```
99
-
100
- ### CLI Tool
101
-
102
- Brief gives you a CLI called `brief`
103
-
104
- This lets you run some general commands, but also gives you an
105
- intelligent interface to work with your models. In the above example,
106
- we defined some actions.
59
+ subtitle "h2:first-of-type"
60
+ excerpt "p:first-of-type"
107
61
 
108
- This will be available in the CLI:
109
-
110
- ```
111
- brief publish posts ./docs/posts/*.md
112
- ```
113
-
114
- This will find all of the matching documents, turn them into `Post`
115
- models, and then run the publish method on them. You can make your
116
- models as advanced as you want:
117
-
118
- ```
119
- define "Post" do
120
- actions do
121
- def submit
122
- update_attributes(status:"submitted to editors")
123
- mailer.send(:to => "jon@chicago.com", :subject => "Please review: #{ self.title }")
124
- end
62
+ # parses YAML blocks inside the document
63
+ settings 'code.yaml', :serialize => true
125
64
  end
126
65
  end
127
66
  ```
128
67
 
129
- ### YAML Frontmatter
130
-
131
- Each markdown document can contain YAML frontmatter. This data will be
132
- available and associated with each document or model, and will also let
133
- you query, filter, and sort your documents.
134
-
135
- ### CSS Structure Definition
136
-
137
- Since markdown renders into HTML, and HTML Documents can be queried
138
- using CSS selectors, we use CSS selectors in our model definition DSL so
139
- that we can isolate certain parts of the document, and use the content
140
- it contains as metadata.
141
-
142
- A real world example:
143
-
144
- ```ruby
145
- content do
146
- title "h1:first-of-type"
147
- define_section "User Stories" do
148
- each("h2").has(:title => "h2",
149
- :paragraph => "p:first-of-type",
150
- :components => "p:first-of-type strong"
151
- )
152
-
153
- each("h2").is_a :user_story
154
- end
155
- end
156
- ```
157
-
158
- This lets me turn a markdown file like:
159
-
160
- ```markdown
161
- ---
162
- title: Epic Example
163
- status: published
164
- ---
165
- # Epic Example
166
- # User Stories
167
-
168
- ## A user wants to do something
169
- As a **User** I would like to **Do this** so that I can **succeed**
68
+ ### Getting Started
170
69
 
171
- ## A user wants to do something else
172
- As a **User** I would like to **Do this** so that I can **succeed**
173
70
  ```
174
-
175
- into:
176
-
177
- ```ruby
178
- {
179
- title: "Epic Example",
180
- status: "published",
181
- type: "epic",
182
- user_stories:[{
183
- title: "A user wants to do something",
184
- paragraph: "As a user I would like to do something so that I can succeed",
185
- goal: "I can succeed",
186
- persona: "user",
187
- behavior: "do something"
188
- },{
189
- title: "A user wants to do something else",
190
- paragraph: "As a user I would like to do something else so that I can succeed"
191
- }]
192
- }
71
+ gem install brief
72
+ brief --help
193
73
  ```
194
-
195
- And we can even go in the other direction.
data/Rakefile CHANGED
@@ -2,6 +2,9 @@ Dir[File.join(Dir.pwd, 'tasks', '**', '*.rb')].each { |f| require f }
2
2
  Dir[File.join(Dir.pwd, 'tasks', '*.rake')].each { |f| load f }
3
3
 
4
4
  require "bundler/gem_tasks"
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
5
8
 
6
9
  Distribution.configure do |config|
7
10
  config.package_name = 'brief'
@@ -21,3 +24,5 @@ Distribution.configure do |config|
21
24
  'unf_ext-0.0.6'
22
25
  ]
23
26
  end
27
+
28
+ task :default => :spec
@@ -13,6 +13,10 @@ view(:summary) do |*args|
13
13
  end
14
14
  end
15
15
 
16
+ config do
17
+ set(:documentation_path, File.join(File.dirname(__FILE__), 'documentation'))
18
+ end
19
+
16
20
  class Brief::Briefcase
17
21
  def has_table_of_contents?
18
22
  docs_path.join('index.md').exist?
@@ -0,0 +1,13 @@
1
+ # Blueprint Diagram
2
+
3
+ The Diagram model is useful for combining notes with an SVG diagram.
4
+
5
+ One workflow I like to use is building a UML Diagram in Google Draw, and
6
+ exporting it as SVG. Then using a tool like Adobe Illustrator, I will
7
+ group the elements of the diagram, and then assign IDs and Classes to
8
+ them.
9
+
10
+ The Diagram document allows for a section called Annotations. The
11
+ Annotations section will be parsed, and treated as data. This allows
12
+ for rendering the diagram document, along with the diagram itself, and
13
+ displaying the annotations in a novel way.
@@ -0,0 +1,10 @@
1
+ # Feature Epics
2
+
3
+ The Feature Epic model is a document that is used to document a bunch of
4
+ related user stories related to a general feature category or group.
5
+
6
+ For example you might have a "3rd Party Integrations" Epic which has
7
+ User Stories for LinkedIn, Facebook, Github, and Twitter.
8
+
9
+ The Epic Document can be used to describe the importance of the module
10
+ as a whole at the same time that it captures the user stories.
@@ -0,0 +1,4 @@
1
+ # Milestone
2
+
3
+ The milestone represents a due date for a release or delivery of
4
+ software.
@@ -0,0 +1,6 @@
1
+ # Outline
2
+
3
+ The Outline document can be used to create a summary page with links to
4
+ a bunch of other pages.
5
+
6
+ The outline model can be
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Diagram
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  subheading
@@ -13,7 +15,7 @@ class Brief::Apps::Blueprint::Diagram
13
15
  subheading "h2:first-of-type"
14
16
 
15
17
  define_section "Annotations" do
16
- each("h2").has(:title => "h3",
18
+ each("h2").has(:title => "h2",
17
19
  :paragraphs => "p",
18
20
  :settings => "code")
19
21
  end
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Epic
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  subheading
@@ -1,6 +1,8 @@
1
- class Brief::Apps::Blueprint::Milestones
1
+ class Brief::Apps::Blueprint::Milestone
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  number
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Outline
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  type
6
8
  end
@@ -14,5 +16,16 @@ class Brief::Apps::Blueprint::Outline
14
16
  h6 "h6"
15
17
  headings "h1,h2,h3,h4,h5,h6"
16
18
  settings "code.yaml:first-of-type", :serialize => :yaml, :hide => true
19
+
20
+ nested_links "li a"
21
+
22
+ items "ul > li"
23
+ nested_items "ul > li li"
24
+ end
25
+
26
+ helpers do
27
+ def link_elements
28
+ document.css('a')
29
+ end
17
30
  end
18
31
  end
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Page
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  category
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Persona
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  end
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Project
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  category
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Release
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  status
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Roadmap
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  subheading
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Sitemap
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  status
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::UserStory
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  status :in => %w(draft published)
@@ -1,6 +1,8 @@
1
1
  class Brief::Apps::Blueprint::Wireframe
2
2
  include Brief::Model
3
3
 
4
+ defined_in Pathname(__FILE__)
5
+
4
6
  meta do
5
7
  title
6
8
  parent_title
data/lib/brief.rb CHANGED
@@ -69,7 +69,9 @@ module Brief
69
69
  def self.load_commands
70
70
  Dir[lib_root.join('brief', 'cli', '**/*.rb')].each { |f| require(f) }
71
71
 
72
- # the instance methods which get defined with the helper
72
+ # Each Brief::Model can define certain "actions" which can be called on the documents.
73
+ #
74
+ # The Brief CLI interface lets users dispatch these actions to the documents specified by the PATH args.
73
75
  Brief::Model.classes.each do |klass|
74
76
  Array(klass.defined_actions).uniq.each do |action|
75
77
  Brief::Util.create_method_dispatcher_command_for(action, klass)
@@ -125,6 +127,7 @@ require 'brief/model/serializers'
125
127
  require 'brief/data'
126
128
  require 'brief/dsl'
127
129
  require 'brief/server'
130
+ require 'brief/briefcase/documentation'
128
131
  require 'brief/briefcase'
129
132
  require 'brief/apps'
130
133
 
@@ -1,6 +1,7 @@
1
1
  module Brief
2
2
  class Briefcase
3
3
  include Brief::DSL
4
+ include Brief::Briefcase::Documentation
4
5
 
5
6
  attr_reader :options,
6
7
  :model_definitions
@@ -50,6 +51,9 @@ module Brief
50
51
  end
51
52
  end
52
53
 
54
+ # TODO
55
+ # The serialization of an entire briefcase at once
56
+ # is important enough to be its own module
53
57
  def as_default(params={})
54
58
  params.symbolize_keys!
55
59
 
@@ -74,6 +78,10 @@ module Brief
74
78
  base[:schema] = schema_map
75
79
  end
76
80
 
81
+ if params[:include_documentation] || params[:documentation]
82
+ base[:documentation] = render_documentation
83
+ end
84
+
77
85
  if params[:include_models] || params[:models]
78
86
  model_settings = {
79
87
  docs_path: docs_path
@@ -106,12 +114,6 @@ module Brief
106
114
  run(app_config_path) if app_path.try(&:exist?)
107
115
  end
108
116
 
109
- def schema_map(include_all=false)
110
- list = include_all ? Brief::Model.classes : model_classes
111
- list.map(&:to_schema)
112
- .reduce({}.to_mash) {|m, k| m[k[:type_alias]] = k; m }
113
- end
114
-
115
117
  def data
116
118
  @data ||= data!
117
119
  end
@@ -0,0 +1,36 @@
1
+ module Brief
2
+ class Briefcase
3
+ module Documentation
4
+
5
+ class ModelDoc
6
+ def initialize(path)
7
+ @content = Pathname(path).read
8
+ end
9
+
10
+ def content
11
+ @content
12
+ end
13
+
14
+ def rendered
15
+ ::GitHub::Markdown.render_gfm(content)
16
+ end
17
+ end
18
+
19
+ def render_documentation(include_all=false)
20
+ list = include_all ? Brief::Model.classes : model_classes
21
+
22
+ list.reduce({}.to_mash) do |memo, klass|
23
+ docs = klass.to_documentation rescue {}
24
+ memo[klass.type_alias] = docs unless docs.empty?
25
+ memo
26
+ end
27
+ end
28
+
29
+ def schema_map(include_all=false)
30
+ list = include_all ? Brief::Model.classes : model_classes
31
+ list.map(&:to_schema)
32
+ .reduce({}.to_mash) {|m, k| m[k[:type_alias]] = k; m }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,42 +1,3 @@
1
- command 'dispatch export' do |c|
2
- c.syntax = 'brief dispatch export PATH [OPTIONS]'
3
- c.description = 'dispatch the export the briefcase found in PATH'
4
-
5
- c.option '--presenter-format FORMAT', String, 'Which presenter to use?'
6
- c.option '--include-schema', 'Include schema information'
7
- c.option '--include-models', 'Include individual models as well'
8
- c.option '--include-data', 'Gets passed to the model renderers if present'
9
- c.option '--include-content', 'Gets passed to the model renderers if present'
10
- c.option '--include-rendered', 'Gets passed to the model renderers if present'
11
- c.option '--include-attachments', 'Gets passed to the model renderers if present'
12
- c.option '--include-urls', 'Gets passed to the model renderers if present'
13
- c.option '--gateway', 'The remote server is a gateway'
14
- c.option '--port DRB_PORT', String, 'The DRb port to use'
15
- c.option '--briefcase KEY', String, 'Which briefcase should we use? if this is a gateway'
16
- c.option '--output FILE', String, 'Save the output in the specified path'
17
- c.option '--format FORMAT', String, 'How to format the CLI output: defaults to printed, accepts printed,json'
18
- c.option '--prefix-output CONTENT', String, 'Prefix the generated output with the following content'
19
-
20
- c.when_called do |args, options|
21
- require 'drb'
22
- options.default(:port => 9000, briefcase: Pathname(Brief.pwd).dirname.to_s)
23
-
24
- remote = DRbObject.new(nil, "druby://:#{ options.port }")
25
-
26
- if options.gateway
27
- remote = remote.briefcases[options.briefcase]
28
- end
29
-
30
- result = remote.present(options.presenter_format, rendered: options.include_rendered,
31
- content: options.include_content,
32
- urls: options.include_urls,
33
- schema: options.include_schema,
34
- data: options.include_data,
35
- attachments: options.include_attachments,
36
- models: options.include_models).as_json
37
- end
38
- end
39
-
40
1
  command 'export' do |c|
41
2
  c.syntax = 'brief export PATH [OPTIONS]'
42
3
  c.description = 'export the briefcase found in PATH'
@@ -9,10 +9,19 @@ module Brief
9
9
  Array(data.attachments)
10
10
  end
11
11
 
12
+ def attachment_paths
13
+ attachments.reduce({}.to_mash) do |memo, name|
14
+ if asset = briefcase.find_asset(name)
15
+ memo[name] = asset.realpath.to_s
16
+ memo
17
+ end
18
+ end
19
+ end
20
+
12
21
  def render_attachments
13
22
  attachments.reduce({}.to_mash) do |memo, name|
14
23
  if asset = briefcase.find_asset(name)
15
- memo[name] = IO.read(asset)
24
+ memo[name] = IO.read(asset) if asset.to_s.match(/\.svg/i)
16
25
  memo
17
26
  end
18
27
  end
data/lib/brief/model.rb CHANGED
@@ -124,12 +124,36 @@ module Brief
124
124
  (definition.content_schema.attributes.keys + definition.metadata_schema.keys).uniq
125
125
  end
126
126
 
127
+ def to_documentation
128
+ docs = definition.documentation
129
+
130
+ path = if docs.markdown
131
+ Pathname(docs.markdown)
132
+ elsif defined_in
133
+ basename = defined_in.basename.to_s.gsub(/.rb/,'')
134
+ defined_in.parent.join('..','documentation',"#{basename}.md")
135
+ end
136
+
137
+ if path
138
+ model_doc = Brief::Briefcase::Documentation::ModelDoc.new(path)
139
+
140
+ {
141
+ content: model_doc.content,
142
+ rendered: model_doc.rendered
143
+ }
144
+ else
145
+ {
146
+ }
147
+ end
148
+ end
149
+
127
150
  def to_schema
128
151
  {
129
152
  schema: {
130
153
  content: definition.content_schema,
131
154
  metadata: definition.metadata_schema,
132
155
  },
156
+ documentation: to_documentation,
133
157
  class_name: to_s,
134
158
  type_alias: type_alias,
135
159
  name: name,
@@ -236,10 +260,22 @@ module Brief
236
260
  definition.send(:example_body, *args).to_s.strip
237
261
  end
238
262
 
263
+ def documentation(*args)
264
+ definition.send(:documentation, *args)
265
+ end
266
+
267
+ def defined_in(*args)
268
+ definition.send(:defined_in, *args)
269
+ end
270
+
239
271
  def method_missing(meth, *args, &block)
272
+ # these methods when called at a class level inside of
273
+ # a class definition body will modify the schema settings for that model
240
274
  if %w(meta content template example actions helpers).include?(meth.to_s)
241
275
  definition.send(meth, *args, &block)
242
276
  finalize
277
+ # these methods allow the model class to inspect itself and report
278
+ # whatever methods and actions are defined on the model class
243
279
  elsif %w(defined_helper_methods defined_actions).include?(meth.to_s)
244
280
  definition.send(meth)
245
281
  elsif meth.to_s.match(/^on_(.*)_change$/)
@@ -19,6 +19,8 @@ module Brief
19
19
  @section_mappings = {}.to_mash
20
20
  @content_schema = { attributes: {} }.to_mash
21
21
  @model_class = options[:model_class]
22
+
23
+ @doc_options = {}.to_mash
22
24
  end
23
25
 
24
26
  def valid?
@@ -61,6 +63,23 @@ module Brief
61
63
  Brief.configuration.model_namespace || Brief::Model
62
64
  end
63
65
 
66
+ # TODO
67
+ # There is probably a way to inspect the filename of the code calling you
68
+ # which would be a better way of handling this that doesn't require
69
+ def defined_in(filename=nil)
70
+ if filename
71
+ filename = Pathname(filename)
72
+ @doc_options[:defined_in] = filename
73
+ end
74
+
75
+ @doc_options[:defined_in]
76
+ end
77
+
78
+ def documentation(options={}, &block)
79
+ @doc_options.merge!(options) if options
80
+ @doc_options
81
+ end
82
+
64
83
  def meta(_options = {}, &block)
65
84
  @current = :meta
66
85
  instance_eval(&block)
@@ -33,6 +33,7 @@ module Brief::Model::Serializers
33
33
 
34
34
  if options[:attachments] || options[:include_attachments]
35
35
  h[:attachments] = document.render_attachments
36
+ h[:attachment_paths] = document.attachment_paths
36
37
  end
37
38
 
38
39
  h[:urls] = {
data/lib/brief/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Brief
2
- VERSION = '1.9.9'
2
+ VERSION = '1.9.11'
3
3
  end
@@ -6,7 +6,12 @@ describe "Packaged Apps" do
6
6
  end
7
7
 
8
8
  let(:blueprint) do
9
- Brief::Briefcase.new(app: "blueprint")
9
+ Brief::Briefcase.new(app: "blueprint", root: Brief.spec_root.join('fixtures','example'))
10
+ end
11
+
12
+ it "renders documentation for the app" do
13
+ rendered = blueprint.render_documentation.epic.rendered
14
+ expect(rendered).to include("h1")
10
15
  end
11
16
 
12
17
  it "should find the right path for an app name" do
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.9.9
4
+ version: 1.9.11
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-05-11 00:00:00.000000000 Z
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -289,6 +289,20 @@ files:
289
289
  - Rakefile
290
290
  - TUTORIAL.md
291
291
  - apps/blueprint/config.rb
292
+ - apps/blueprint/documentation/diagram.md
293
+ - apps/blueprint/documentation/epic.md
294
+ - apps/blueprint/documentation/milestone.md
295
+ - apps/blueprint/documentation/outline.md
296
+ - apps/blueprint/documentation/page.md
297
+ - apps/blueprint/documentation/persona.md
298
+ - apps/blueprint/documentation/project.md
299
+ - apps/blueprint/documentation/release.md
300
+ - apps/blueprint/documentation/roadmap.md
301
+ - apps/blueprint/documentation/sitemap.md
302
+ - apps/blueprint/documentation/user_story.md
303
+ - apps/blueprint/documentation/wireframe.md
304
+ - apps/blueprint/example/brief.rb
305
+ - apps/blueprint/example/docs/diagrams/example-diagram.md
292
306
  - apps/blueprint/models/diagram.rb
293
307
  - apps/blueprint/models/epic.rb
294
308
  - apps/blueprint/models/milestone.rb
@@ -314,6 +328,7 @@ files:
314
328
  - lib/brief/adapters/middleman_extension.rb
315
329
  - lib/brief/apps.rb
316
330
  - lib/brief/briefcase.rb
331
+ - lib/brief/briefcase/documentation.rb
317
332
  - lib/brief/briefcase/initializer.rb
318
333
  - lib/brief/cli/01_extensions.rb
319
334
  - lib/brief/cli/all.rb