eucalypt 0.1.0
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.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +26 -0
- data/Rakefile +2 -0
- data/bin/eucalypt +3 -0
- data/eucalypt.gemspec +39 -0
- data/lib/eucalypt/app.rb +6 -0
- data/lib/eucalypt/controller.rb +10 -0
- data/lib/eucalypt/errors.rb +109 -0
- data/lib/eucalypt/eucalypt-blog/helpers.rb +106 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/__base__.rb +22 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/__require__.rb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/cli/blog.rb +65 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/article.rb +28 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/controller.rb +14 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/helper.rb +12 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/list.rb +74 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/views.rb +20 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller.tt +33 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller_spec.tt +43 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper.tt +5 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_layout.erb +10 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_md.tt +9 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles_layout.erb +10 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/search.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article/cli/article.rb +120 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-datetime.rb +113 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-urltitle.rb +75 -0
- data/lib/eucalypt/eucalypt-core/cli/__base__.rb +11 -0
- data/lib/eucalypt/eucalypt-core/cli/console.rb +15 -0
- data/lib/eucalypt/eucalypt-core/cli/core.rb +6 -0
- data/lib/eucalypt/eucalypt-core/cli/help.rb +11 -0
- data/lib/eucalypt/eucalypt-core/cli/init.rb +71 -0
- data/lib/eucalypt/eucalypt-core/cli/launch.rb +33 -0
- data/lib/eucalypt/eucalypt-core/cli/test.rb +16 -0
- data/lib/eucalypt/eucalypt-core/cli/version.rb +11 -0
- data/lib/eucalypt/eucalypt-core/templates/Gemfile.tt +35 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/.gitignore +48 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/.travis.yml +8 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/Procfile +1 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/Rakefile +7 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/fonts/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/images/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/scripts/application.js +17 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/__partials__.scss +16 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/application.scss +17 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/partials/_mixins.scss +54 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/controllers/application_controller.rb +7 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/helpers/application_helper.rb +3 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/models/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/readme.yml +34 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/index.erb +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/layouts/main.erb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/partials/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app.rb +42 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/active_record.rb +6 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/asset_pipeline.rb +15 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/database.yml +16 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/initializers/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/logging.rb +27 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/manifest.rb +15 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config.ru +10 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/log/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/controllers/application_controller_spec.rb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/helpers/application_helper_spec.rb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/models/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/spec_helper.rb +18 -0
- data/lib/eucalypt/eucalypt-destroy/helpers.rb +77 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-controller.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-helper.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-model.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-scaffold.rb +63 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy.rb +21 -0
- data/lib/eucalypt/eucalypt-generate/.gitkeep +0 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate-scaffold.rb +62 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate.rb +24 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/cli/generate-controller.rb +29 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/generators/controller.rb +45 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/controller.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/policy_rest_controller.tt +71 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/rest_controller.tt +28 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/cli/generate-helper.rb +23 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/generators/helper.rb +24 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/cli/generate-model.rb +26 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/generators/model.rb +25 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model_spec.tt +8 -0
- data/lib/eucalypt/eucalypt-migration/helpers.rb +93 -0
- data/lib/eucalypt/eucalypt-migration/migration_base.tt +4 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration/cli/migration.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-column.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-index.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add.rb +18 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/column.rb +46 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/index.rb +52 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/cli/blank.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/generators/blank.rb +28 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change-column.rb +23 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change.rb +17 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/generators/column.rb +46 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create-table.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create.rb +17 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/generators/table.rb +53 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-column.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-index.rb +23 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-table.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop.rb +19 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/column.rb +38 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/index.rb +48 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/table.rb +37 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-column.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-index.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-table.rb +24 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename.rb +19 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/column.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/index.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/table.rb +38 -0
- data/lib/eucalypt/eucalypt-security/helpers.rb +22 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security/cli/security.rb +31 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/cli/security-policy.rb +91 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/generators/policy.rb +31 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/create_policy_roles_migration.tt +11 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/policy.tt +16 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/cli/security-policy-permission.rb +62 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/generators/policy-permission.rb +28 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/templates/add_permission_to_policy_migration.tt +5 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-role/cli/security-policy-role.rb +66 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/cli/security-pundit.rb +79 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/generators/role.rb +24 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/create_roles_migration.tt +7 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/pundit.tt +4 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/cli/security-warden.rb +61 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/auth_controller.rb +34 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/user.rb +37 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_controller.tt +25 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_login.tt +1 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/create_users_table_migration.tt +9 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/user.tt +16 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/warden.tt +35 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/user_confirm.rb +38 -0
- data/lib/eucalypt/helpers/colorize.rb +27 -0
- data/lib/eucalypt/helpers/gemfile.rb +48 -0
- data/lib/eucalypt/helpers/inflect.rb +79 -0
- data/lib/eucalypt/helpers/messages.rb +31 -0
- data/lib/eucalypt/helpers/migration.rb +85 -0
- data/lib/eucalypt/helpers/numeric.rb +10 -0
- data/lib/eucalypt/helpers.rb +6 -0
- data/lib/eucalypt/list.rb +39 -0
- data/lib/eucalypt/static.rb +48 -0
- data/lib/eucalypt/version.rb +3 -0
- data/lib/eucalypt.rb +19 -0
- metadata +373 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: aa6a5ff7a9dcd9363c00239a5f3c4f061cf4462c619cc8b59f1cdf406cd876b3
|
|
4
|
+
data.tar.gz: 5b40cd192caec208c295bbe054b4bded5bbb87d4c0a8fe50feeb94a16159edfc
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7d0814b65d0d6c769e0d4f104066c5aeee5b3be0b4f0c0da18955b38938e951ddf71cf11918e6adca2c33a169cf8ede27a92f9b55b3bd784e5ad06340e5a8bce
|
|
7
|
+
data.tar.gz: 2445d94f7f54fb716c06220d429b94a895b352172ddb85ce91abc163b23c8dad51bf1a8de31410daf3863d0a468764c3846afc6b12cf1dce92e44829dc36a9ff
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Edwin Onuonga
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[](https://github.com/eonu/eucalypt/blob/0c509a4e22fd97ec52b6f638af21de783f3aafc8/eucalypt.gemspec#L19)
|
|
2
|
+
[](https://rubygems.org/gems/eucalypt)
|
|
3
|
+
[]
|
|
4
|
+
[]
|
|
5
|
+
|
|
6
|
+
# Eucalypt
|
|
7
|
+
|
|
8
|
+
Micro-framework and CLI for the generation and maintenance of structured Sinatra web applications.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
To install the CLI, run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
$ gem install eucalypt
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
Initialize a new application with:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
$ eucalypt init my-new-app
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
And you're ready to go!
|
data/Rakefile
ADDED
data/bin/eucalypt
ADDED
data/eucalypt.gemspec
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require "eucalypt/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "eucalypt"
|
|
7
|
+
spec.version = Eucalypt::VERSION
|
|
8
|
+
spec.authors = ["Edwin Onuonga"]
|
|
9
|
+
spec.email = ["edwinonuonga@gmail.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = %q{Micro-framework and CLI for the generation and maintenance of structured Sinatra web applications.}
|
|
12
|
+
spec.homepage = "https://eucalypt.gitbook.io/eucalypt/"
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
spec.files = Dir.glob('lib/**/*', File::FNM_DOTMATCH) + %w[Gemfile LICENSE README.md Rakefile eucalypt.gemspec bin/eucalypt]
|
|
15
|
+
spec.bindir = "bin"
|
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f)}
|
|
17
|
+
spec.require_paths = ["lib"]
|
|
18
|
+
|
|
19
|
+
spec.required_ruby_version = "~> 2.5"
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
|
22
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
|
24
|
+
spec.add_development_dependency "regexp-examples", "~> 1.4"
|
|
25
|
+
spec.add_development_dependency "colorize", "~> 0.8"
|
|
26
|
+
|
|
27
|
+
spec.add_runtime_dependency "string-builder", "~> 2.3"
|
|
28
|
+
spec.add_runtime_dependency "activesupport", "~> 5.2"
|
|
29
|
+
spec.add_runtime_dependency "activerecord", "~> 5.2"
|
|
30
|
+
spec.add_runtime_dependency "front_matter_parser", "0.2.0"
|
|
31
|
+
spec.add_runtime_dependency "thor", "~> 0.20"
|
|
32
|
+
spec.add_runtime_dependency "sinatra", "~> 2.0"
|
|
33
|
+
spec.add_runtime_dependency "rerun", "~> 0.13"
|
|
34
|
+
|
|
35
|
+
spec.metadata = {
|
|
36
|
+
# "documentation_uri" => "https://eucalypt.gitbook.io/eucalypt/",
|
|
37
|
+
"source_code_uri" => "https://github.com/eucalypt/eucalypt/"
|
|
38
|
+
}
|
|
39
|
+
end
|
data/lib/eucalypt/app.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'sinatra'
|
|
2
|
+
class ApplicationController < Sinatra::Base; end
|
|
3
|
+
module Eucalypt
|
|
4
|
+
def self.Controller(route:)
|
|
5
|
+
name = File.basename(caller[0][/[^:]+/],'.*').camelize
|
|
6
|
+
Object.const_set name, Class.new(::ApplicationController)
|
|
7
|
+
name.constantize.instance_eval %{def router() "#{route}" end}
|
|
8
|
+
::ApplicationController
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'eucalypt/app'
|
|
2
|
+
require 'eucalypt/helpers'
|
|
3
|
+
require 'string/builder'
|
|
4
|
+
|
|
5
|
+
module Eucalypt
|
|
6
|
+
module Error
|
|
7
|
+
include Eucalypt::Helpers
|
|
8
|
+
include Eucalypt::Helpers::Messages
|
|
9
|
+
using String::Builder
|
|
10
|
+
using Colorize
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
include Eucalypt::Helpers::Messages
|
|
14
|
+
def wrong_directory
|
|
15
|
+
puts
|
|
16
|
+
Out.error "Couldn't find #{Eucalypt::APP_FILE.colorize(:bold)} in current directory."
|
|
17
|
+
puts
|
|
18
|
+
Out.info 'Try:'
|
|
19
|
+
puts " - Changing the current working directory to your application's root directory."
|
|
20
|
+
puts " - Creating a new application with `#{'eucalypt init'.colorize(:bold)}`."
|
|
21
|
+
puts " - Creating a #{Eucalypt::APP_FILE.colorize(:bold)} if you deleted it."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def found_app_file
|
|
25
|
+
Out.warning "Found #{Eucalypt::APP_FILE.colorize(:bold)} in the current directory."
|
|
26
|
+
puts
|
|
27
|
+
Out.info
|
|
28
|
+
puts " - The current directory might already be a Eucalypt application."
|
|
29
|
+
puts " - Proceeding with the initialization will create a new nested application."
|
|
30
|
+
puts " - This shouldn't be a problem, but is it really what you intended?"
|
|
31
|
+
puts
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def no_articles
|
|
35
|
+
Out.error "Couldn't find any blog articles"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def delete_article_warning
|
|
39
|
+
Out.warning 'Deleting an article will delete both the markdown file and all assets!'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def no_mvc(mvc_file)
|
|
43
|
+
Out.error "Couldn't find any #{mvc_file}s"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def no_scaffolds
|
|
47
|
+
Out.error "Couldn't find any scaffolds."
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def no_gems(gems, command)
|
|
51
|
+
Out.error "Couldn't find gems #{gems} in Gemfile."
|
|
52
|
+
puts
|
|
53
|
+
Out.info
|
|
54
|
+
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def no_user_model
|
|
58
|
+
Out.error "Couldn't find a user model."
|
|
59
|
+
puts
|
|
60
|
+
Out.info
|
|
61
|
+
command = 'eucalypt security warden setup'
|
|
62
|
+
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def no_role_model
|
|
66
|
+
Out.error "Couldn't find a role model."
|
|
67
|
+
puts
|
|
68
|
+
Out.info
|
|
69
|
+
command = 'eucalypt security pundit setup'
|
|
70
|
+
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def no_policy(policy_name)
|
|
74
|
+
Out.error "Couldn't find a #{policy_name} role model or policy file."
|
|
75
|
+
puts
|
|
76
|
+
Out.info
|
|
77
|
+
command = "eucalypt security policy g #{policy_name}"
|
|
78
|
+
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def invalid_columns(invalid_declarations, invalid_types)
|
|
82
|
+
puts if invalid_declarations.any? || invalid_types.any?
|
|
83
|
+
if invalid_declarations.any?
|
|
84
|
+
Out.error "Invalid column declaration(s): #{invalid_declarations.inspect}"
|
|
85
|
+
Out.info "Column declarations should match the regex: #{Eucalypt::Helpers::Migration::Validation::DECLARATION_REGEX.inspect}"
|
|
86
|
+
puts " - Examples: name:string, price:decimal, elo:primary_key"
|
|
87
|
+
end
|
|
88
|
+
if invalid_types.any?
|
|
89
|
+
output = String.build "Invalid column type(s): " do |s|
|
|
90
|
+
invalid_types.each_with_index do |obj, i|
|
|
91
|
+
type, column = obj[:type], obj[:column]
|
|
92
|
+
s << "#{column}:#{type.colorize(:bold)}"
|
|
93
|
+
s << ', ' unless i == invalid_types.size-1
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
puts if invalid_declarations.any? && invalid_types.any?
|
|
97
|
+
Out.error output
|
|
98
|
+
Out.info "To list all permitted column types, run the command `#{"eucalypt migration types".colorize(:bold)}`"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def invalid_type(type)
|
|
103
|
+
puts
|
|
104
|
+
Out.error "Invalid column type: #{type.colorize(:bold)}"
|
|
105
|
+
Out.info "To list all permitted column types, run the command `#{"eucalypt migration types".colorize(:bold)}`"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
module Eucalypt
|
|
3
|
+
class Blog < Thor
|
|
4
|
+
module Helpers
|
|
5
|
+
|
|
6
|
+
module Array::DateSort
|
|
7
|
+
refine Array.singleton_class do
|
|
8
|
+
def date_sorter(order, obj)
|
|
9
|
+
obj.sort! do |x1, x2|
|
|
10
|
+
if order == :ascending
|
|
11
|
+
x1[:datetime] <=> x2[:datetime]
|
|
12
|
+
else
|
|
13
|
+
x2[:datetime] <=> x1[:datetime]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
refine Array do
|
|
19
|
+
def sort_by_date!(order: :descending)
|
|
20
|
+
obj = self.map!{|x|x[:datetime] = DateTime.strptime(x[:time], "%Y-%m-%d %H:%M:%S"); x}
|
|
21
|
+
Array.date_sorter(order, obj)
|
|
22
|
+
end
|
|
23
|
+
def sort_by_date(order: :descending)
|
|
24
|
+
obj = self.map{|x|x[:datetime] = DateTime.strptime(x[:time], "%Y-%m-%d %H:%M:%S"); x}
|
|
25
|
+
Array.date_sorter(order, obj)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class Blog
|
|
31
|
+
class << self
|
|
32
|
+
def articles=(val) @@articles = val end
|
|
33
|
+
def articles() @@articles end
|
|
34
|
+
def all() @@articles.map{|md|FrontMatterParser::Parser.parse_file(md).front_matter.symbolize_keys} end
|
|
35
|
+
def search(query) all.select{|post|post[:tags].any?{|tag|tag.include?(query)}} end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Article
|
|
39
|
+
def initialize(md) @parsed = FrontMatterParser::Parser.parse_file(md) end
|
|
40
|
+
def front_matter() @parsed.front_matter.symbolize_keys end
|
|
41
|
+
def content() @parsed.content end
|
|
42
|
+
def route() "/#{front_matter[:time].split(' ').first.gsub(?-,?/)}/#{front_matter[:urltitle]}" end
|
|
43
|
+
def asset(file) File.join(front_matter[:assetpath].sub('/assets',''), file) end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def construct_date_regex(date)
|
|
51
|
+
y = date[:year]
|
|
52
|
+
m = date[:month]
|
|
53
|
+
d = date[:day]
|
|
54
|
+
return nil unless y || m || d
|
|
55
|
+
return /#{y}\-#{m}\-#{d}/ if y && m && d
|
|
56
|
+
return /#{y}\-#{m}\-[0-9][0-9]/ if y && m && !d
|
|
57
|
+
return /#{y}\-[0-9][0-9]\-#{d}/ if y && !m && d
|
|
58
|
+
return /[0-9]*\-#{m}\-#{d}/ if !y && m && d
|
|
59
|
+
return /#{y}\-[0-9][0-9]\-[0-9][0-9]/ if y && !m && !d
|
|
60
|
+
return /[0-9]*\-#{m}\-[0-9][0-9]/ if !y && m && !d
|
|
61
|
+
return /[0-9]*\-[0-9][0-9]\-#{d}/ if !y && !m && d
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def clean_directory(base)
|
|
65
|
+
Dir.chdir base do
|
|
66
|
+
Dir[?*].each do |year|
|
|
67
|
+
Dir.chdir year do
|
|
68
|
+
Dir[?*].each do |month|
|
|
69
|
+
Dir.chdir month do
|
|
70
|
+
Dir[?*].each do |day|
|
|
71
|
+
FileUtils.rm_rf day if Dir.empty? day
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
FileUtils.rm_rf month if Dir.empty? month
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
FileUtils.rm_rf year if Dir.empty? year
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def build_article_hash(articles, article_base)
|
|
83
|
+
articles_hash = Hash.new
|
|
84
|
+
articles.each_with_index do |article,i|
|
|
85
|
+
index_key = (i+1).to_s.to_sym
|
|
86
|
+
articles_hash[index_key] = {}
|
|
87
|
+
articles_hash[index_key][:path] = article
|
|
88
|
+
articles_hash[index_key][:markdown] = article.split(article_base.gsub(/\/$/,'')<<?/).last
|
|
89
|
+
articles_hash[index_key][:identifier] = articles_hash[index_key][:markdown].rpartition(?.).first
|
|
90
|
+
articles_hash[index_key][:base_name] = File.basename articles_hash[index_key][:markdown]
|
|
91
|
+
articles_hash[index_key][:date] = articles_hash[index_key][:identifier].rpartition(?/).first
|
|
92
|
+
articles_hash[index_key][:front_matter] = FrontMatterParser::Parser.parse_file(
|
|
93
|
+
articles_hash[index_key][:path]
|
|
94
|
+
).front_matter
|
|
95
|
+
title = articles_hash[index_key][:front_matter]['title']
|
|
96
|
+
puts "\e[1m#{index_key}\e[0m: #{articles_hash[index_key][:identifier]}"
|
|
97
|
+
puts "#{' '*(index_key.to_s.length+2)}#{title}" if title
|
|
98
|
+
puts
|
|
99
|
+
end
|
|
100
|
+
articles_hash
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'front_matter_parser'
|
|
3
|
+
require 'string/builder'
|
|
4
|
+
require 'active_support'
|
|
5
|
+
require 'active_support/core_ext'
|
|
6
|
+
|
|
7
|
+
require 'eucalypt/helpers'
|
|
8
|
+
require 'eucalypt/eucalypt-blog/helpers'
|
|
9
|
+
|
|
10
|
+
module Eucalypt
|
|
11
|
+
module Generators
|
|
12
|
+
class Blog < Thor::Group
|
|
13
|
+
include Thor::Actions
|
|
14
|
+
include Eucalypt::Helpers
|
|
15
|
+
include Eucalypt::Blog::Helpers
|
|
16
|
+
|
|
17
|
+
def self.source_root
|
|
18
|
+
File.join __dir__, 'templates'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Dir[File.join __dir__, 'generators', '*.rb'].each{|file| require file}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'eucalypt/errors'
|
|
2
|
+
require 'eucalypt/helpers'
|
|
3
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__require__'
|
|
4
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog-article/cli/article'
|
|
5
|
+
|
|
6
|
+
module Eucalypt
|
|
7
|
+
class Blog < Thor
|
|
8
|
+
include Thor::Actions
|
|
9
|
+
include Eucalypt::Helpers
|
|
10
|
+
include Eucalypt::Helpers::Messages
|
|
11
|
+
include Eucalypt::Helpers::Gemfile
|
|
12
|
+
using Colorize
|
|
13
|
+
|
|
14
|
+
method_option :route, type: :string, aliases: '-r', default: 'blog', desc: "The route at which the blog lies"
|
|
15
|
+
desc "setup", "Sets up the blog-aware environment".colorize(:grey)
|
|
16
|
+
def setup
|
|
17
|
+
directory = File.expand_path('.')
|
|
18
|
+
if Eucalypt.app? directory
|
|
19
|
+
Out.setup 'Setting up blog environment...'
|
|
20
|
+
|
|
21
|
+
gemfile_add(
|
|
22
|
+
'Markdown and YAML front-matter parsing',
|
|
23
|
+
{front_matter_parser: '0.2.0', rdiscount: '~> 2.2'},
|
|
24
|
+
directory
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
generator = Eucalypt::Generators::Blog.new
|
|
28
|
+
generator.destination_root = directory
|
|
29
|
+
generator.helper
|
|
30
|
+
generator.controller(route: options[:route])
|
|
31
|
+
generator.views
|
|
32
|
+
|
|
33
|
+
asset_pipeline_file = File.join(directory, 'config', 'asset_pipeline.rb')
|
|
34
|
+
|
|
35
|
+
File.open(asset_pipeline_file) do |f|
|
|
36
|
+
return if f.read.include? "environment.append_path Eucalypt.path 'app', 'assets', 'blog'"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
insert_into_file(
|
|
40
|
+
asset_pipeline_file,
|
|
41
|
+
"\tenvironment.append_path Eucalypt.path 'app', 'assets', 'blog'\n",
|
|
42
|
+
after: "set :environment, Sprockets::Environment.new\n"
|
|
43
|
+
)
|
|
44
|
+
else
|
|
45
|
+
Eucalypt::Error.wrong_directory
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class << self
|
|
50
|
+
require 'eucalypt/list'
|
|
51
|
+
include Eucalypt::List
|
|
52
|
+
def banner(task, namespace = false, subcommand = true)
|
|
53
|
+
basename + ' ' + task.formatted_usage(self, true, subcommand).split(':').join(' ')
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
register(Eucalypt::BlogArticle, 'article', 'article [COMMAND]', 'Create, edit and destroy blog articles'.colorize(:grey))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class CLI < Thor
|
|
61
|
+
include Eucalypt::Helpers
|
|
62
|
+
using Colorize
|
|
63
|
+
register(Blog, 'blog', 'blog [COMMAND]', 'Manage static blog environment'.colorize(:grey))
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__base__'
|
|
2
|
+
|
|
3
|
+
module Eucalypt
|
|
4
|
+
module Generators
|
|
5
|
+
class Blog < Thor::Group
|
|
6
|
+
def article(urltitle:)
|
|
7
|
+
urltitle = Inflect.route(urltitle)
|
|
8
|
+
|
|
9
|
+
dt = Hash.new
|
|
10
|
+
dt[:full] = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
|
11
|
+
dt[:date] = dt[:full].split(' ').first
|
|
12
|
+
|
|
13
|
+
# Assets path generation
|
|
14
|
+
asset_base = File.join 'app', 'assets', 'blog'
|
|
15
|
+
asset_path = File.join asset_base, dt[:date].gsub(?-,?/), urltitle
|
|
16
|
+
|
|
17
|
+
empty_directory(asset_path)
|
|
18
|
+
|
|
19
|
+
# Markdown file and path generation
|
|
20
|
+
article_base = File.join 'app', 'views', 'blog', 'markdown'
|
|
21
|
+
article_path = File.join article_base, dt[:date].gsub(?-,?/), "#{urltitle}.md"
|
|
22
|
+
|
|
23
|
+
config = {datetime: dt[:full], date: dt[:date], urltitle: urltitle}
|
|
24
|
+
template File.join('views', 'article_md.tt'), article_path, config
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__base__'
|
|
2
|
+
|
|
3
|
+
module Eucalypt
|
|
4
|
+
module Generators
|
|
5
|
+
class Blog < Thor::Group
|
|
6
|
+
def controller(route:)
|
|
7
|
+
route = "/#{Inflect.route(route)}"
|
|
8
|
+
config = {route: route}
|
|
9
|
+
template File.join('controller','controller.tt'), File.join('app','controllers','blog_controller.rb'), config
|
|
10
|
+
template File.join('controller','controller_spec.tt'), File.join('spec','controllers','blog_controller_spec.rb')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__base__'
|
|
2
|
+
|
|
3
|
+
module Eucalypt
|
|
4
|
+
module Generators
|
|
5
|
+
class Blog < Thor::Group
|
|
6
|
+
def helper
|
|
7
|
+
template File.join('helper','helper.tt'), File.join('app','helpers','blog_helper.rb')
|
|
8
|
+
template File.join('helper','helper_spec.tt'), File.join('spec','helpers','blog_helper_spec.rb')
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'eucalypt/helpers'
|
|
2
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__base__'
|
|
3
|
+
|
|
4
|
+
module Eucalypt
|
|
5
|
+
module Generators
|
|
6
|
+
class Blog < Thor::Group
|
|
7
|
+
include Eucalypt::Helpers
|
|
8
|
+
using Array::DateSort
|
|
9
|
+
using String::Builder
|
|
10
|
+
using Colorize
|
|
11
|
+
|
|
12
|
+
def list(tag, order, date)
|
|
13
|
+
chars = {corner: ?+, vertical: ?║, horizontal: ?═}
|
|
14
|
+
|
|
15
|
+
puts
|
|
16
|
+
|
|
17
|
+
files = Dir.glob(File.join(self.destination_root,"app/views/blog/markdown/**/*.md"))
|
|
18
|
+
if files.empty?
|
|
19
|
+
puts "0 article(s) found."
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
date_regex = Eucalypt::Blog::Helpers.send :construct_date_regex, date
|
|
24
|
+
|
|
25
|
+
metadata = files.map{|md|FrontMatterParser::Parser.parse_file(md).front_matter.symbolize_keys}
|
|
26
|
+
metadata.select!{|post|post[:tags].any?{|t|t.include?(tag)}} unless tag.empty?
|
|
27
|
+
metadata.select!{|post|date_regex.match? post[:time].split.first} if date_regex
|
|
28
|
+
metadata.sort_by_date!(order: order)
|
|
29
|
+
|
|
30
|
+
number = metadata.length
|
|
31
|
+
if number == 0
|
|
32
|
+
puts "0 article(s) found.\n"
|
|
33
|
+
return
|
|
34
|
+
else
|
|
35
|
+
puts "#{metadata.length} article(s) found.\n"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
longest = 0
|
|
39
|
+
metadata.each do |article|
|
|
40
|
+
article.each do |k,v|
|
|
41
|
+
next if %i[desc datetime].include? k
|
|
42
|
+
str = "#{k}: #{v}"
|
|
43
|
+
longest = str.length if longest < str.length
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
output = String.build "\n" do |s|
|
|
48
|
+
s << (chars[:corner]+chars[:horizontal]*(longest+2)+chars[:corner]+"\n")
|
|
49
|
+
metadata.each do |article|
|
|
50
|
+
article.each do |k,v|
|
|
51
|
+
next if k == :datetime
|
|
52
|
+
str = "#{k}: #{v}"
|
|
53
|
+
if k == :desc
|
|
54
|
+
value = v.to_s
|
|
55
|
+
rel = longest-(k.length+5) # 5 is from ": " and "..."
|
|
56
|
+
unless str.length <= longest
|
|
57
|
+
str = "#{k}: #{value.length > rel ? "#{value[0...rel]}..." : value}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
len = str.ljust(longest,' ').length-str.length
|
|
61
|
+
s << "#{chars[:vertical]} "
|
|
62
|
+
s << "#{k.to_s.colorize(:magenta)}: #{str[(k.to_s.length+2)..-1]}"
|
|
63
|
+
s << ' '*len
|
|
64
|
+
s << " #{chars[:vertical]}\n"
|
|
65
|
+
end
|
|
66
|
+
s << (chars[:corner]+chars[:horizontal]*(longest+2)+chars[:corner]+"\n")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
puts output
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'eucalypt/eucalypt-blog/namespaces/blog/__base__'
|
|
2
|
+
|
|
3
|
+
module Eucalypt
|
|
4
|
+
module Generators
|
|
5
|
+
class Blog < Thor::Group
|
|
6
|
+
def views
|
|
7
|
+
config = {erb: ["<%= application :css, :js %>","<%= yield %>"]}
|
|
8
|
+
template File.join('views','article_layout.erb'), File.join('app','views','layouts','blog','article.erb'), config
|
|
9
|
+
template File.join('views','articles_layout.erb'), File.join('app','views','layouts','blog','articles.erb'), config
|
|
10
|
+
|
|
11
|
+
config = {erb: "<%= content %>"}
|
|
12
|
+
template File.join('views','article.erb'), File.join('app','views','blog','article.erb'), config
|
|
13
|
+
|
|
14
|
+
config = {erb: "<%= @articles %>"}
|
|
15
|
+
template File.join('views','articles.erb'), File.join('app','views','blog','articles.erb'), config
|
|
16
|
+
template File.join('views','search.erb'), File.join('app','views','blog','search.erb'), config
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class BlogController < Eucalypt::Controller(route: '<%= config[:route] %>')
|
|
2
|
+
helpers BlogHelper
|
|
3
|
+
using Array::DateSort
|
|
4
|
+
|
|
5
|
+
# Display all blog articles at this route
|
|
6
|
+
get '/' do
|
|
7
|
+
@articles = Blog.all.sort_by_date order: :descending
|
|
8
|
+
erb :'blog/articles', layout: :'layouts/blog/articles'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Display a single blog article at this route
|
|
12
|
+
Blog.articles.each do |md|
|
|
13
|
+
article = Blog::Article.new md
|
|
14
|
+
get article.route do
|
|
15
|
+
@front_matter = article.front_matter
|
|
16
|
+
locals = {content: markdown(article.content), article: article}
|
|
17
|
+
erb :'blog/article', locals: locals, layout: :'layouts/blog/article'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Search for blog articles by tag at this route
|
|
22
|
+
get '/search/:tag' do
|
|
23
|
+
@tag = params[:tag]
|
|
24
|
+
redirect to '/' unless @tag.match /\A[a-zA-Z]*[a-zA-Z0-9\\-_.]*[a-zA-Z0-9]\Z/
|
|
25
|
+
@articles = Blog.search(@tag).sort_by_date order: :descending
|
|
26
|
+
erb :'blog/search', layout: :'layouts/blog/articles'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Redirect all other blog routes
|
|
30
|
+
get %r{/.*} do
|
|
31
|
+
redirect to '/'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
require 'front_matter_parser'
|
|
3
|
+
|
|
4
|
+
describe BlogController do
|
|
5
|
+
def app() BlogController end
|
|
6
|
+
|
|
7
|
+
ARTICLES = Eucalypt.glob('app', 'views', 'blog', 'markdown', '**', '*.md').map do |md|
|
|
8
|
+
FrontMatterParser::Parser.parse_file(md).front_matter.symbolize_keys
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe 'blog page' do
|
|
12
|
+
it "should display all posts" do
|
|
13
|
+
get '/'
|
|
14
|
+
expect(true).to be false
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
ARTICLES.each do |post|
|
|
19
|
+
subpath = post[:time].split(' ').first.gsub(?-,?/)
|
|
20
|
+
|
|
21
|
+
describe "Post: #{post[:title]}" do
|
|
22
|
+
before { get "/#{subpath}/#{post[:urltitle]}" }
|
|
23
|
+
|
|
24
|
+
it "should have a timestamp" do
|
|
25
|
+
expect(true).to be false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should have a title" do
|
|
29
|
+
expect(true).to be false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should have a description" do
|
|
33
|
+
expect(true).to be false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should have tags" do
|
|
37
|
+
post[:tags].each do |tag|
|
|
38
|
+
expect(true).to be false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|