lb-project 0.0.1

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +41 -0
  3. data/.rspec +6 -0
  4. data/.rubocop.yml +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +7 -0
  7. data/Guardfile +43 -0
  8. data/LICENSE +20 -0
  9. data/README.md +28 -0
  10. data/Rakefile +6 -0
  11. data/bin/lb-project +29 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/mutant.yml +3 -0
  16. data/config/reek.yml +103 -0
  17. data/config/rubocop.yml +10 -0
  18. data/config/yardstick.yml +2 -0
  19. data/lb-project.gemspec +42 -0
  20. data/lib/lb/project/app.rb +9 -0
  21. data/lib/lb/project/config.rb +35 -0
  22. data/lib/lb/project/page.rb +19 -0
  23. data/lib/lb/project/registry/registration.rb +73 -0
  24. data/lib/lb/project/registry.rb +58 -0
  25. data/lib/lb/project/render.rb +28 -0
  26. data/lib/lb/project/route.rb +15 -0
  27. data/lib/lb/project/site.rb +41 -0
  28. data/lib/lb/project/types.rb +10 -0
  29. data/lib/lb/project/version.rb +8 -0
  30. data/lib/lb/project/view.rb +19 -0
  31. data/lib/lb/project.rb +159 -0
  32. data/lib/lb-project.rb +5 -0
  33. data/rakelib/ci.rake +24 -0
  34. data/spec/fixtures/config/application.yml +10 -0
  35. data/spec/fixtures/config/lb-project.yml +3 -0
  36. data/spec/fixtures/config.ru +9 -0
  37. data/spec/fixtures/docs/assets/javascripts/main.bundle.js +0 -0
  38. data/spec/fixtures/docs/assets/stylesheets/main.bundle.css +0 -0
  39. data/spec/fixtures/lib/example/app.rb +14 -0
  40. data/spec/fixtures/lib/example/page/index.rb +13 -0
  41. data/spec/fixtures/lib/example/page.rb +8 -0
  42. data/spec/fixtures/lib/example.rb +15 -0
  43. data/spec/fixtures/locales/en.yml +7 -0
  44. data/spec/fixtures/templates/index.html.slim +7 -0
  45. data/spec/fixtures/templates/layouts/main.html.slim +13 -0
  46. data/spec/fixtures/webpack-assets.json +1 -0
  47. data/spec/spec_helper.rb +31 -0
  48. data/spec/support/helper.rb +5 -0
  49. data/spec/unit/lb/project/class_methods/config_spec.rb +57 -0
  50. data/spec/unit/lb/project/class_methods/development_quest_spec.rb +39 -0
  51. data/spec/unit/lb/project/class_methods/logger_spec.rb +25 -0
  52. data/spec/unit/lb/project/class_methods/rack_env_spec.rb +39 -0
  53. data/spec/unit/lb/project/class_methods/root_for_spec.rb +28 -0
  54. data/spec/unit/lb/project/class_methods/root_spec.rb +31 -0
  55. data/spec/unit/lb/project/class_methods/setup_spec.rb +23 -0
  56. metadata +373 -0
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LB
4
+ module Project
5
+ # Version
6
+ VERSION = '0.0.1'
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LB
4
+ module Project
5
+ # Base view
6
+ class View < Dry::View::Controller
7
+ extend LB::Project::Registry::Registration[:view]
8
+
9
+ def self.setup(view)
10
+ view.setting :paths, [LB::Project.template_path]
11
+ view.setting :layout, 'main'
12
+ end
13
+
14
+ def view_locals(options)
15
+ options
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/lb/project.rb ADDED
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'yaml'
5
+
6
+ # Web
7
+ require 'roda'
8
+ require 'roda/plugins/public'
9
+
10
+ # r18n
11
+ require 'r18n-core'
12
+
13
+ # Dry
14
+ require 'dry-types'
15
+ require 'dry-struct'
16
+ require 'dry-view'
17
+ require 'dry-initializer'
18
+
19
+ # Version
20
+ require 'lb/project/version'
21
+
22
+ # Custom Types
23
+ require 'lb/project/types'
24
+
25
+ # Config
26
+ require 'lb/project/config'
27
+
28
+ # LB namespace
29
+ module LB
30
+ # Project
31
+ module Project
32
+ CONFIG_NAME = 'application'
33
+ DEFAULT_RACK_ENV = 'development'
34
+
35
+ # Setup
36
+ #
37
+ # @param [File] root Path to project root
38
+ #
39
+ # @return [self]
40
+ #
41
+ # @api private
42
+ #
43
+ def self.setup(root)
44
+ @root = root
45
+
46
+ self
47
+ end
48
+
49
+ # Get root path
50
+ #
51
+ # @return [dir_name]
52
+ #
53
+ # @api private
54
+ #
55
+ def self.root
56
+ @root
57
+ end
58
+
59
+ # Get root path for file
60
+ #
61
+ # @param [File] file The file to get the root path from
62
+ # @param [File] depth The depth of the given file relative from the root
63
+ # directory
64
+ #
65
+ # @return [dir_name]
66
+ #
67
+ # @api private
68
+ #
69
+ def self.root_for(file, depth = 2)
70
+ path = File.expand_path(file)
71
+ depth.times { path = File.dirname(path) }
72
+ path
73
+ end
74
+
75
+ # Get template path
76
+ #
77
+ # @return [dir_name]
78
+ #
79
+ # @api private
80
+ #
81
+ def self.template_path
82
+ File.join(root, config.template_path)
83
+ end
84
+
85
+ # Get public path
86
+ #
87
+ # @return [dir_name]
88
+ #
89
+ # @api private
90
+ #
91
+ def self.public_path
92
+ File.join(root, config.public_path)
93
+ end
94
+
95
+ # Get main configuration
96
+ #
97
+ # @return [Config]
98
+ #
99
+ # @api private
100
+ #
101
+ def self.config
102
+ @config ||= Config.load(root, CONFIG_NAME, rack_env)
103
+ end
104
+
105
+ # Get RACK_ENV
106
+ #
107
+ # @return [String]
108
+ #
109
+ # @api private
110
+ #
111
+ def self.rack_env
112
+ @rack_env ||= ENV.fetch('RACK_ENV', DEFAULT_RACK_ENV)
113
+ end
114
+
115
+ # Check if rack_env is 'development'
116
+ #
117
+ # @return [Boolean]
118
+ #
119
+ # @api private
120
+ #
121
+ def self.development?
122
+ DEFAULT_RACK_ENV.eql? rack_env
123
+ end
124
+
125
+ def self.t(*params)
126
+ R18n.t(*params)
127
+ end
128
+
129
+ def self.logger
130
+ @logger ||= create_logger
131
+ end
132
+
133
+ def self.create_logger
134
+ logger = Logger.new(STDOUT)
135
+ logger.level = Logger::INFO
136
+ logger
137
+ end
138
+
139
+ private_class_method :create_logger
140
+ end
141
+ end
142
+
143
+ # Site
144
+ require 'lb/project/site'
145
+
146
+ # Routing
147
+ require 'lb/project/route'
148
+ require 'lb/project/app'
149
+
150
+ # Registry
151
+ require 'lb/project/registry'
152
+ require 'lb/project/registry/registration'
153
+
154
+ # Views
155
+ require 'lb/project/view'
156
+ require 'lb/project/page'
157
+
158
+ # Render
159
+ require 'lb/project/render'
data/lib/lb-project.rb ADDED
@@ -0,0 +1,5 @@
1
+ # rubocop:disable Naming/FileName
2
+ # frozen_string_literal: true
3
+
4
+ require 'lb/project'
5
+ # rubocop:enable Naming/FileName
data/rakelib/ci.rake ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Remove existing same-named tasks
4
+ %w[ci ci:metrics].each do |task|
5
+ klass = Rake::Task
6
+ klass[task].clear if klass.task_defined?(task)
7
+ end
8
+
9
+ desc 'Run all specs, metrics and mutant'
10
+ task ci: %w[ci:metrics metrics:mutant]
11
+
12
+ namespace :ci do
13
+ tasks = %w[
14
+ metrics:coverage
15
+ metrics:yardstick:verify
16
+ metrics:rubocop
17
+ metrics:flog
18
+ metrics:flay
19
+ spec:integration
20
+ ]
21
+
22
+ desc 'Run metrics (except mutant)'
23
+ task metrics: tasks
24
+ end
@@ -0,0 +1,10 @@
1
+ development: &base
2
+ base_path : ''
3
+ image_base_path: 'assets/images'
4
+ public_path: 'docs'
5
+ template_path: 'templates'
6
+ test:
7
+ <<: *base
8
+ production:
9
+ <<: *base
10
+ public_path: 'htdocs'
@@ -0,0 +1,3 @@
1
+ ---
2
+ namespace: example
3
+
@@ -0,0 +1,9 @@
1
+ #\ -p 3000 -P invalid_public_path_to_disable_shotguns_static_route
2
+ # frozen_string_literal: true
3
+
4
+ root = File.dirname(File.expand_path(__FILE__))
5
+ $LOAD_PATH << File.join(root, 'lib')
6
+
7
+ require 'example'
8
+
9
+ run Example::App.freeze.app
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Example
4
+ # Main routing entry point
5
+ class App < LB::Project::App
6
+ LB::Project::Route.setup(self)
7
+
8
+ route do |r|
9
+ r.i18n_set_locale_from(:http)
10
+
11
+ r.public
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Example
4
+ class Page
5
+ # The index page
6
+ class Index < self
7
+ setting :template, 'index'
8
+
9
+ register_page_as :index
10
+ register_view_as :index
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Example
4
+ # Base page
5
+ class Page < LB::Project::Page
6
+ LB::Project::View.setup(self)
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Slim
4
+ require 'slim'
5
+
6
+ require 'lb-project'
7
+
8
+ # Example project
9
+ module Example
10
+ LB::Project.setup(LB::Project.root_for(__FILE__))
11
+ end
12
+
13
+ require 'example/app'
14
+ require 'example/page'
15
+ require 'example/page/index'
@@ -0,0 +1,7 @@
1
+ site:
2
+ title: lb-rb.org
3
+ logo: Logo
4
+
5
+ page:
6
+ index:
7
+ title: lb-rb.org
@@ -0,0 +1,7 @@
1
+ body
2
+ h1 lb-rb.org
3
+
4
+ #content
5
+ p
6
+ a href='https://github.com/lb-rb'
7
+ | Visit us at GitHub
@@ -0,0 +1,13 @@
1
+ doctype html
2
+ html
3
+ head
4
+ meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"
5
+ meta charset="utf-8"
6
+ meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"
7
+
8
+ title = "#{_context.page.title} - #{site.t.site.title}"
9
+
10
+ link href="#{site.css_for('main')}" rel='stylesheet' type='text/css'
11
+ script src="#{site.js_for('main')}"
12
+
13
+ == yield
@@ -0,0 +1 @@
1
+ {"main":{"js":"assets/javascripts/main.bundle.js","css":"assets/stylesheets/main.bundle.css"}}
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ if ENV['COVERAGE'] == 'true'
5
+ require 'simplecov'
6
+
7
+ SimpleCov.start do
8
+ command_name 'spec:unit'
9
+
10
+ add_filter 'config'
11
+ add_filter 'spec'
12
+
13
+ minimum_coverage 100
14
+ end
15
+ end
16
+
17
+ $LOAD_PATH << 'lib'
18
+
19
+ require 'lb-project'
20
+
21
+ require 'devtools/spec_helper'
22
+
23
+ # require spec support files and shared behavior
24
+ Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
25
+ require file
26
+ end
27
+
28
+ RSpec.configure do |config|
29
+ config.include(SpecHelper)
30
+ config.mock_framework = :rspec
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Spec Helper
4
+ module SpecHelper
5
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.config' do
6
+ subject { object.config }
7
+
8
+ let(:object) { described_class }
9
+
10
+ let(:default_hash) do
11
+ {
12
+ base_path: '',
13
+ image_base_path: 'assets/images',
14
+ public_path: 'docs',
15
+ template_path: 'templates'
16
+ }
17
+ end
18
+
19
+ let(:default) { LB::Project::Config.new(default_hash) }
20
+
21
+ let(:env) { 'RACK_ENV' }
22
+
23
+ before(:each) do
24
+ root = LB::Project.root_for(__FILE__, 6)
25
+ LB::Project.setup(File.join(root, 'spec/fixtures'))
26
+ end
27
+
28
+ after(:each) do
29
+ object.remove_instance_variable(:@rack_env)
30
+ object.remove_instance_variable(:@config)
31
+ object.remove_instance_variable(:@root)
32
+ end
33
+
34
+ context 'without RACK_ENV' do
35
+ it 'should return default config' do
36
+ expect(subject).to eql(default)
37
+ end
38
+ end
39
+
40
+ context 'with RACK_ENV=production' do
41
+ let(:production_hash) { default_hash.merge(public_path: 'htdocs') }
42
+ let(:production) { LB::Project::Config.new(production_hash) }
43
+ let(:rack_env) { 'production' }
44
+
45
+ before(:each) do
46
+ ENV[env] = rack_env
47
+ end
48
+
49
+ after(:each) do
50
+ ENV.delete(env)
51
+ end
52
+
53
+ it 'should return production config' do
54
+ expect(subject).to eql(production)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.development?' do
6
+ subject { object.development? }
7
+
8
+ let(:object) { described_class }
9
+
10
+ let(:default) { 'development' }
11
+
12
+ let(:env) { 'RACK_ENV' }
13
+
14
+ after(:each) do
15
+ object.remove_instance_variable(:@rack_env)
16
+ end
17
+
18
+ context 'without RACK_ENV' do
19
+ it 'should return true' do
20
+ expect(subject).to be true
21
+ end
22
+ end
23
+
24
+ context 'with RACK_ENV=production' do
25
+ let(:rack_env) { 'production' }
26
+
27
+ before(:each) do
28
+ ENV[env] = rack_env
29
+ end
30
+
31
+ after(:each) do
32
+ ENV.delete(env)
33
+ end
34
+
35
+ it 'should return false' do
36
+ expect(subject).to be false
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.logger' do
6
+ subject { object.logger }
7
+
8
+ let(:object) { described_class }
9
+
10
+ let(:expected_level) { Logger::INFO }
11
+
12
+ let(:expected_type) { Logger }
13
+
14
+ after(:each) do
15
+ object.remove_instance_variable(:@logger)
16
+ end
17
+
18
+ it 'should return logger of type Logger' do
19
+ expect(subject.class).to be(expected_type)
20
+ end
21
+
22
+ it 'should set log level to info' do
23
+ expect(subject.level).to be(expected_level)
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.rack_env' do
6
+ subject { object.rack_env }
7
+
8
+ let(:object) { described_class }
9
+
10
+ let(:default) { 'development' }
11
+
12
+ let(:env) { 'RACK_ENV' }
13
+
14
+ after(:each) do
15
+ object.remove_instance_variable(:@rack_env)
16
+ end
17
+
18
+ context 'without RACK_ENV' do
19
+ it 'should return default RACK_ENV' do
20
+ expect(subject).to eql(default)
21
+ end
22
+ end
23
+
24
+ context 'with RACK_ENV=production' do
25
+ let(:rack_env) { 'production' }
26
+
27
+ before(:each) do
28
+ ENV[env] = rack_env
29
+ end
30
+
31
+ after(:each) do
32
+ ENV.delete(env)
33
+ end
34
+
35
+ it 'should return production' do
36
+ expect(subject).to eql(rack_env)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.root_for' do
6
+ subject { object.root_for(*args) }
7
+
8
+ let(:args) { [file] }
9
+ let(:object) { described_class }
10
+ let(:file) { __FILE__ }
11
+
12
+ let(:expected) { File.dirname(File.dirname(File.expand_path(file))) }
13
+
14
+ it 'should equal the absolute parent path (two directory levels up)' do
15
+ expect(subject).to eql(expected)
16
+ end
17
+
18
+ context 'with depth of 3' do
19
+ let(:args) { [file, 3] }
20
+ let(:expected) do
21
+ File.dirname(File.dirname(File.dirname(File.expand_path(file))))
22
+ end
23
+
24
+ it 'should equal the absolute parent path (two directory levels up)' do
25
+ expect(subject).to eql(expected)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.root' do
6
+ subject { object.root }
7
+
8
+ let(:object) { described_class }
9
+
10
+ context 'without setup' do
11
+ it 'should return nil' do
12
+ expect(subject).to be_nil
13
+ end
14
+ end
15
+
16
+ context 'without setup' do
17
+ let(:root) { double(:root) }
18
+
19
+ before(:each) do
20
+ object.setup(root)
21
+ end
22
+
23
+ after(:each) do
24
+ object.remove_instance_variable(:@root)
25
+ end
26
+
27
+ it 'should return nil' do
28
+ expect(subject).to be(root)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LB::Project, '.setup' do
6
+ subject { object.setup(root) }
7
+
8
+ let(:root) { double(:root) }
9
+ let(:object) { described_class }
10
+
11
+ after(:each) do
12
+ object.remove_instance_variable(:@root)
13
+ end
14
+
15
+ it 'should return self' do
16
+ expect(subject).to eql(object)
17
+ end
18
+
19
+ it 'should set root' do
20
+ subject
21
+ expect(object.root).to be(root)
22
+ end
23
+ end