brief 1.0.0 → 1.1.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: 5de4de1da31d941ba973047d92612413463c2cfa
4
- data.tar.gz: 9fbd98bbe85b00b6fdefabde34f79c03e6ceb6d4
3
+ metadata.gz: 4ea25b279da5166d726a9463be10836ab9b6d7bb
4
+ data.tar.gz: e52d0270a01c924196c8ab59250df0973320589d
5
5
  SHA512:
6
- metadata.gz: 47d96dd1a4537378b35dc5af7f8fef84e0d80fc484497d14c90119fed09776f3274ac0b464402f858f7348f555a26e8cb45dcb9d488124ad56010ef950661d3b
7
- data.tar.gz: 536970830fd8c5d7b4c4b1a3eaad68043932f5b562d07d5b714f3852db1c39eb5ba3847c4f62d056e17ab291d772d10d4f0fb1a3d3cb656d255233c540b23525
6
+ metadata.gz: 250b23f611f467ec9731114557f84d8bf24e498642849eab59dcb79f7a7c1790ea33b8f734a3017f515ad025caf5353625b0ec972c7e016eb7682eafe9aa063a
7
+ data.tar.gz: 88a4250edb54523fdb51f18700a149831a5835d031cf67fbc49c142bb6d3abeccec9eff48c32df99f9ded979330c9223b7f7934819b87e4f79f33a67292b2e3e
@@ -0,0 +1,2 @@
1
+ # the test suite writes to this
2
+ spec/fixtures/example/docs/epic.html.md
data/README.md CHANGED
@@ -2,171 +2,110 @@
2
2
 
3
3
  An ActiveRecord style layer on top of a folder of markdown files.
4
4
 
5
- ### No more dead documents
5
+ Treat your markdown documents as active models, run actions on them,
6
+ convert them into HTML, extract fragments of HTML, combine it all in
7
+ whatever interesting way you can think of.
6
8
 
7
- Brief is a tool that lets you build simple applications on top of
8
- collections of markdown files. The metaphor we use is a briefcase,
9
- which contains folders with different document types.
9
+ The end result is a really neat way of being able to use the words that you write
10
+ to power all sorts of applications.
10
11
 
11
- Every document type, or model, can define a simple schema of attributes,
12
- which can be specified in a YAML frontmatter preamble at the very top of
13
- each document.
12
+ **No more writing dead documents!**
14
13
 
15
- In addition to frontmatter metadata, you can declare other model
16
- attributes as CSS selectors. For example, the very first h1 heading
17
- could be the title for your document, and the corresponding model for
18
- that document would have a `title` method which returned its value.
14
+ ### Documents as Models
19
15
 
20
- This is a great way to build applications whose primary interface is the
21
- text editor, allowing writing and thought to flow as freely as possible
22
- and to later be used to power some automation tasks.
23
-
24
- **Think of it as an ActiveRecord like layer on top of a folder of
25
- Markdown files**. Brief turns static text into a 'living' data object.
26
-
27
- ## Getting started
28
-
29
- ```bash
30
- gem install brief
31
- mkdir blog
32
- cd blog
33
- brief init
34
- ```
35
-
36
- This will create a new folder for your briefcase, along with the
37
- following config file and structure.
38
-
39
- ```
40
- - docs/
41
- - an-introduction-to-brief.html.md
42
- - models/
43
- - brief.rb
44
- ```
45
-
46
- The config file will look like:
16
+ Brief lets you treat an individual markdown file as if it were a model,
17
+ complete with validations, callbacks, and methods you can run. You can
18
+ define a `Post` model for all of the files in a 'posts' folder and
19
+ define actions like 'publish' on them.
47
20
 
48
21
  ```ruby
49
-
50
- # configuration options for this briefcase
51
- config do
52
- set(:models_path => Pathname(__FILE__).parent.join("models"))
53
- end
54
-
55
- # define a Post model
56
- define("Post") do
57
-
58
- # the post model will have YAML frontmatter
59
- # with values for 'status' and 'date'
22
+ define "Post" do
60
23
  meta do
61
24
  status
62
- date DateTime, :default => lambda {|post, attr| post.document.created_at }
25
+ tags Array
63
26
  end
64
-
65
- # the post model will have a 'title' method which returns the text
66
- # from the first h1 heading
27
+
67
28
  content do
68
- title "h1"
29
+ has_one :title, "h1"
69
30
  has_many :subheadings, "h2"
70
31
  end
71
32
 
72
- helpers do
73
- def publish(options={})
74
-
33
+ actions do
34
+ def publish
35
+ update_attributes(:status => "published")
75
36
  end
76
37
  end
77
-
78
- # Whenever we call post.save() and the status attribute changes
79
- # from draft to published, do something with the model
80
- on_status_change(:from => "draft", :to => "published") do |model|
81
- # Do Something
82
- # mail_service.send_html_email_campaign(model.to_html)
83
- end
84
38
  end
39
+ ```
85
40
 
86
- # this creates a custom command in the brief CLI tool
87
- #
88
- # so when you run:
89
- #
90
- # brief publish posts /path/to/*.html.md.
91
- #
92
- # the brief CLI will find models for the post files you reference,
93
- # and call whatever methods you want.
94
41
 
95
- action "publish posts" do |briefcase, models, options|
42
+ ### Model attributes derived from YAML frontmatter
96
43
 
97
- say "== Publishing #{ models.length } posts"
44
+ Models can get their attributes from headers on the document, aka YAML frontmatter.
98
45
 
99
- Array(models).each do |post|
100
- post.publish()
101
- end
102
- end
46
+ ```markdown
47
+ ---
48
+ status: draft
49
+ tags:
50
+ - demo
51
+ - sample
52
+ ---
53
+
54
+ # Title
55
+
56
+ ## Section One
57
+ ## Section Two
103
58
  ```
104
59
 
105
- ### Real World Application
60
+ which will let you use it like such:
61
+
62
+ ```ruby
63
+ post = Brief::Document.new(/path/to/doc.html.md)
64
+
65
+ post.status #=> "draft"
66
+ post.title #=> "Title"
67
+ post.tags #=> ['demo','sample']
68
+ ```
106
69
 
107
- My company Architects.io, Inc. uses brief to power our Blueprint
108
- software. A Blueprint is a collection of related documents that are
109
- used in the software architecture and design process, as well as in the
110
- day to day writing that takes place while building the software itself.
70
+ #### Model attributes derived from the document structure
111
71
 
112
- This includes things like:
72
+ Models can also get their attributes from the structure itself.
113
73
 
114
- - daily standups
115
- - bug reports
116
- - code reviews
117
- - feature epics
118
- - user stories
119
- - integration tests
120
- - release notes
121
- - wireframe annotations
74
+ ```ruby
75
+ post.title #=> "Title"
76
+ post.subheadings #=> ["Section One", "Section Two"]
77
+ ```
122
78
 
123
- All of these things are simple markdown files. They live in the
124
- projects we are working on, and by treating our writing as a structured
125
- exercise we are able to do a lot more things with it than just read it.
79
+ ### Querying Documents
126
80
 
127
- For example we can do:
81
+ Given a big folder of markdown files with attributes, we can query them:
128
82
 
129
83
  ```
130
- brief publish user stories /path/to/user-stories/*.html.md
84
+ posts = briefcase.posts.where(:status => "published")
85
+ posts.map(&:title) #=> ['Title']
131
86
  ```
132
87
 
133
- which is implemented by:
88
+ This functionality is based on https://github.com/ralph/document_mapper,
89
+ and similar to middleman.
134
90
 
135
- ```ruby
136
- # brief.rb
91
+ ### Document Actions
137
92
 
138
- define "User Story" do
139
- meta do
140
- status
141
- end
93
+ By defining actions on documents like so:
142
94
 
143
- content do
144
- title "h1"
145
- paragraph "p:first-child"
146
- persona "p:first-child strong:1st-child"
147
- behavior "p:first-child strong:2nd-child"
148
- goal "p:first-child strong:3rd-child"
149
- end
95
+ ```ruby
150
96
 
151
- helpers do
152
- def create_github_issue
153
- issue = github.create_issue(title: title, body: document.content)
154
- set(issue_number: issue.number)
97
+ define "Post" do
98
+ actions do
99
+ def publish
100
+ # DO Something
155
101
  end
156
102
  end
157
103
  end
104
+ ```
158
105
 
159
- action "publish user stories" do |briefcase, models, options|
160
- user_stories = models
106
+ you can either call that method as you normally would, or you can run
107
+ that action from the command line:
161
108
 
162
- user_stories.each do |user_story|
163
- if user_story.create_github_issue()
164
- user_story.status = "published"
165
- user_story.save
166
- end
167
- end
168
- end
109
+ ```bash
110
+ brief publish posts ./posts/*.html.md
169
111
  ```
170
-
171
- As you can see, Brief can be a way to make your Markdown writing efforts
172
- much more productive.
@@ -0,0 +1,146 @@
1
+ ## Tutorial
2
+
3
+ ```bash
4
+ gem install brief
5
+ mkdir blog
6
+ cd blog
7
+ brief init
8
+ ```
9
+
10
+ This will create a new folder for your briefcase, along with the
11
+ following config file and structure.
12
+
13
+ ```
14
+ - docs/
15
+ - an-introduction-to-brief.html.md
16
+ - models/
17
+ - brief.rb
18
+ ```
19
+
20
+ The config file will look like:
21
+
22
+ ```ruby
23
+
24
+ # configuration options for this briefcase
25
+ config do
26
+ set(:models_path => Pathname(__FILE__).parent.join("models"))
27
+ end
28
+
29
+ # define a Post model
30
+ define("Post") do
31
+
32
+ # the post model will have YAML frontmatter
33
+ # with values for 'status' and 'date'
34
+ meta do
35
+ status
36
+ date DateTime, :default => lambda {|post, attr| post.document.created_at }
37
+ end
38
+
39
+ # the post model will have a 'title' method which returns the text
40
+ # from the first h1 heading
41
+ content do
42
+ title "h1"
43
+ has_many :subheadings, "h2"
44
+ end
45
+
46
+ helpers do
47
+ def publish(options={})
48
+
49
+ end
50
+ end
51
+
52
+ # Whenever we call post.save() and the status attribute changes
53
+ # from draft to published, do something with the model
54
+ on_status_change(:from => "draft", :to => "published") do |model|
55
+ # Do Something
56
+ # mail_service.send_html_email_campaign(model.to_html)
57
+ end
58
+ end
59
+
60
+ # this creates a custom command in the brief CLI tool
61
+ #
62
+ # so when you run:
63
+ #
64
+ # brief publish posts /path/to/*.html.md.
65
+ #
66
+ # the brief CLI will find models for the post files you reference,
67
+ # and call whatever methods you want.
68
+
69
+ action "publish posts" do |briefcase, models, options|
70
+
71
+ say "== Publishing #{ models.length } posts"
72
+
73
+ Array(models).each do |post|
74
+ post.publish()
75
+ end
76
+ end
77
+ ```
78
+
79
+ ### Real World Application
80
+
81
+ My company Architects.io, Inc. uses brief to power our Blueprint
82
+ software. A Blueprint is a collection of related documents that are
83
+ used in the software architecture and design process, as well as in the
84
+ day to day writing that takes place while building the software itself.
85
+
86
+ This includes things like:
87
+
88
+ - daily standups
89
+ - bug reports
90
+ - code reviews
91
+ - feature epics
92
+ - user stories
93
+ - integration tests
94
+ - release notes
95
+ - wireframe annotations
96
+
97
+ All of these things are simple markdown files. They live in the
98
+ projects we are working on, and by treating our writing as a structured
99
+ exercise we are able to do a lot more things with it than just read it.
100
+
101
+ For example we can do:
102
+
103
+ ```
104
+ brief publish user stories /path/to/user-stories/*.html.md
105
+ ```
106
+
107
+ which is implemented by:
108
+
109
+ ```ruby
110
+ # brief.rb
111
+
112
+ define "User Story" do
113
+ meta do
114
+ status
115
+ end
116
+
117
+ content do
118
+ title "h1"
119
+ paragraph "p:first-child"
120
+ persona "p:first-child strong:1st-child"
121
+ behavior "p:first-child strong:2nd-child"
122
+ goal "p:first-child strong:3rd-child"
123
+ end
124
+
125
+ helpers do
126
+ def create_github_issue
127
+ issue = github.create_issue(title: title, body: document.content)
128
+ set(issue_number: issue.number)
129
+ end
130
+ end
131
+ end
132
+
133
+ action "publish user stories" do |briefcase, models, options|
134
+ user_stories = models
135
+
136
+ user_stories.each do |user_story|
137
+ if user_story.create_github_issue()
138
+ user_story.status = "published"
139
+ user_story.save
140
+ end
141
+ end
142
+ end
143
+ ```
144
+
145
+ As you can see, Brief can be a way to make your Markdown writing efforts
146
+ much more productive.
@@ -20,35 +20,9 @@ define("Post") do
20
20
  has_many :subheadings, "h2"
21
21
  end
22
22
 
23
- helpers do
23
+ actions do
24
24
  def publish(options={})
25
-
25
+ puts "The publish action"
26
26
  end
27
27
  end
28
-
29
- # Whenever we call post.save() and the status attribute changes
30
- # from draft to published, do something with the model
31
- on_status_change(:from => "draft", :to => "published") do |model|
32
- # Do Something
33
- # mail_service.send_html_email_campaign(model.to_html)
34
- end
35
- end
36
-
37
- # this creates a custom command in the brief CLI tool
38
- #
39
- # so when you run:
40
- #
41
- # brief publish posts /path/to/*.html.md.
42
- #
43
- # the brief CLI will find models for the post files you reference,
44
- # and call whatever methods you want.
45
-
46
- action "publish posts" do |briefcase, models, options|
47
-
48
- say "== Publishing #{ models.length } posts"
49
-
50
- Array(models).each do |post|
51
- post.publish()
52
- end
53
28
  end
54
-
@@ -28,6 +28,13 @@ module Brief
28
28
 
29
29
  def self.load_commands
30
30
  Dir[gem_root.join("brief","cli","**/*.rb")].each {|f| require(f) }
31
+
32
+ # the instance methods which get defined with the helper
33
+ Brief::Model.classes.each do |klass|
34
+ Array(klass.defined_actions).uniq.each do |action|
35
+ Brief::Util.create_method_dispatcher_command_for(action, klass)
36
+ end
37
+ end
31
38
  end
32
39
 
33
40
  def self.load_models(from_folder=nil)
@@ -37,6 +44,7 @@ end
37
44
 
38
45
  require "brief/core_ext"
39
46
  require "brief/version"
47
+ require "brief/util"
40
48
  require "brief/configuration"
41
49
  require "brief/document/rendering"
42
50
  require "brief/document/front_matter"
@@ -1,3 +1,4 @@
1
+ # Credit to github.com/ralph/document_mapper
1
2
  module Brief::DocumentMapper
2
3
  OPERATOR_MAPPING = {
3
4
  'equal' => :==,
@@ -13,9 +13,10 @@ module Brief
13
13
  include AccessorMethods
14
14
  include Persistence
15
15
 
16
- class_attribute :models, :after_initialization_hooks, :defined_helpers
16
+ class_attribute :models, :after_initialization_hooks, :defined_actions
17
17
 
18
18
  self.models = Array(self.models).to_set
19
+ self.defined_actions = Array(self.defined_actions).to_set
19
20
 
20
21
  class << self
21
22
  include Enumerable
@@ -69,21 +70,7 @@ module Brief
69
70
 
70
71
  def self.finalize
71
72
  Virtus.finalize
72
-
73
- classes.each do |klass|
74
- klass.name ||= klass.to_s.split('::').last.humanize
75
- klass.type_alias ||= klass.name.parameterize.gsub(/-/,'_')
76
-
77
- klass.attribute_set.map(&:name).each do |attr|
78
- klass.define_singleton_method("find_by_#{ attr }") do |value|
79
- where(attr => value).first
80
- end
81
- end
82
-
83
- klass.definition.apply_config
84
- end
85
-
86
- Brief::Repository.define_document_finder_methods
73
+ classes.each(&:finalize)
87
74
  end
88
75
 
89
76
  def ==(other)
@@ -95,24 +82,35 @@ module Brief
95
82
  end
96
83
 
97
84
  module ClassMethods
98
- def where(*args, &block)
99
- Brief::DocumentMapper::Query.new(self).send(:where, *args)
85
+ def has_actions?
86
+ definition.has_actions?
100
87
  end
101
88
 
102
- def each(*args, &block)
103
- Array(self.models).send(:each, *args, &block)
104
- end
89
+ def finalize
90
+ klass = self
91
+
92
+ klass.name ||= klass.to_s.split('::').last.humanize
93
+ klass.type_alias ||= klass.name.parameterize.gsub(/-/,'_')
94
+
95
+ klass.attribute_set.map(&:name).each do |attr|
96
+ unless klass.method_defined?("find_by_#{ attr }")
97
+ klass.define_singleton_method("find_by_#{ attr }") do |value|
98
+ where(attr => value).first
99
+ end
100
+ end
101
+ end
102
+
103
+ klass.definition.apply_config
105
104
 
106
- def meta(options={}, &block)
107
- definition.send(:meta, options, &block)
105
+ Brief::Repository.define_document_finder_methods
108
106
  end
109
107
 
110
- def content(options={}, &block)
111
- definition.send(:content, options, &block)
108
+ def where(*args, &block)
109
+ Brief::DocumentMapper::Query.new(self).send(:where, *args)
112
110
  end
113
111
 
114
- def actions(&block)
115
- definition.send(:helpers, &block)
112
+ def each(*args, &block)
113
+ Array(self.models).send(:each, *args, &block)
116
114
  end
117
115
 
118
116
  def after_initialize(&block)
@@ -144,7 +142,10 @@ module Brief
144
142
  end
145
143
 
146
144
  def method_missing(meth, *args, &block)
147
- if meth.to_s.match(/^on_(.*)_change$/)
145
+ if %w(meta content actions helpers).include?(meth.to_s)
146
+ definition.send(meth, &block)
147
+ finalize
148
+ elsif meth.to_s.match(/^on_(.*)_change$/)
148
149
  create_change_handler($1, *args, &block)
149
150
  else
150
151
  super
@@ -27,7 +27,7 @@ module Brief
27
27
  create_model_class.tap do |k|
28
28
  k.send(:include, Brief::Model)
29
29
 
30
- k.definition = definition
30
+ k.definition ||= definition
31
31
 
32
32
  k.name ||= name
33
33
  k.type_alias ||= type_alias
@@ -40,21 +40,22 @@ module Brief
40
40
  end
41
41
 
42
42
  def apply_config
43
+ # define a virtus attribute mapping
43
44
  metadata_schema.values.each do |settings|
44
- if model_class.nil?
45
- binding.pry
46
- end
47
-
48
45
  model_class.send(:attribute, *(settings[:args]))
49
46
  end
50
47
 
51
- Array(self.defined_helpers).each do |mod|
52
- model_class.send(:include, mod)
53
- end
48
+ # defined helpers adds an anonymous module include
49
+ Array(self.defined_helpers).each {|mod| model_class.send(:include, mod) }
50
+
51
+ model_class.defined_actions += Array(self.defined_actions)
52
+ true
54
53
  end
55
54
 
56
55
  def create_model_class
57
- model_namespace.const_set(type_alias.camelize, Class.new) unless model_class
56
+ unless (model_namespace.const_get(type_alias.camelize) rescue nil)
57
+ model_namespace.const_set(type_alias.camelize, Class.new)
58
+ end
58
59
  end
59
60
 
60
61
  def model_class
@@ -75,6 +76,18 @@ module Brief
75
76
  instance_eval(&block)
76
77
  end
77
78
 
79
+ def has_actions?
80
+ !@defined_actions.empty?
81
+ end
82
+
83
+ def actions(&block)
84
+ helpers(&block)
85
+ end
86
+
87
+ def defined_actions
88
+ Array(defined_helpers).map(&:instance_methods).flatten
89
+ end
90
+
78
91
  def helpers(&block)
79
92
  self.defined_helpers ||= []
80
93
 
@@ -0,0 +1,7 @@
1
+ module Brief
2
+ module Model::Persistence
3
+ extend ActiveSupport::Concern
4
+
5
+
6
+ end
7
+ end
@@ -0,0 +1,36 @@
1
+ module Brief::Util
2
+ def self.create_method_dispatcher_command_for(action, klass)
3
+ identifier = "#{ action } #{ klass.type_alias.to_s.pluralize }"
4
+
5
+ Object.class.class_eval do
6
+ command "#{identifier}" do |c|
7
+ c.syntax = "brief #{identifier}"
8
+ c.description = "run the #{identifier} command"
9
+
10
+ c.action do |args, opts|
11
+ briefcase = Brief.case
12
+
13
+ path_args = args.select {|arg| arg.is_a?(String) && arg.match(/\.md$/) }
14
+
15
+ path_args.select! do |arg|
16
+ path = briefcase.repository.root.join(arg)
17
+ path.exist?
18
+ end
19
+
20
+ path_args.map! {|p| briefcase.repository.root.join(p) }
21
+
22
+ models = path_args.map {|path| Brief::Document.new(path) }.map(&:to_model)
23
+
24
+ if models.empty?
25
+ model_finder = c.name.to_s.split(' ').last
26
+ models = briefcase.send(model_finder)
27
+ end
28
+
29
+ models.each do |model|
30
+ model.send(action)
31
+ end
32
+ end
33
+ end rescue nil
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module Brief
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -15,13 +15,13 @@ define "User Story" do
15
15
  goal "p strong:third-child"
16
16
  end
17
17
 
18
- helpers do
18
+ actions do
19
19
  def defined_helper_method
20
20
  true
21
21
  end
22
- end
23
- end
24
22
 
25
- action "custom command" do
26
- $custom_command = true
23
+ def custom_action
24
+ true
25
+ end
26
+ end
27
27
  end
@@ -2,7 +2,8 @@ class Brief::Epic
2
2
  include Brief::Model
3
3
 
4
4
  meta do
5
- title String
5
+ title
6
+ subheading
6
7
  status String, :in => %w(draft published)
7
8
  end
8
9
 
@@ -13,4 +14,9 @@ class Brief::Epic
13
14
  has_many :user_stories, "h2" => "title", "p:first-child" => "paragraph"
14
15
  end
15
16
  end
17
+
18
+ actions do
19
+ def custom_action
20
+ end
21
+ end
16
22
  end
@@ -31,6 +31,11 @@ describe "The Brief Model" do
31
31
  set = Brief::Model::UserStory.attribute_set.map(&:name)
32
32
  expect(set).to include(:title, :status, :epic_title)
33
33
  end
34
+
35
+ it "has attribute setters" do
36
+ story = Brief::Model::UserStory.new
37
+ expect(story).to respond_to(:title=)
38
+ end
34
39
  end
35
40
 
36
41
  context "Class Definitions" do
@@ -55,6 +60,12 @@ describe "The Brief Model" do
55
60
  set = Brief::Epic.attribute_set.map(&:name)
56
61
  expect(set).to include(:path, :document, :title, :status)
57
62
  end
63
+
64
+ it "has attribute setters" do
65
+ epic = Brief::Epic.new
66
+ expect(epic).to respond_to(:title=)
67
+ expect(epic).to respond_to(:subheading=)
68
+ end
58
69
  end
59
70
 
60
71
  context "Briefcase Finders" do
@@ -81,4 +92,14 @@ describe "The Brief Model" do
81
92
  expect(epic.extracted.title).to eq("Blueprint Epic Example")
82
93
  end
83
94
  end
95
+
96
+ context "Actions and Helpers" do
97
+ it "uses the actions block to define CLI dispatchers" do
98
+ expect(epic.class.defined_actions).to include(:custom_action)
99
+ end
100
+
101
+ it "users the actions block to define CLI dispatchers (dsl)" do
102
+ expect(user_story.class.defined_actions).to include(:custom_action)
103
+ end
104
+ end
84
105
  end
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe "Updating Model Data" do
4
+ let(:briefcase) { Brief.example }
5
+
6
+ it "lets me set new attributes on the model" do
7
+ end
8
+
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brief
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Soeder
@@ -215,11 +215,13 @@ executables:
215
215
  extensions: []
216
216
  extra_rdoc_files: []
217
217
  files:
218
+ - ".gitignore"
218
219
  - Gemfile
219
220
  - Gemfile.lock
220
221
  - LICENSE.txt
221
222
  - README.md
222
223
  - Rakefile
224
+ - TUTORIAL.md
223
225
  - bin/brief
224
226
  - brief.gemspec
225
227
  - examples/blog/brief.rb
@@ -229,7 +231,6 @@ files:
229
231
  - lib/brief/briefcase.rb
230
232
  - lib/brief/cli/change.rb
231
233
  - lib/brief/cli/init.rb
232
- - lib/brief/cli/publish.rb
233
234
  - lib/brief/cli/write.rb
234
235
  - lib/brief/configuration.rb
235
236
  - lib/brief/core_ext.rb
@@ -241,7 +242,9 @@ files:
241
242
  - lib/brief/dsl.rb
242
243
  - lib/brief/model.rb
243
244
  - lib/brief/model/definition.rb
245
+ - lib/brief/model/persistence.rb
244
246
  - lib/brief/repository.rb
247
+ - lib/brief/util.rb
245
248
  - lib/brief/version.rb
246
249
  - spec/fixtures/example/brief.rb
247
250
  - spec/fixtures/example/docs/concept.html.md
@@ -256,6 +259,7 @@ files:
256
259
  - spec/lib/brief/document_spec.rb
257
260
  - spec/lib/brief/dsl_spec.rb
258
261
  - spec/lib/brief/model_spec.rb
262
+ - spec/lib/brief/persistence_spec.rb
259
263
  - spec/lib/brief/repository_spec.rb
260
264
  - spec/spec_helper.rb
261
265
  - spec/support/test_helpers.rb
@@ -298,6 +302,7 @@ test_files:
298
302
  - spec/lib/brief/document_spec.rb
299
303
  - spec/lib/brief/dsl_spec.rb
300
304
  - spec/lib/brief/model_spec.rb
305
+ - spec/lib/brief/persistence_spec.rb
301
306
  - spec/lib/brief/repository_spec.rb
302
307
  - spec/spec_helper.rb
303
308
  - spec/support/test_helpers.rb
File without changes