soupcms-cli 0.5.2.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +5 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +43 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +11 -0
  11. data/Rakefile +9 -0
  12. data/bin/soupcms +7 -0
  13. data/lib/soupcms/cli/colorize.rb +167 -0
  14. data/lib/soupcms/cli/front_matter_parser.rb +22 -0
  15. data/lib/soupcms/cli/model/base.rb +145 -0
  16. data/lib/soupcms/cli/model/chapter.rb +55 -0
  17. data/lib/soupcms/cli/model/markdown.rb +45 -0
  18. data/lib/soupcms/cli/model/page.rb +70 -0
  19. data/lib/soupcms/cli/model/post.rb +14 -0
  20. data/lib/soupcms/cli/model/yaml.rb +18 -0
  21. data/lib/soupcms/cli/resolve_file_reference.rb +35 -0
  22. data/lib/soupcms/cli/version.rb +5 -0
  23. data/lib/soupcms/cli.rb +14 -0
  24. data/lib/soupcms/soupcms_cli.rb +128 -0
  25. data/lib/templates/Gemfile +18 -0
  26. data/lib/templates/Procfile +1 -0
  27. data/lib/templates/blog/my-first-post.md +23 -0
  28. data/lib/templates/pages/about.md +6 -0
  29. data/lib/templates/pages/blog-post.yml +79 -0
  30. data/lib/templates/pages/default.yml +82 -0
  31. data/lib/templates/pages/home.yml +26 -0
  32. data/lib/templates/pages/posts.yml +23 -0
  33. data/lib/templates/public/blog/posts/images/my-first-post/1-post-image.png +0 -0
  34. data/lib/templates/public/blog/posts/images/my-first-post.png +0 -0
  35. data/lib/templates/public/favicon.png +0 -0
  36. data/lib/templates/schemaless/footer.yml +9 -0
  37. data/lib/templates/schemaless/navigation.yml +25 -0
  38. data/lib/templates/schemaless/social-toolbar.yml +7 -0
  39. data/lib/templates/single-app-config.ru +54 -0
  40. data/soupcms-cli.gemspec +25 -0
  41. data/spec/sopucms-site/dummy_spec.rb +8 -0
  42. data/spec/sopucms-site/rake/front_matter_parser_spec.rb +38 -0
  43. data/spec/spec_helper.rb +17 -0
  44. metadata +133 -0
@@ -0,0 +1,18 @@
1
+ module SoupCMS
2
+ module CLI
3
+ module Model
4
+
5
+ class Yaml < SoupCMS::CLI::Model::Base
6
+
7
+ def parse_file
8
+ document_hash = YAML.load(file.read)
9
+ SoupCMS::CLI::ResolveFileReference.new(File.dirname(file)).parse(document_hash)
10
+ end
11
+
12
+
13
+ end
14
+
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ module SoupCMS
2
+ module CLI
3
+
4
+
5
+ class ResolveFileReference
6
+
7
+ def initialize(path)
8
+ @path = path
9
+ end
10
+
11
+ def parse(document)
12
+ if document.kind_of?(Array)
13
+ document.collect { |doc| parse_for_file(doc) }
14
+ elsif document.kind_of?(Hash)
15
+ parse_for_file(document)
16
+ end
17
+ end
18
+
19
+ def parse_for_file(document)
20
+ document.each do |key, value|
21
+ if value.kind_of?(Array)
22
+ document[key] = value.collect { |item| item.kind_of?(Hash) ? parse_for_file(item) : item }
23
+ elsif value.kind_of?(Hash)
24
+ document[key] = parse_for_file(value)
25
+ elsif value.kind_of?(String) && value.match(/^\$file:/)
26
+ document[key] = File.read(File.join(@path, 'ref_files', value.match(/\$file:([\w\.\-]*)/).captures[0]))
27
+ end
28
+ end
29
+ @document = document
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module Soupcms
2
+ module Cli
3
+ VERSION = '0.5.2.rc1'
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ require 'soupcms/cli/version'
2
+
3
+ require 'soupcms/soupcms_cli'
4
+
5
+ require 'soupcms/cli/colorize'
6
+ require 'soupcms/cli/front_matter_parser'
7
+ require 'soupcms/cli/resolve_file_reference'
8
+
9
+ require 'soupcms/cli/model/base'
10
+ require 'soupcms/cli/model/yaml'
11
+ require 'soupcms/cli/model/markdown'
12
+ require 'soupcms/cli/model/page'
13
+ require 'soupcms/cli/model/post'
14
+ require 'soupcms/cli/model/chapter'
@@ -0,0 +1,128 @@
1
+ require 'rubygems'
2
+ require 'thor'
3
+ require 'yaml'
4
+ require 'json'
5
+ require 'mongo'
6
+
7
+ class SoupCMSCLI < Thor
8
+ include Thor::Actions
9
+
10
+ def initialize(*args)
11
+ super
12
+ @configs = {}
13
+ end
14
+
15
+ attr_reader :configs
16
+
17
+ desc 'new <name>', 'create new application'
18
+ method_option :generate, type: :boolean, aliases: '-g', default: false, desc: 'Generate NEW soupcms application. Default is false.'
19
+ def new(name)
20
+ configs[:name] = name
21
+ configs[:display_name] = ask('Short display application name? (10 to 15 char) :', :green)
22
+ configs[:description] = ask('Long application description? (30 to 40 char) :', :green)
23
+
24
+ configs[:blog] = yes?('Blog support? (y/n):', :blue)
25
+ if configs[:blog]
26
+ say('Choose blog layout? (y/n):',:green)
27
+ blog_layouts = [[1, 'full-width'], [2, 'right-sidebar'], [3, 'left-sidebar']]
28
+ print_table blog_layouts
29
+ layout = ask('choose from', :green, :limited_to => %w(1 2 3))
30
+ configs[:blog_layout] = blog_layouts[layout.to_i - 1][1]
31
+ end
32
+
33
+ if configs[:blog]
34
+ template 'lib/templates/pages/blog-post.yml',"data/#{name}/pages/blog-post.yml"
35
+ template 'lib/templates/pages/posts.yml',"data/#{name}/pages/posts.yml"
36
+ end
37
+ copy_file 'lib/templates/public/favicon.png', 'public/favicon.png'
38
+
39
+ template 'lib/templates/schemaless/footer.yml',"data/#{name}/schemaless/footer.yml"
40
+ template 'lib/templates/schemaless/navigation.yml',"data/#{name}/schemaless/navigation.yml"
41
+ template 'lib/templates/schemaless/social-toolbar.yml',"data/#{name}/schemaless/social-toolbar.yml"
42
+
43
+ template 'lib/templates/pages/default.yml',"data/#{name}/pages/default.yml"
44
+ template 'lib/templates/pages/home.yml',"data/#{name}/pages/home.yml"
45
+ template 'lib/templates/pages/about.md',"data/#{name}/pages/about.md"
46
+
47
+ template 'lib/templates/Gemfile', 'Gemfile'
48
+ template 'lib/templates/Procfile', 'Procfile'
49
+
50
+ if yes?('Would you like to host your website public on platform like Heroku? (y/n):', :blue)
51
+ configs[:site_name] = ask('Provide the hostname for your website (e.g. http://myblog.herokuapp.com OR http://www.myblog.com) :', :green)
52
+ end
53
+ template 'lib/templates/single-app-config.ru', 'config.ru'
54
+
55
+ if configs[:blog]
56
+ while yes?('Would you like to add blog post? (y/n):', :blue)
57
+ post(configs[:name])
58
+ end
59
+ end
60
+
61
+
62
+ create_file "data/#{name}/_config.yml", YAML.dump(JSON.parse(configs.to_json))
63
+ end
64
+
65
+ desc 'post <name>', 'create new post for given application name'
66
+ def post(name)
67
+ configs[:name] = name
68
+ configs[:title] = ask('Title for the new post? (20 to 30 char) :', :green)
69
+ sanitize_title = configs[:title].gsub(' ','-').gsub('\'','').gsub(',','').downcase #TODO: proper sanitization
70
+ configs[:sanitize_title] = sanitize_title
71
+ tags = ask('Tags as comma separated list:', :green)
72
+ configs[:tags] = tags.split(',')
73
+
74
+ template 'lib/templates/blog/my-first-post.md',"data/#{name}/posts/#{sanitize_title}.md"
75
+ copy_file 'lib/templates/public/blog/posts/images/my-first-post.png',"public/#{name}/posts/images/#{sanitize_title}.png"
76
+ copy_file 'lib/templates/public/blog/posts/images/my-first-post/1-post-image.png',"public/#{name}/posts/images/#{sanitize_title}/1-post-image.png"
77
+ end
78
+
79
+ desc 'delete <name>', 'delete application'
80
+ def delete(name)
81
+ if yes?("Are you sure you would like to delete #{name}? (y/n):")
82
+ remove_dir "data/#{name}"
83
+ remove_dir "public/#{name}"
84
+ remove_file 'Procfile'
85
+ remove_file 'config.ru'
86
+ end
87
+ end
88
+
89
+ desc 'clean <name>', 'clean all content from database'
90
+ def clean(name)
91
+ mongo_uri = ENV["MONGODB_URI_#{name}"] || "mongodb://localhost:27017/#{name}"
92
+ conn = Mongo::MongoClient.from_uri(mongo_uri)
93
+ db = conn.db
94
+ say "Cleaning up the database '#{name}'", :green
95
+ db.collection_names.each { |coll_name|
96
+ next if coll_name.match(/^system/)
97
+ say "Dropping collection '#{coll_name}'", :red
98
+ db.drop_collection(coll_name)
99
+ }
100
+ conn.close
101
+ end
102
+
103
+ desc 'seed <name>', 'seed content to database'
104
+ method_option :clean, type: :boolean, aliases: '-c', default: false, desc: 'Clean all documents before seed.'
105
+ method_option :verbose, type: :boolean, aliases: '-v', default: false, desc: 'Show verbose information during seed (debug level logs).'
106
+ def seed(name)
107
+ clean(name) if options.clean?
108
+ ENV['verbose'] = options.verbose?.to_s
109
+ Dir.glob("data/#{name}/**/*.{json,md,yml}").each do |file|
110
+ unless file.include?('ref_files') || file.include?('_config.yml')
111
+ begin
112
+ SoupCMS::CLI::Model::Base.create_model(File.new(file))
113
+ rescue => e
114
+ say "Error importing file... #{file}", :red
115
+ say "#{e.backtrace.first}: #{e.message} (#{e.class})", :red
116
+ say "#{e.backtrace.drop(1).map{|s| s }.join("\n")}", :red
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ def self.source_root
123
+ File.join(File.dirname(__FILE__), '../..')
124
+ end
125
+
126
+
127
+ end
128
+
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.1.1'
3
+
4
+ gem 'soupcms-cli'
5
+ gem 'soupcms-common', github: 'soupcms/soupcms-common'
6
+ gem 'soupcms-core', github: 'soupcms/soupcms-core'
7
+ gem 'soupcms-api', github: 'soupcms/soupcms-api'
8
+
9
+ gem 'kramdown'
10
+ gem 'coderay'
11
+ gem 'nokogiri'
12
+ gem 'sprockets', github: 'sstephenson/sprockets', ref: '2a658ff971b44ee995bf3205a991005f8dbdca1d'
13
+
14
+ gem 'foreman'
15
+ gem 'passenger'
16
+ gem 'puma'
17
+ gem 'mongo'
18
+ gem 'bson_ext'
@@ -0,0 +1 @@
1
+ web: bundle exec passenger start -p $PORT
@@ -0,0 +1,23 @@
1
+ ---
2
+ # blog post attributes in front matter format
3
+ tags: [<%= configs[:tags].join(",") %>]
4
+ title: <%= configs[:title] %>
5
+ publish_datetime: 2014-01-01T00:00:07.0Z
6
+ description: Write post description here...
7
+ ---
8
+
9
+ # Markdown documentation
10
+
11
+ This is [markdown template](http://kramdown.gettalong.org/index.html) and quick reference of the markdown language is available [here](http://kramdown.gettalong.org/quickref.html).
12
+
13
+ ## How to add images in post?
14
+
15
+ To add images on the post copy images in directory 'public/<%= configs[:name] %>/posts/images/<%= configs[:sanitize_title] %>' and use following sample on how to provide image path.
16
+
17
+ ![Images within post](/assets/<%= configs[:name] %>/posts/images/<%= configs[:sanitize_title] %>/1-post-image.png "images with post")
18
+
19
+
20
+
21
+
22
+
23
+
@@ -0,0 +1,6 @@
1
+ # About
2
+
3
+ TODO: write about page here... **OR** delete this file if not required.
4
+
5
+
6
+
@@ -0,0 +1,79 @@
1
+ ---
2
+ meta:
3
+ model: posts
4
+ areas:
5
+ -
6
+ name: sidebar
7
+ modules:
8
+ -
9
+ recipes:
10
+ -
11
+ type: http
12
+ url: "#{context.application.soupcms_api_url}/schemaless/name/social-toolbar"
13
+ return: social-toolbar
14
+ template:
15
+ type: slim
16
+ name: bootstrap/social-toolbar
17
+ -
18
+ recipes:
19
+ -
20
+ type: soupcms-api
21
+ model: "/#{context.model_name}/slug/#{context.slug}"
22
+ return: toc-document
23
+ -
24
+ type: post-processor
25
+ processor: SoupCMS::Core::Processor::NokogiriTOC
26
+ config:
27
+ toc_for: "#{data['toc-document']['content']['value']}"
28
+ levels:
29
+ - h2
30
+ - h3
31
+ - h4
32
+ - h5
33
+ - h6
34
+ return: table-of-content
35
+ template:
36
+ type: slim
37
+ name: bootstrap/table-of-content
38
+ config:
39
+ title: Contents
40
+ -
41
+ recipes:
42
+ -
43
+ type: soupcms-api
44
+ url: posts/tag-cloud
45
+ return: tag-cloud
46
+ template:
47
+ type: slim
48
+ name: bootstrap/tag-cloud
49
+ -
50
+ recipes:
51
+ -
52
+ type: soupcms-api
53
+ model: posts
54
+ fields:
55
+ - title
56
+ - slug
57
+ limit: 5
58
+ return: articles
59
+ template:
60
+ type: slim
61
+ name: bootstrap/list-view
62
+ config:
63
+ title: Recent Posts
64
+ -
65
+ name: body
66
+ modules:
67
+ -
68
+ recipes:
69
+ -
70
+ type: soupcms-api
71
+ model: "/#{context.model_name}/slug/#{context.slug}"
72
+ return: article
73
+ template:
74
+ type: slim
75
+ name: bootstrap/article
76
+ -
77
+ template:
78
+ type: slim
79
+ name: meta/disqus
@@ -0,0 +1,82 @@
1
+ ---
2
+ meta:
3
+ name: enricher
4
+ layout:
5
+ type: slim
6
+ name: bootstrap/<%= configs[:blog_layout] %>
7
+ areas:
8
+ -
9
+ name: meta
10
+ modules:
11
+ -
12
+ template:
13
+ type: slim
14
+ name: meta/page-title
15
+ -
16
+ name: header
17
+ modules:
18
+ -
19
+ recipes:
20
+ -
21
+ type: soupcms-api
22
+ model: schemaless
23
+ match:
24
+ name: navigation
25
+ return: navigation
26
+ template:
27
+ type: slim
28
+ name: bootstrap/navigation
29
+ -
30
+ recipes:
31
+ -
32
+ type: inline
33
+ data:
34
+ title: <%= configs[:display_name] %>
35
+ sub_headline: <%= configs[:description] %>
36
+ image:
37
+ source: cloudinary
38
+ base_url: http://res.cloudinary.com/sunitparekh/image/upload
39
+ desktop: purple-textures-low_xiamgc.jpg
40
+ return: page-header
41
+ template:
42
+ type: slim
43
+ name: bootstrap/page-header
44
+ -
45
+ name: sidebar
46
+ modules:
47
+ -
48
+ recipes:
49
+ -
50
+ type: http
51
+ url: "#{context.application.soupcms_api_url}/schemaless/name/social-toolbar"
52
+ return: social-toolbar
53
+ template:
54
+ type: slim
55
+ name: bootstrap/social-toolbar
56
+ -
57
+ recipes:
58
+ -
59
+ type: soupcms-api
60
+ url: posts/tag-cloud
61
+ return: tag-cloud
62
+ template:
63
+ type: slim
64
+ name: bootstrap/tag-cloud
65
+ -
66
+ name: footer
67
+ modules:
68
+ -
69
+ recipes:
70
+ -
71
+ type: soupcms-api
72
+ model: schemaless
73
+ match:
74
+ name: footer
75
+ return: footer
76
+ template:
77
+ type: slim
78
+ name: bootstrap/footer
79
+ -
80
+ template:
81
+ type: slim
82
+ name: meta/analytics/google
@@ -0,0 +1,26 @@
1
+ ---
2
+ slug: home
3
+ title: <%= configs[:description] %> - <%= configs[:display_name] %>
4
+ seo:
5
+ description: <%= configs[:description] %>
6
+ areas:
7
+ -
8
+ name: body
9
+ modules:
10
+ -
11
+ recipes:
12
+ -
13
+ type: soupcms-api
14
+ model: posts
15
+ fields:
16
+ - title
17
+ - slug
18
+ - description
19
+ - hero_image
20
+ - author_ref
21
+ - tags
22
+ - publish_datetime
23
+ return: articles
24
+ template:
25
+ type: slim
26
+ name: bootstrap/article-list-view
@@ -0,0 +1,23 @@
1
+ ---
2
+ slug: posts
3
+ title: Latest blog posts on <%= configs[:display_name] %>
4
+ seo:
5
+ description: Latest blog posts on <%= configs[:display_name] %>
6
+ layout:
7
+ type: slim
8
+ name: bootstrap/full-width
9
+ areas:
10
+ -
11
+ name: body
12
+ modules:
13
+ -
14
+ recipes:
15
+ -
16
+ type: soupcms-api
17
+ model: posts
18
+ match:
19
+ tags: "#{page.context.params['tags']}"
20
+ return: articles
21
+ template:
22
+ type: slim
23
+ name: bootstrap/article-tile-view
Binary file
@@ -0,0 +1,9 @@
1
+ ---
2
+ name: footer
3
+
4
+ copyright: "&copy; 2014"
5
+ links:
6
+ -
7
+ label: Powered by soupCMS
8
+ link:
9
+ url: http://www.soupcms.com
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: navigation
3
+
4
+ logo:
5
+ font_icon: fa fa-magic
6
+ text: "<%= configs[:display_name] %>"
7
+ link:
8
+ url: home
9
+
10
+ menu:
11
+
12
+ <% if configs[:blog] %>
13
+ left:
14
+ -
15
+ label: Latest posts
16
+ link:
17
+ url: posts
18
+ <% end %>
19
+
20
+ right:
21
+ -
22
+ label: About
23
+ link:
24
+ url: about
25
+ font_icon: fa fa-user
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: social-toolbar
3
+
4
+ twitter: http://www.twitter.com/<%= configs[:name] %> # update or remove if not needed
5
+ facebook: http://www.facebook.com/<%= configs[:name] %> # update or remove if not needed
6
+ github: https://www.github.com/<%= configs[:name] %> # update or remove if not needed
7
+ plus: https://plus.google.com/+<%= configs[:name] %> # update or remove if not needed
@@ -0,0 +1,54 @@
1
+ require 'tilt'
2
+ require 'sprockets'
3
+
4
+ require 'soupcms/core'
5
+ require 'soupcms/api'
6
+
7
+ SoupCMS::Common::Strategy::Application::SingleApp.configure do |app|
8
+ app.app_name = "<%= configs[:name] %>"
9
+ app.display_name = "<%= configs[:description] %>"
10
+ <%- if configs[:site_name] %>
11
+ if ENV['RACK_ENV'] == 'production'
12
+ app.soupcms_api_url = '<%= configs[:site_name] %>/api'
13
+ app.app_base_url = '<%= configs[:site_name] %>/'
14
+ else
15
+ app.soupcms_api_url = 'http://localhost:9292/api'
16
+ app.app_base_url = 'http://localhost:9292/'
17
+ end
18
+ <%- end %>
19
+ end
20
+
21
+ map '/api' do
22
+ SoupCMSApi.configure do |config|
23
+ config.application_strategy = SoupCMS::Common::Strategy::Application::SingleApp
24
+ config.data_resolver.register(/content$/,SoupCMS::Api::Resolver::KramdownMarkdownResolver)
25
+ end
26
+ run SoupCMSApiRackApp.new
27
+ end
28
+
29
+ PUBLIC_DIR = File.join(File.dirname(__FILE__), 'public')
30
+ map '/assets' do
31
+ sprockets = SoupCMSCore.config.sprockets
32
+ sprockets.append_path SoupCMS::Core::Template::Manager::DEFAULT_TEMPLATE_DIR
33
+ sprockets.append_path PUBLIC_DIR
34
+ Sprockets::Helpers.configure do |config|
35
+ config.environment = sprockets
36
+ config.prefix = '/assets'
37
+ config.public_path = nil
38
+ config.digest = true
39
+ end
40
+ run sprockets
41
+ end
42
+
43
+ map '/' do
44
+ SoupCMSCore.configure do |config|
45
+ config.application_strategy = SoupCMS::Common::Strategy::Application::SingleApp
46
+ end
47
+ soup_cms_rack_app = SoupCMSRackApp.new
48
+ <%- if configs[:site_name] %>
49
+ soup_cms_rack_app.set_redirect('<%= configs[:site_name] %>','<%= configs[:site_name] %>/home')
50
+ <%- end %>
51
+ run soup_cms_rack_app
52
+ end
53
+
54
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'soupcms/cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'soupcms-cli'
8
+ spec.version = Soupcms::Cli::VERSION
9
+ spec.authors = ['Sunit Parekh']
10
+ spec.email = ['parekh.sunit@gmail.com']
11
+ spec.summary = %q{soupCMS command line interpreter}
12
+ spec.description = %q{soupCMS command line interpreter for generating new application and applying updates}
13
+ spec.homepage = 'http://blog.soupcms.com/posts/setup-blog-site'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency('thor', '~> 0.19')
22
+ spec.add_runtime_dependency('mongo', '~> 1.10')
23
+ spec.add_runtime_dependency('bson_ext', '~> 1.10')
24
+
25
+ end
@@ -0,0 +1,8 @@
1
+ require 'rspec'
2
+
3
+ describe 'Dummy Spec' do
4
+
5
+ it 'should dummy spec that always passes' do
6
+ expect(true).to eq(true)
7
+ end
8
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe SoupCMS::CLI::FrontMatterParser do
4
+
5
+ it 'parse string with front matter YAML' do
6
+ text = <<-textwithfrontmatter
7
+ ---
8
+ layout: post
9
+ title: Blogging Like a Hacker
10
+ ---
11
+ ## Ohh this is awesome and works
12
+
13
+ textwithfrontmatter
14
+
15
+ attributes, content = SoupCMS::CLI::FrontMatterParser.new.parse(text)
16
+ expect(attributes['layout']).to eq('post')
17
+ expect(attributes['title']).to eq('Blogging Like a Hacker')
18
+ expect(content).to eq('## Ohh this is awesome and works')
19
+
20
+ end
21
+
22
+ it 'parse string with front matter YAML' do
23
+ text = <<-textwithfrontmatter
24
+ ## Ohh this is awesome and works
25
+ ---
26
+ layout: post
27
+ title: Blogging Like a Hacker
28
+ ---
29
+ ## Ohh this is awesome and works
30
+
31
+ textwithfrontmatter
32
+
33
+ attributes, content = SoupCMS::CLI::FrontMatterParser.new.parse(text)
34
+ expect(attributes).to eq({})
35
+ expect(content).to eq(text)
36
+
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ require 'rspec'
2
+ require 'soupcms/cli'
3
+
4
+ RSpec.configure do |config|
5
+ config.order = 'random'
6
+ config.expect_with :rspec
7
+
8
+ config.before(:suite) do
9
+ end
10
+
11
+ config.before(:each) do
12
+ end
13
+
14
+ config.after(:suite) do
15
+ end
16
+
17
+ end