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.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +21 -0
  4. data/README.md +26 -0
  5. data/Rakefile +2 -0
  6. data/bin/eucalypt +3 -0
  7. data/eucalypt.gemspec +39 -0
  8. data/lib/eucalypt/app.rb +6 -0
  9. data/lib/eucalypt/controller.rb +10 -0
  10. data/lib/eucalypt/errors.rb +109 -0
  11. data/lib/eucalypt/eucalypt-blog/helpers.rb +106 -0
  12. data/lib/eucalypt/eucalypt-blog/namespaces/blog/__base__.rb +22 -0
  13. data/lib/eucalypt/eucalypt-blog/namespaces/blog/__require__.rb +1 -0
  14. data/lib/eucalypt/eucalypt-blog/namespaces/blog/cli/blog.rb +65 -0
  15. data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/article.rb +28 -0
  16. data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/controller.rb +14 -0
  17. data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/helper.rb +12 -0
  18. data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/list.rb +74 -0
  19. data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/views.rb +20 -0
  20. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller.tt +33 -0
  21. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller_spec.tt +43 -0
  22. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper.tt +5 -0
  23. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper_spec.tt +9 -0
  24. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article.erb +1 -0
  25. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_layout.erb +10 -0
  26. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_md.tt +9 -0
  27. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles.erb +1 -0
  28. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles_layout.erb +10 -0
  29. data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/search.erb +1 -0
  30. data/lib/eucalypt/eucalypt-blog/namespaces/blog-article/cli/article.rb +120 -0
  31. data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-datetime.rb +113 -0
  32. data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-urltitle.rb +75 -0
  33. data/lib/eucalypt/eucalypt-core/cli/__base__.rb +11 -0
  34. data/lib/eucalypt/eucalypt-core/cli/console.rb +15 -0
  35. data/lib/eucalypt/eucalypt-core/cli/core.rb +6 -0
  36. data/lib/eucalypt/eucalypt-core/cli/help.rb +11 -0
  37. data/lib/eucalypt/eucalypt-core/cli/init.rb +71 -0
  38. data/lib/eucalypt/eucalypt-core/cli/launch.rb +33 -0
  39. data/lib/eucalypt/eucalypt-core/cli/test.rb +16 -0
  40. data/lib/eucalypt/eucalypt-core/cli/version.rb +11 -0
  41. data/lib/eucalypt/eucalypt-core/templates/Gemfile.tt +35 -0
  42. data/lib/eucalypt/eucalypt-core/templates/eucalypt/.gitignore +48 -0
  43. data/lib/eucalypt/eucalypt-core/templates/eucalypt/.travis.yml +8 -0
  44. data/lib/eucalypt/eucalypt-core/templates/eucalypt/Procfile +1 -0
  45. data/lib/eucalypt/eucalypt-core/templates/eucalypt/Rakefile +7 -0
  46. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/fonts/.empty_directory +0 -0
  47. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/images/.empty_directory +0 -0
  48. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/scripts/application.js +17 -0
  49. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/__partials__.scss +16 -0
  50. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/application.scss +17 -0
  51. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/partials/_mixins.scss +54 -0
  52. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/controllers/application_controller.rb +7 -0
  53. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/helpers/application_helper.rb +3 -0
  54. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/models/.empty_directory +0 -0
  55. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/.empty_directory +0 -0
  56. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/readme.yml +34 -0
  57. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/index.erb +0 -0
  58. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/layouts/main.erb +9 -0
  59. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/partials/.empty_directory +0 -0
  60. data/lib/eucalypt/eucalypt-core/templates/eucalypt/app.rb +42 -0
  61. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/active_record.rb +6 -0
  62. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/asset_pipeline.rb +15 -0
  63. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/database.yml +16 -0
  64. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/initializers/.empty_directory +0 -0
  65. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/logging.rb +27 -0
  66. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/manifest.rb +15 -0
  67. data/lib/eucalypt/eucalypt-core/templates/eucalypt/config.ru +10 -0
  68. data/lib/eucalypt/eucalypt-core/templates/eucalypt/log/.empty_directory +0 -0
  69. data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/controllers/application_controller_spec.rb +9 -0
  70. data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/helpers/application_helper_spec.rb +9 -0
  71. data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/models/.empty_directory +0 -0
  72. data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/spec_helper.rb +18 -0
  73. data/lib/eucalypt/eucalypt-destroy/helpers.rb +77 -0
  74. data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-controller.rb +16 -0
  75. data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-helper.rb +16 -0
  76. data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-model.rb +16 -0
  77. data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-scaffold.rb +63 -0
  78. data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy.rb +21 -0
  79. data/lib/eucalypt/eucalypt-generate/.gitkeep +0 -0
  80. data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate-scaffold.rb +62 -0
  81. data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate.rb +24 -0
  82. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/cli/generate-controller.rb +29 -0
  83. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/generators/controller.rb +45 -0
  84. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/controller.tt +3 -0
  85. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/policy_rest_controller.tt +71 -0
  86. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/rest_controller.tt +28 -0
  87. data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller_spec.tt +9 -0
  88. data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/cli/generate-helper.rb +23 -0
  89. data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/generators/helper.rb +24 -0
  90. data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper.tt +3 -0
  91. data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper_spec.tt +9 -0
  92. data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/cli/generate-model.rb +26 -0
  93. data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/generators/model.rb +25 -0
  94. data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model.tt +3 -0
  95. data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model_spec.tt +8 -0
  96. data/lib/eucalypt/eucalypt-migration/helpers.rb +93 -0
  97. data/lib/eucalypt/eucalypt-migration/migration_base.tt +4 -0
  98. data/lib/eucalypt/eucalypt-migration/namespaces/migration/cli/migration.rb +39 -0
  99. data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-column.rb +25 -0
  100. data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-index.rb +25 -0
  101. data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add.rb +18 -0
  102. data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/column.rb +46 -0
  103. data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/index.rb +52 -0
  104. data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/cli/blank.rb +22 -0
  105. data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/generators/blank.rb +28 -0
  106. data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change-column.rb +23 -0
  107. data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change.rb +17 -0
  108. data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/generators/column.rb +46 -0
  109. data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create-table.rb +25 -0
  110. data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create.rb +17 -0
  111. data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/generators/table.rb +53 -0
  112. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-column.rb +22 -0
  113. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-index.rb +23 -0
  114. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-table.rb +22 -0
  115. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop.rb +19 -0
  116. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/column.rb +38 -0
  117. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/index.rb +48 -0
  118. data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/table.rb +37 -0
  119. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-column.rb +22 -0
  120. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-index.rb +22 -0
  121. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-table.rb +24 -0
  122. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename.rb +19 -0
  123. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/column.rb +39 -0
  124. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/index.rb +39 -0
  125. data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/table.rb +38 -0
  126. data/lib/eucalypt/eucalypt-security/helpers.rb +22 -0
  127. data/lib/eucalypt/eucalypt-security/namespaces/security/cli/security.rb +31 -0
  128. data/lib/eucalypt/eucalypt-security/namespaces/security-policy/cli/security-policy.rb +91 -0
  129. data/lib/eucalypt/eucalypt-security/namespaces/security-policy/generators/policy.rb +31 -0
  130. data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/create_policy_roles_migration.tt +11 -0
  131. data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/policy.tt +16 -0
  132. data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/cli/security-policy-permission.rb +62 -0
  133. data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/generators/policy-permission.rb +28 -0
  134. data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/templates/add_permission_to_policy_migration.tt +5 -0
  135. data/lib/eucalypt/eucalypt-security/namespaces/security-policy-role/cli/security-policy-role.rb +66 -0
  136. data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/cli/security-pundit.rb +79 -0
  137. data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/generators/role.rb +24 -0
  138. data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/create_roles_migration.tt +7 -0
  139. data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/pundit.tt +4 -0
  140. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/cli/security-warden.rb +61 -0
  141. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/auth_controller.rb +34 -0
  142. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/user.rb +37 -0
  143. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_controller.tt +25 -0
  144. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_login.tt +1 -0
  145. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/create_users_table_migration.tt +9 -0
  146. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/user.tt +16 -0
  147. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/warden.tt +35 -0
  148. data/lib/eucalypt/eucalypt-security/namespaces/security-warden/user_confirm.rb +38 -0
  149. data/lib/eucalypt/helpers/colorize.rb +27 -0
  150. data/lib/eucalypt/helpers/gemfile.rb +48 -0
  151. data/lib/eucalypt/helpers/inflect.rb +79 -0
  152. data/lib/eucalypt/helpers/messages.rb +31 -0
  153. data/lib/eucalypt/helpers/migration.rb +85 -0
  154. data/lib/eucalypt/helpers/numeric.rb +10 -0
  155. data/lib/eucalypt/helpers.rb +6 -0
  156. data/lib/eucalypt/list.rb +39 -0
  157. data/lib/eucalypt/static.rb +48 -0
  158. data/lib/eucalypt/version.rb +3 -0
  159. data/lib/eucalypt.rb +19 -0
  160. metadata +373 -0
@@ -0,0 +1,5 @@
1
+ module BlogHelper
2
+ include Eucalypt::Blog::Helpers
3
+ Blog.articles = Eucalypt.glob 'app', 'views', 'blog', 'markdown', '**', '*.md'
4
+ # Add your helper methods here...
5
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe BlogHelper do
4
+ include BlogHelper
5
+
6
+ it "should expect true to be true" do
7
+ expect(true).to be false
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ <!-- Layout for displaying a single blog article -->
2
+ <html>
3
+ <head>
4
+ <title></title>
5
+ <%= config[:erb][0] %>
6
+ </head>
7
+ <body>
8
+ <%= config[:erb][1] %>
9
+ </body>
10
+ </html>
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: "TODO"
3
+ desc: "TODO"
4
+ tags: ["TODO"]
5
+ # Only change the below fields with `eucalypt blog article edit` commands!
6
+ urltitle: "<%= config[:urltitle] %>"
7
+ time: "<%= config[:datetime] %>"
8
+ assetpath: "/assets/<%= config[:date].gsub(?-,?/) %>/<%= config[:urltitle] %>/"
9
+ ---
@@ -0,0 +1,10 @@
1
+ <!-- Layout for displaying all blog articles (or articles found in a blog search) -->
2
+ <html>
3
+ <head>
4
+ <title></title>
5
+ <%= config[:erb][0] %>
6
+ </head>
7
+ <body>
8
+ <%= config[:erb][1] %>
9
+ </body>
10
+ </html>
@@ -0,0 +1,120 @@
1
+ require 'eucalypt/errors'
2
+ require 'eucalypt/helpers'
3
+ require 'eucalypt/eucalypt-blog/helpers'
4
+ require 'eucalypt/eucalypt-blog/namespaces/blog/__require__'
5
+ require 'eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-datetime'
6
+ require 'eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-urltitle'
7
+
8
+ module Eucalypt
9
+ class BlogArticle < Thor
10
+ include Thor::Actions
11
+ include Eucalypt::Helpers
12
+ include Eucalypt::Helpers::Messages
13
+ include Eucalypt::Blog::Helpers
14
+ using Colorize
15
+
16
+ method_option :descending, type: :boolean, aliases: '-d', default: true, desc: 'Descending chronological order'
17
+ method_option :ascending, type: :boolean, aliases: '-a', default: false, desc: 'Ascending chronological order'
18
+ method_option :tag, type: :string, aliases: '-t', default: String.new, desc: 'Search by blog article tag'
19
+ method_option :year, type: :string, aliases: '-Y', desc: 'Search articles by year'
20
+ method_option :month, type: :string, aliases: '-M', desc: 'Search articles by month'
21
+ method_option :day, type: :string, aliases: '-D', desc: 'Search articles by day'
22
+ desc "list", "Display the metadata of blog articles".colorize(:grey)
23
+ def list
24
+ directory = File.expand_path('.')
25
+ if Eucalypt.app? directory
26
+ return unless Gemfile.check(%w[front_matter_parser rdiscount], 'eucalypt blog setup', directory)
27
+
28
+ generator = Eucalypt::Generators::Blog.new
29
+ generator.destination_root = directory
30
+ generator.list(
31
+ options[:tag],
32
+ options[:ascending] ? :ascending : :descending,
33
+ {year: options[:year], month: options[:month], day: options[:day]}
34
+ )
35
+ else
36
+ Eucalypt::Error.wrong_directory
37
+ end
38
+ end
39
+
40
+ desc "generate [URLTITLE]", "Create a new blog article".colorize(:grey)
41
+ def generate(urltitle)
42
+ directory = File.expand_path('.')
43
+ if Eucalypt.app? directory
44
+ return unless Gemfile.check(%w[front_matter_parser rdiscount], 'eucalypt blog setup', directory)
45
+
46
+ urltitle = Inflect.route(urltitle) if urltitle
47
+
48
+ generator = Eucalypt::Generators::Blog.new
49
+ generator.destination_root = directory
50
+ generator.article(urltitle: urltitle)
51
+ else
52
+ Eucalypt::Error.wrong_directory
53
+ end
54
+ end
55
+
56
+ desc "destroy [URLTITLE]", "Destroys a blog article".colorize(:grey)
57
+ def destroy(urltitle = nil)
58
+ directory = File.expand_path('.')
59
+ if Eucalypt.app? directory
60
+ return unless Gemfile.check(%w[front_matter_parser rdiscount], 'eucalypt blog setup', directory)
61
+
62
+ markdown_base = File.join directory, 'app', 'views', 'blog', 'markdown'
63
+ articles_path = File.join '**', (urltitle ? "#{urltitle}.md" : "*.md")
64
+
65
+ articles = Dir[File.join markdown_base, articles_path]
66
+ if articles.empty?
67
+ Eucalypt::Error.no_articles
68
+ return
69
+ end
70
+
71
+ Eucalypt::Error.delete_article_warning; puts
72
+
73
+ asset_base = File.join directory, 'app', 'assets', 'blog'
74
+ articles_hash = {}
75
+ article_numbers = []
76
+ articles.each_with_index do |article, i|
77
+ number = (i+1).to_s
78
+ article_numbers << number
79
+ identifier = article.split(markdown_base.gsub(/\/$/,'')<<?/).last.split('.md').first
80
+ articles_hash[number.to_sym] = identifier
81
+ title = FrontMatterParser::Parser.parse_file(article).front_matter['title']
82
+ puts "#{number.colorize(:bold)}: #{identifier}#{title ? " - #{title}" : ''}"
83
+ end
84
+
85
+ article_number = ask("\nEnter the number of the article to delete:", limited_to: article_numbers)
86
+ article = articles_hash[article_number.to_sym]
87
+ delete_article = ask Out.warning_message("Delete article #{article.colorize(:bold)}?"), limited_to: %w[y Y Yes YES n N No NO]
88
+ return unless %w[y Y Yes YES].include? delete_article
89
+ remove_file File.join(markdown_base, "#{article}.md")
90
+ paths = article.rpartition ?/
91
+ Dir.chdir(File.join asset_base, paths.first) { FileUtils.rm_rf paths.last }
92
+
93
+ Eucalypt::Blog::Helpers.send :clean_directory, asset_base
94
+ Eucalypt::Blog::Helpers.send :clean_directory, markdown_base
95
+ else
96
+ Eucalypt::Error.wrong_directory
97
+ end
98
+ end
99
+
100
+ class << self
101
+ require 'eucalypt/list'
102
+ include Eucalypt::List
103
+ def banner(task, namespace = false, subcommand = true)
104
+ "#{basename} blog #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
105
+ end
106
+ end
107
+
108
+ class Eucalypt::BlogArticleEdit < Thor
109
+ class << self
110
+ require 'eucalypt/list'
111
+ include Eucalypt::List
112
+ def banner(task, namespace = false, subcommand = true)
113
+ "#{basename} blog article #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
114
+ end
115
+ end
116
+ end
117
+
118
+ register(Eucalypt::BlogArticleEdit, 'edit', 'edit [COMMAND]', 'Edit blog articles'.colorize(:grey))
119
+ end
120
+ end
@@ -0,0 +1,113 @@
1
+ require 'thor'
2
+ require 'eucalypt/errors'
3
+ require 'eucalypt/helpers'
4
+ require 'eucalypt/eucalypt-blog/helpers'
5
+
6
+ module Eucalypt
7
+ class BlogArticleEdit < Thor
8
+ include Thor::Actions
9
+ include Eucalypt::Helpers
10
+ include Eucalypt::Helpers::Messages
11
+ include Eucalypt::Blog::Helpers
12
+ using Colorize
13
+
14
+ desc "datetime [URLTITLE]", "Edits the datetime of a blog post".colorize(:grey)
15
+ def datetime(urltitle = nil)
16
+ directory = File.expand_path('.')
17
+ if Eucalypt.app? directory
18
+ return unless Gemfile.check(%w[front_matter_parser rdiscount], 'eucalypt blog setup', directory)
19
+
20
+ article_base = File.join directory, 'app', 'views', 'blog', 'markdown'
21
+ article_asset_base = File.join directory, 'app', 'assets', 'blog'
22
+ articles = Dir[File.join article_base, '**','*.md']
23
+
24
+ if articles.empty?
25
+ Eucalypt::Error.no_articles
26
+ return
27
+ end
28
+
29
+ if urltitle
30
+ if articles.any? {|a| File.basename(a, '.md') == urltitle}
31
+ articles = articles.select {|a| File.basename(a, '.md') == urltitle}
32
+ else
33
+ Eucalypt::Error.no_articles
34
+ return
35
+ end
36
+ end
37
+
38
+ articles_hash = Eucalypt::Blog::Helpers.send :build_article_hash, articles, article_base
39
+ article_number = ask("Enter the number of the article to edit:", limited_to: articles_hash.keys.map(&:to_s))
40
+ article = articles_hash[article_number.to_sym]
41
+
42
+ current_datetime = article[:front_matter]['time']
43
+ puts "\n\tCurrent datetime: #{current_datetime.colorize(:bold)}"
44
+
45
+ new_datetime = ''
46
+ loop do
47
+ new_datetime = ask "\nEnter the new datetime (format YYYY-MM-DD HH:MM:SS):"
48
+ valid = false
49
+ begin
50
+ DateTime.strptime(new_datetime, "%Y-%m-%d %H:%M:%S").tap do |output|
51
+ valid = output.strftime("%Y-%m-%d %H:%M:%S") == new_datetime
52
+ end
53
+ rescue ArgumentError
54
+ Out.error 'Incorrect datetime format.'
55
+ end
56
+ break if valid
57
+ end
58
+
59
+ new_date, new_time = new_datetime.split
60
+ current_date, current_time = current_datetime.split
61
+
62
+ update = ask Out.warning_message("Change datetime from #{current_datetime.colorize(:bold)} to #{new_datetime.colorize(:bold)}?"), limited_to: %w[y Y Yes YES n N No NO]
63
+ return unless %w[y Y Yes YES].include? update
64
+
65
+ gsub_file(
66
+ article[:path],
67
+ /time\:.*\n/,
68
+ "time: \"#{new_datetime}\"\n"
69
+ )
70
+
71
+ gsub_file(
72
+ article[:path],
73
+ "/assets/#{current_date.gsub(?-,?/)}/#{article[:front_matter]['urltitle']}",
74
+ "/assets/#{new_date.gsub(?-,?/)}/#{article[:front_matter]['urltitle']}"
75
+ )
76
+
77
+ Dir.chdir(article_asset_base) do
78
+ relative_from_urltitle = File.join
79
+ asset_files = Dir[File.join article[:identifier], '**', '*']
80
+ asset_files.each do |file|
81
+ next unless File.file? file
82
+ path_to_urltitle = File.join article_asset_base, article[:identifier]
83
+ full_file_path = File.join article_asset_base, file
84
+ relative_to_urltitle = full_file_path.split(path_to_urltitle.gsub(/\/$/,'')<<?/).last
85
+ destination_date = File.join article_asset_base, new_date.gsub(?-,?/)
86
+ destination = File.join destination_date, article[:front_matter]['urltitle'], relative_to_urltitle
87
+
88
+ reset = Eucalypt::Blog::Article::Edit.source_root
89
+ Eucalypt::Blog::Article::Edit.source_root(article_asset_base)
90
+ copy_file file, destination
91
+ Eucalypt::Blog::Article::Edit.source_root(reset)
92
+ remove_file(full_file_path)
93
+ end
94
+ FileUtils.mkdir_p File.join(new_date.gsub(?-,?/), File.basename(article[:base_name], '.md'))
95
+ FileUtils.rm_rf article[:identifier]
96
+ end
97
+
98
+ Eucalypt::Blog::Helpers.send :clean_directory, article_asset_base
99
+
100
+ Dir.chdir(article_base) do
101
+ destination_directory = File.join new_date.gsub(?-,?/)
102
+ FileUtils.mkdir_p(destination_directory)
103
+ FileUtils.mv(article[:identifier] << '.md', destination_directory)
104
+ end
105
+
106
+ Eucalypt::Blog::Helpers.send :clean_directory, article_base
107
+
108
+ else
109
+ Eucalypt::Error.wrong_directory
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,75 @@
1
+ require 'thor'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+
5
+ require 'eucalypt/errors'
6
+ require 'eucalypt/helpers'
7
+ require 'eucalypt/eucalypt-blog/helpers'
8
+
9
+ module Eucalypt
10
+ class BlogArticleEdit < Thor
11
+ include Thor::Actions
12
+ include Eucalypt::Helpers
13
+ include Eucalypt::Helpers::Messages
14
+ include Eucalypt::Blog::Helpers
15
+ using Colorize
16
+
17
+ desc "urltitle [URLTITLE]", "Edits the urltitle of a blog post".colorize(:grey)
18
+ def urltitle(urltitle = nil)
19
+ directory = File.expand_path('.')
20
+ if Eucalypt.app? directory
21
+ return unless Gemfile.check(%w[front_matter_parser rdiscount], 'eucalypt blog setup', directory)
22
+
23
+ article_base = File.join directory, 'app', 'views', 'blog', 'markdown'
24
+ article_asset_base = File.join directory, 'app', 'assets', 'blog'
25
+ articles = Dir[File.join article_base, '**', '*.md']
26
+
27
+ if articles.empty?
28
+ Eucalypt::Error.no_articles
29
+ return
30
+ end
31
+
32
+ if urltitle
33
+ if articles.any? {|a| File.basename(a, '.md') == urltitle}
34
+ articles = articles.select {|a| File.basename(a, '.md') == urltitle}
35
+ else
36
+ Eucalypt::Error.no_articles
37
+ return
38
+ end
39
+ end
40
+
41
+ articles_hash = Eucalypt::Blog::Helpers.send :build_article_hash, articles, article_base
42
+ article_number = ask("Enter the number of the article to edit:", limited_to: articles_hash.keys.map(&:to_s))
43
+ article = articles_hash[article_number.to_sym]
44
+
45
+ current_urltitle = article[:front_matter]['urltitle']
46
+ new_urltitle = ask("Enter new urltitle:").parameterize
47
+ update = ask Out.warning_message("Change urltitle from #{current_urltitle.colorize(:bold)} to #{new_urltitle.colorize(:bold)}?"), limited_to: %w[y Y Yes YES n N No NO]
48
+ return unless %w[y Y Yes YES].include? update
49
+
50
+ gsub_file(
51
+ article[:path],
52
+ /urltitle\:.*\n/,
53
+ "urltitle: \"#{new_urltitle}\"\n"
54
+ )
55
+
56
+ gsub_file(
57
+ article[:path],
58
+ /\/assets\/#{article[:date]}\/#{current_urltitle}/,
59
+ "/assets/#{article[:date]}/#{new_urltitle}"
60
+ )
61
+
62
+ Dir.chdir(File.join article_base, article[:date]) do
63
+ FileUtils.mv(article[:base_name], "#{new_urltitle}.md")
64
+ end
65
+
66
+ Dir.chdir(File.join article_asset_base, article[:date]) do
67
+ FileUtils.mv(File.basename(article[:base_name], '.md'), new_urltitle)
68
+ end
69
+
70
+ else
71
+ Eucalypt::Error.wrong_directory
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,11 @@
1
+ require 'eucalypt/errors'
2
+ require 'eucalypt/version'
3
+ require 'eucalypt/helpers'
4
+ require 'thor'
5
+
6
+ module Eucalypt
7
+ class CLI < Thor
8
+ include Thor::Actions
9
+ include Eucalypt::Helpers
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require_relative '__base__'
2
+ module Eucalypt
3
+ class CLI < Thor
4
+ using Colorize
5
+ desc "console", "Interactive console with all files loaded".colorize(:grey)
6
+ def console
7
+ directory = File.expand_path('.')
8
+ if Eucalypt.app? directory
9
+ exec 'bundle exec irb -r ./app.rb'
10
+ else
11
+ Eucalypt::Error.wrong_directory
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'init'
2
+ require_relative 'launch'
3
+ require_relative 'console'
4
+ require_relative 'test'
5
+ require_relative 'version'
6
+ require_relative 'help'
@@ -0,0 +1,11 @@
1
+ require_relative '__base__'
2
+ module Eucalypt
3
+ class CLI < Thor
4
+ using Colorize
5
+ map %[-H] => :__help
6
+ desc "-H [COMMAND]", "Show additional information for a command".colorize(:grey)
7
+ def __help(*args)
8
+ Eucalypt::CLI.start args.insert(args.size-1, 'help')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,71 @@
1
+ require_relative '__base__'
2
+ require 'string/builder'
3
+ module Eucalypt
4
+ class CLI < Thor
5
+ include Eucalypt::Helpers::Messages
6
+ using String::Builder
7
+ using Colorize
8
+ method_option :git, type: :boolean, default: true, desc: 'Initialize a Git repository'
9
+ method_option :bundle, type: :boolean, default: true, desc: 'Install gems after application generation'
10
+ method_option :blog, type: :boolean, default: false, aliases: '-b', desc: 'Set up the blog environment'
11
+ method_option :route, type: :string, default: 'blog', aliases: '-r', desc: 'Specify a route for the blog application'
12
+ method_option :silence, type: :boolean, default: false, aliases: '-s', desc: 'Silence `git init` and `bundle install` commands'
13
+ method_option :warden, type: :boolean, default: false, aliases: '-w', desc: 'Set up Warden authentication'
14
+ method_option :pundit, type: :boolean, default: false, aliases: '-p', desc: 'Set up Pundit authorization'
15
+ desc "init [NAME]", "Sets up your application".colorize(:grey)
16
+ def init(name)
17
+ current_directory = File.expand_path ?.
18
+ name = Inflect.route(name)
19
+ root = File.join(current_directory, name)
20
+ if Dir.exist? root
21
+ Out.error "Directory #{name.colorize(:bold)} already exists."
22
+ return
23
+ else
24
+ if File.file? File.join(current_directory, Eucalypt::APP_FILE)
25
+ Eucalypt::Error.found_app_file
26
+ initialize_anyway = ask "Initialize application anyway?", limited_to: %w[y Y Yes YES n N No NO]
27
+ return unless %w[y Y Yes YES].include? initialize_anyway
28
+ end
29
+
30
+ Out.setup "Setting up Eucalypt application..."
31
+ Eucalypt::CLI.source_root File.join(File.dirname(__dir__), 'templates')
32
+
33
+ directory 'eucalypt', root
34
+
35
+ app_file_content = String.build do |s|
36
+ msg = "This file should be placed in the root directory of a Eucalypt application."
37
+ version_msg = "Generated with Eucalypt version: #{Eucalypt::VERSION}"
38
+ separator = "# #{?=*msg.size} #\n"
39
+ s << separator
40
+ s << "# #{msg} #\n"
41
+ s << separator
42
+ s << "# #{version_msg.center msg.size, ' '} #\n"
43
+ s << separator.chomp
44
+ end
45
+
46
+ create_file File.join(root, Eucalypt::APP_FILE), app_file_content
47
+
48
+ config = {version: Eucalypt::VERSION}
49
+ template 'Gemfile.tt', File.join(root, 'Gemfile'), config
50
+
51
+ if options[:blog]
52
+ inside(root) do
53
+ args = %w[blog setup]
54
+ args << '-r' << options[:route] if options[:route]
55
+ Eucalypt::CLI.start(args)
56
+ end
57
+ end
58
+
59
+ inside(root) do
60
+ Eucalypt::CLI.start %w[security warden setup] if options[:warden]
61
+ Eucalypt::CLI.start %w[security pundit setup] if options[:warden] && options[:pundit]
62
+ end
63
+
64
+ puts if options[:git] || options[:bundle]
65
+ inside(root) { run(options[:silence] ? 'git init --quiet' : 'git init') } if options[:git]
66
+ puts if options[:git] && options[:bundle]
67
+ inside(root) { run(options[:silence] ? 'bundle install --quiet' : 'bundle install') } if options[:bundle]
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '__base__'
2
+ module Eucalypt
3
+ class CLI < Thor
4
+ using Colorize
5
+ include Eucalypt::Helpers::Messages
6
+ method_option :port, type: :numeric, aliases: '-p', desc: 'Port to serve the application on'
7
+ method_option :rerun, type: :boolean, aliases: '-r', desc: 'Rerun (watch for file changes and restart server)'
8
+ method_option :quiet, type: :boolean, aliases: '-q', desc: 'Silences rerun (runs less verbosely)'
9
+ desc "launch [ENV]", "Launches your application".colorize(:grey)
10
+ def launch(env = ENV['RACK_ENV']||'development')
11
+ directory = File.expand_path('.')
12
+ if Eucalypt.app? directory
13
+ unless %w[production development test].include? env
14
+ Out.error "Invalid Rack environment #{env.colorize(:bold)}"
15
+ return
16
+ end
17
+
18
+ cmd = "bundle exec rackup -p #{options[:port]||9292}"
19
+
20
+ if options[:rerun]
21
+ cmd = "rerun \"#{cmd}\""
22
+ cmd.gsub!('rerun', 'rerun -q') if options[:quiet]
23
+ end
24
+
25
+ puts "Running command: #{cmd.colorize(:bold)}"
26
+ puts "Rack environment: #{env.colorize(:bold)}"
27
+ exec "env RACK_ENV=#{env} #{cmd}"
28
+ else
29
+ Eucalypt::Error.wrong_directory
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '__base__'
2
+ module Eucalypt
3
+ class CLI < Thor
4
+ using Colorize
5
+ method_option :summarized, type: :boolean, default: false, aliases: '-s', desc: 'rspec -fd spec'
6
+ desc "test", "Run all application tests".colorize(:grey)
7
+ def test
8
+ directory = File.expand_path('.')
9
+ if Eucalypt.app? directory
10
+ exec (options[:summarized] ? "rspec -fd spec" : "rspec spec")
11
+ else
12
+ Eucalypt::Error.wrong_directory
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ require_relative '__base__'
2
+ module Eucalypt
3
+ class CLI < Thor
4
+ using Colorize
5
+ map %w[--version -v] => :version
6
+ desc "version", "Display installed Eucalypt version".colorize(:grey)
7
+ def version
8
+ puts Eucalypt::VERSION
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Bundler
4
+ gem 'bundler', '~> 1.16'
5
+ # Sinatra DSL
6
+ gem 'sinatra', '~> 2.0', require: 'sinatra/base'
7
+ # Eucalypt CLI
8
+ gem 'eucalypt', '<%= config[:version] %>'
9
+ # Rake
10
+ gem 'rake', '~> 12.3'
11
+ # Server
12
+ gem 'thin', '~> 1.7'
13
+
14
+ # Test environment
15
+ group :test, :production do
16
+ gem 'rack-test', '~> 1.0', require: 'rack/test'
17
+ gem 'rspec', '~> 3.7'
18
+ gem 'shoulda-matchers', '~> 3.1'
19
+ end
20
+
21
+ # Database adapters
22
+ gem 'sqlite3', '~> 1.3', group: [:development, :test]
23
+ gem 'pg', '~> 1.0', group: :production
24
+ # ActiveRecord for models and records
25
+ gem 'activerecord', '~> 5.2', require: ['active_support','active_support/core_ext']
26
+ gem 'sinatra-activerecord', '~> 2.0', require: ['sinatra/activerecord','sinatra/activerecord/rake']
27
+ # Logging library
28
+ gem 'lumberjack', '~> 1.0'
29
+ # Asset pipeline and preprocessors/compressors
30
+ gem 'sprockets', '~> 3.7'
31
+ gem 'sassc', '~> 1.12'
32
+ gem 'uglifier', '~> 4.1'
33
+ # Hanami HTML/asset helpers
34
+ gem 'hanami-helpers', '~> 1.2', require: 'hanami/helpers'
35
+ gem 'hanami-assets', '~> 1.2', require: ['hanami/assets','hanami/assets/helpers']
@@ -0,0 +1,48 @@
1
+ ## Ruby
2
+ *.gem
3
+ *.rbc
4
+ /.config
5
+ /coverage/
6
+ /InstalledFiles
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/tmp/
10
+ /spec/examples.txt
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+
15
+ ## Logs, databases and sensitive files
16
+ *.log
17
+ *.sql
18
+ *.sqlite
19
+ *.sqlite3
20
+ *.dump
21
+
22
+ ## Used by dotenv library to load environment variables
23
+ .env
24
+
25
+ ## Documentation cache and generated files:
26
+ /.yardoc/
27
+ /_yardoc/
28
+ /doc/
29
+ /rdoc/
30
+ /coverage/
31
+
32
+ ## Environment normalization:
33
+ /.bundle/
34
+ /vendor/bundle
35
+ /lib/bundler/man/
36
+
37
+ ## OS generated files
38
+ .DS_Store
39
+ .DS_Store?
40
+ ._*
41
+ .Spotlight-V100
42
+ .Trashes
43
+ ehthumbs.db
44
+ Thumbs.db
45
+
46
+ ## Other
47
+ /.bundle/
48
+ .rvmrc
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install: gem update --system
3
+ script: bundle exec rake
4
+ rvm: 2.5
5
+ services:
6
+ - postgresql
7
+ addons:
8
+ postgresql: '10.1'
@@ -0,0 +1 @@
1
+ web: bundle exec rackup -p $PORT
@@ -0,0 +1,7 @@
1
+ require './app'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => [:spec]
5
+
6
+ desc "Run the specs"
7
+ RSpec::Core::RakeTask.new :spec