apogee 0.2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 55c20d8b520abe0413950e3edbbae220ce1fbcdd1c8638f6db0e4036a55f7940
4
+ data.tar.gz: 333cf3e36c4ce96a5f9e8ba9d836da7f953649a063e3af874057750b7f783eb8
5
+ SHA512:
6
+ metadata.gz: b637a99eb82bc4c06f82373313cdc78e50d066f19f16b282343fa58897972b77d0d42f4f2d63df6c030802826886155343d04b9eb31f4ee80f673087406c9469
7
+ data.tar.gz: f02aa1ab7f489385890fed0e2877272ef68fb6b17431e9342a32ba287aaf9ce3fe8b43eade9a6a6969cc1114e67378d23bb64432b8aceec9df8eb48ff72726bc
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,130 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+
6
+ Style/BlockDelimiters:
7
+ Exclude:
8
+ - 'spec/**/*.rb'
9
+
10
+ Layout/MultilineMethodCallIndentation:
11
+ Enabled: true
12
+ EnforcedStyle: indented_relative_to_receiver
13
+
14
+ Layout/SpaceAroundMethodCallOperator:
15
+ Enabled: true
16
+
17
+ Lint/RaiseException:
18
+ Enabled: true
19
+
20
+ Lint/StructNewOverride:
21
+ Enabled: true
22
+
23
+ Style/ExponentialNotation:
24
+ Enabled: false
25
+
26
+ Style/HashEachMethods:
27
+ Enabled: true
28
+
29
+ Style/HashTransformKeys:
30
+ Enabled: true
31
+
32
+ Style/HashTransformValues:
33
+ Enabled: true
34
+
35
+ Metrics/BlockLength:
36
+ Exclude:
37
+ - 'spec/**'
38
+ - 'spec/**/*'
39
+
40
+ RSpec/ExampleLength:
41
+ Max: 10
42
+ Exclude:
43
+ - 'spec/**/*.rb'
44
+
45
+ RSpec/MessageSpies:
46
+ EnforcedStyle: receive
47
+
48
+ RSpec/MultipleExpectations:
49
+ Max: 5
50
+
51
+ Lint/DuplicateBranch:
52
+ Enabled: true
53
+
54
+ Lint/DuplicateRegexpCharacterClassElement:
55
+ Enabled: true
56
+
57
+ Lint/EmptyBlock:
58
+ Enabled: true
59
+
60
+ Lint/EmptyClass:
61
+ Enabled: true
62
+
63
+ Lint/NoReturnInBeginEndBlocks:
64
+ Enabled: true
65
+
66
+ Lint/ToEnumArguments:
67
+ Enabled: true
68
+
69
+ Lint/UnmodifiedReduceAccumulator:
70
+ Enabled: true
71
+
72
+ Style/ArgumentsForwarding:
73
+ Enabled: false
74
+
75
+ Style/CollectionCompact:
76
+ Enabled: true
77
+
78
+ Style/DocumentDynamicEvalDefinition:
79
+ Enabled: true
80
+
81
+ Style/NegatedIfElseCondition:
82
+ Enabled: true
83
+
84
+ Style/NilLambda:
85
+ Enabled: true
86
+
87
+ Style/SwapValues:
88
+ Enabled: true
89
+
90
+ Performance/AncestorsInclude:
91
+ Enabled: true
92
+
93
+ Performance/ArraySemiInfiniteRangeSlice:
94
+ Enabled: true
95
+
96
+ Performance/BigDecimalWithNumericArgument:
97
+ Enabled: true
98
+
99
+ Performance/BlockGivenWithExplicitBlock:
100
+ Enabled: true
101
+
102
+ Performance/CollectionLiteralInLoop:
103
+ Enabled: true
104
+
105
+ Performance/ConstantRegexp:
106
+ Enabled: true
107
+
108
+ Performance/MethodObjectAsBlock:
109
+ Enabled: true
110
+
111
+ Performance/RedundantSortBlock:
112
+ Enabled: true
113
+
114
+ Performance/RedundantStringChars:
115
+ Enabled: true
116
+
117
+ Performance/ReverseFirst:
118
+ Enabled: true
119
+
120
+ Performance/SortReverse:
121
+ Enabled: true
122
+
123
+ Performance/Squeeze:
124
+ Enabled: true
125
+
126
+ Performance/StringInclude:
127
+ Enabled: true
128
+
129
+ Performance/Sum:
130
+ Enabled: true
@@ -0,0 +1,7 @@
1
+ no_browser: true
2
+ path: '/tmp/rubycritic'
3
+ formats:
4
+ - console
5
+ minimum_score: 90
6
+ paths:
7
+ - 'lib/'
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.6
6
+ before_install: gem install bundler -v 2.1.4
File without changes
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at brian@disjunct.io. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rake'
6
+ gem 'thor'
7
+
8
+ group :development do
9
+ gem 'rubocop'
10
+ gem 'rubocop-performance'
11
+ gem 'rubocop-rake'
12
+ gem 'rubocop-rspec'
13
+ gem 'rubycritic'
14
+ end
15
+
16
+ group :test do
17
+ gem 'simplecov'
18
+ end
19
+
20
+ group :development, :test do
21
+ gem 'byebug'
22
+ gem 'rspec', '~> 3.0'
23
+ end
24
+
25
+ gemspec
@@ -0,0 +1,131 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ apogee (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ ast (2.4.1)
12
+ axiom-types (0.1.1)
13
+ descendants_tracker (~> 0.0.4)
14
+ ice_nine (~> 0.11.0)
15
+ thread_safe (~> 0.3, >= 0.3.1)
16
+ byebug (11.1.3)
17
+ coercible (1.0.0)
18
+ descendants_tracker (~> 0.0.1)
19
+ descendants_tracker (0.0.4)
20
+ thread_safe (~> 0.3, >= 0.3.1)
21
+ diff-lcs (1.4.4)
22
+ docile (1.3.2)
23
+ equalizer (0.0.11)
24
+ erubis (2.7.0)
25
+ flay (2.12.1)
26
+ erubis (~> 2.7.0)
27
+ path_expander (~> 1.0)
28
+ ruby_parser (~> 3.0)
29
+ sexp_processor (~> 4.0)
30
+ flog (4.6.4)
31
+ path_expander (~> 1.0)
32
+ ruby_parser (~> 3.1, > 3.1.0)
33
+ sexp_processor (~> 4.8)
34
+ ice_nine (0.11.2)
35
+ kwalify (0.7.2)
36
+ launchy (2.5.0)
37
+ addressable (~> 2.7)
38
+ parallel (1.20.0)
39
+ parser (2.7.2.0)
40
+ ast (~> 2.4.1)
41
+ path_expander (1.1.0)
42
+ psych (3.2.0)
43
+ public_suffix (4.0.6)
44
+ rainbow (3.0.0)
45
+ rake (12.3.3)
46
+ reek (6.0.2)
47
+ kwalify (~> 0.7.0)
48
+ parser (>= 2.5.0.0, < 2.8, != 2.5.1.1)
49
+ psych (~> 3.1)
50
+ rainbow (>= 2.0, < 4.0)
51
+ regexp_parser (1.8.2)
52
+ rexml (3.2.4)
53
+ rspec (3.10.0)
54
+ rspec-core (~> 3.10.0)
55
+ rspec-expectations (~> 3.10.0)
56
+ rspec-mocks (~> 3.10.0)
57
+ rspec-core (3.10.0)
58
+ rspec-support (~> 3.10.0)
59
+ rspec-expectations (3.10.0)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.10.0)
62
+ rspec-mocks (3.10.0)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.10.0)
65
+ rspec-support (3.10.0)
66
+ rubocop (1.3.1)
67
+ parallel (~> 1.10)
68
+ parser (>= 2.7.1.5)
69
+ rainbow (>= 2.2.2, < 4.0)
70
+ regexp_parser (>= 1.8)
71
+ rexml
72
+ rubocop-ast (>= 1.1.1)
73
+ ruby-progressbar (~> 1.7)
74
+ unicode-display_width (>= 1.4.0, < 2.0)
75
+ rubocop-ast (1.1.1)
76
+ parser (>= 2.7.1.5)
77
+ rubocop-performance (1.9.0)
78
+ rubocop (>= 0.90.0, < 2.0)
79
+ rubocop-ast (>= 0.4.0)
80
+ rubocop-rake (0.5.1)
81
+ rubocop
82
+ rubocop-rspec (2.0.0)
83
+ rubocop (~> 1.0)
84
+ rubocop-ast (>= 1.1.0)
85
+ ruby-progressbar (1.10.1)
86
+ ruby_parser (3.15.0)
87
+ sexp_processor (~> 4.9)
88
+ rubycritic (4.5.2)
89
+ flay (~> 2.8)
90
+ flog (~> 4.4)
91
+ launchy (>= 2.0.0)
92
+ parser (>= 2.6.0)
93
+ rainbow (~> 3.0)
94
+ reek (~> 6.0, < 7.0)
95
+ ruby_parser (~> 3.8)
96
+ simplecov (>= 0.17.0)
97
+ tty-which (~> 0.4.0)
98
+ virtus (~> 1.0)
99
+ sexp_processor (4.15.1)
100
+ simplecov (0.19.1)
101
+ docile (~> 1.1)
102
+ simplecov-html (~> 0.11)
103
+ simplecov-html (0.12.3)
104
+ thor (1.0.1)
105
+ thread_safe (0.3.6)
106
+ tty-which (0.4.2)
107
+ unicode-display_width (1.7.0)
108
+ virtus (1.0.5)
109
+ axiom-types (~> 0.1)
110
+ coercible (~> 1.0)
111
+ descendants_tracker (~> 0.0, >= 0.0.3)
112
+ equalizer (~> 0.0, >= 0.0.9)
113
+
114
+ PLATFORMS
115
+ ruby
116
+
117
+ DEPENDENCIES
118
+ apogee!
119
+ byebug
120
+ rake
121
+ rspec (~> 3.0)
122
+ rubocop
123
+ rubocop-performance
124
+ rubocop-rake
125
+ rubocop-rspec
126
+ rubycritic
127
+ simplecov
128
+ thor
129
+
130
+ BUNDLED WITH
131
+ 2.1.4
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Brian Davies
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,156 @@
1
+ # Apogee
2
+
3
+ Apogee is a no-frill, no-configuration static site generator for when you need
4
+ to build a simple site fast and don't want to mess with more complicated
5
+ frameworks.
6
+
7
+
8
+ ## Installation
9
+ Install it with:
10
+
11
+ ```bash
12
+ $ gem install apogee
13
+ ```
14
+
15
+
16
+ ## Usage
17
+
18
+ ### Create a site
19
+ You may create a new site from the command line with:
20
+ ```bash
21
+ $ apogee new site_name
22
+ ```
23
+
24
+ Your site is now fully configured and ready to use:
25
+ ```
26
+ site_name
27
+ ├── dist <---------------- Rendered final site
28
+ ├── Gemfile
29
+ ├── Guardfile
30
+ ├── README.md
31
+ └── src <---------------- Working files
32
+ ├── css
33
+ │   └── styles.css
34
+ ├── images
35
+ ├── javascript
36
+ │   └── script.js
37
+ ├── layouts
38
+ │   └── default.html
39
+ └── pages
40
+ └── index.html
41
+ ```
42
+
43
+
44
+ ### Build the final deployable site from your source files:
45
+ Render your deployable site using:
46
+ ```bash
47
+ $ apogee build
48
+ ```
49
+
50
+ Pages are rendered inside their respective layouts.
51
+
52
+ CSS and Javascript assets are combined and linked inside a layout.
53
+
54
+
55
+ ### Tokens
56
+ Tokens can be used to specify a page's layout, as well as pass information from a page to its layout.
57
+
58
+
59
+ Apogee manages 4 tokens for you:
60
+ * `layout`: Specifies which layout file to use with a given page
61
+ * `css_bundle`: Specifies location in the layout to link the css bundle
62
+ * `js_bundle`: Specifies location in the layout to link the js bundle
63
+ * `page_content`: Specifies location in the layout to insert the page content
64
+
65
+ To pass additional information from a page to its layout, you may define arbitrary tokens
66
+ in pages using a YAML format HTML comment.
67
+
68
+
69
+ Here is an example setup:
70
+
71
+ `src/pages/index.html`:
72
+ ```html
73
+ <!--
74
+ layout: 'no_navigation'
75
+ title: 'Welcome to Example Site'
76
+ -->
77
+
78
+ <h1>Hello, World<h2>
79
+ ```
80
+
81
+
82
+ `src/layouts/no_navigation.html`:
83
+ ```html
84
+ <html>
85
+ <head>
86
+ <title>{{title}}</title>
87
+
88
+ {{js_bundle}}
89
+ {{css_bundle}}
90
+ </head>
91
+ <body>
92
+ <div>{{page_content}}</div>
93
+ </body>
94
+ </html>
95
+ ```
96
+
97
+
98
+ This would yield the following page when the site is built:
99
+
100
+ `dist/index.html`:
101
+ ```html
102
+ <html>
103
+ <head>
104
+ <title>Welcome to Example Site</title>
105
+
106
+ <script src="script.js"></script>
107
+ <link rel="stylesheet" href="styles.css">
108
+ </head>
109
+ <body>
110
+ <div><h1>Hello, World<h2></div>
111
+ </body>
112
+ </html>
113
+ ```
114
+
115
+ ### Using Guard to improve workflow
116
+ Sites created with Apogee come configured to work with [Guard](https://github.com/guard/guard)
117
+ for automatic building and browser reloading.
118
+
119
+ The new site [README.md](https://github.com/bdavi/apogee/blob/main/lib/apogee/templates/new_site/README.md)
120
+ includes more detail on how to use Guard to speed up site creation workflow.
121
+
122
+
123
+ ## Development
124
+
125
+ After you checkout the repo, run `bundle install` to install dependencies.
126
+
127
+ Then, you can run `bundle exec rspec` to run the tests.
128
+
129
+ Apogee uses a variety of tools to maintain code correctness, consistency
130
+ and quality. Before merging new code the expectation is:
131
+ * All specs pass
132
+ * 90% test coverage
133
+ * Adherence to the style guide
134
+ * Minimum 90% quality score on all code files
135
+
136
+ To verify the application run:
137
+ ```
138
+ $ bin/verify
139
+ ```
140
+
141
+ For more information about how to work with gems in development, see [https://guides.rubygems.org/make-your-own-gem/](https://guides.rubygems.org/make-your-own-gem/).
142
+
143
+
144
+ ## Contributing
145
+
146
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bdavi/apogee. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/bdavi/apogee/blob/master/CODE_OF_CONDUCT.md).
147
+
148
+
149
+ ## License
150
+
151
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
152
+
153
+
154
+ ## Code of Conduct
155
+
156
+ Everyone interacting in the Apogee project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/bdavi/apogee/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/apogee/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'apogee'
7
+ spec.version = Apogee::VERSION
8
+ spec.authors = ['Brian Davies']
9
+ spec.email = ['brian@disjunct.io']
10
+
11
+ spec.summary = 'Dead simple static sites'
12
+ spec.description = "Sometimes you don't need the complexity of a full web framework."
13
+ spec.homepage = 'https://github.com/bdavi/apogee'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/bdavi/apogee'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/bdavi/apogee/blob/main/CODE_OF_CONDUCT.md'
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = 'exe'
27
+ spec.executables << 'apogee'
28
+ spec.require_paths = ['lib']
29
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'apogee'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+
3
+ gem uninstall apogee
4
+ gem build apogee.gemspec
5
+ gem install apogee-0.1.0.gem
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ def system!(*args)
6
+ system(*args) || abort("\n== Command #{args} failed ==")
7
+ end
8
+
9
+ system! 'bundle exec rspec'
10
+ system! 'bundle exec rubocop'
11
+ system! 'bundle exec rubycritic'
12
+
13
+ puts "\nVerification Successful"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'apogee'
6
+
7
+ Apogee::CLI.start(ARGV)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apogee/builder'
4
+ require 'apogee/builder_helpers'
5
+ require 'apogee/cli'
6
+ require 'apogee/css_processor'
7
+ require 'apogee/file_helpers'
8
+ require 'apogee/image_processor'
9
+ require 'apogee/installer'
10
+ require 'apogee/js_processor'
11
+ require 'apogee/page_processor'
12
+ require 'apogee/page_renderer'
13
+ require 'apogee/version'
14
+
15
+ module Apogee
16
+ class Error < StandardError; end
17
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'builder_helpers'
4
+
5
+ module Apogee
6
+ # Builds site for distribution using the specified processors
7
+ class Builder
8
+ attr_reader :processors
9
+
10
+ def initialize(
11
+ processors: [
12
+ ImageProcessor.new,
13
+ CSSProcessor.new,
14
+ JSProcessor.new,
15
+ PageProcessor.new
16
+ ]
17
+ )
18
+ @processors = processors
19
+ end
20
+
21
+ def build
22
+ prepare_dist_dir
23
+ processors.each(&:process)
24
+ end
25
+
26
+ def prepare_dist_dir
27
+ FileUtils.rm_rf('dist')
28
+ FileUtils.mkdir('dist')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apogee
4
+ # Helpers for classes processing the build
5
+ module BuilderHelpers
6
+ def images?
7
+ image_paths.any?
8
+ end
9
+
10
+ def image_paths
11
+ Dir[File.join('src', 'images', '**', '*.*')]
12
+ end
13
+
14
+ def css?
15
+ css_paths.any?
16
+ end
17
+
18
+ def css_paths
19
+ Dir[File.join('src', 'css', '**', '*.css')]
20
+ end
21
+
22
+ def js?
23
+ js_paths.any?
24
+ end
25
+
26
+ def js_paths
27
+ Dir[File.join('src', 'javascript', '**', '*.js')]
28
+ end
29
+
30
+ def layout(name)
31
+ IO.read(File.join('src', 'layouts', "#{name}.html"))
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Apogee
6
+ # Command line interface
7
+ class CLI < Thor
8
+ package_name 'apogee'
9
+
10
+ desc 'new SITE_NAME', 'Creates a new empty site.'
11
+ long_desc <<~LONGDESC
12
+ `apogee new SITE_NAME` will create a new empty site with the specified name.
13
+
14
+ SITE_NAME must be a valid as a directory name and contain only letters, numbers, dashes and underscores.
15
+
16
+ Example:
17
+ \x5> apogee new site_name
18
+ LONGDESC
19
+ def new(site_name)
20
+ Installer.new(site_name).install
21
+ end
22
+
23
+ desc 'build', 'Builds the site for preview or distribution'
24
+ long_desc <<~LONGDESC
25
+ `apogee build` will builds the site for preview or distribution.
26
+
27
+ WARNING: THIS WILL OVERWRITE THE CONTENTS OF THE `/dist` DIRECTORY.
28
+
29
+ The working files in `/src` are compiled into `/dist`.
30
+
31
+ Example:
32
+ \x5> apogee build
33
+ LONGDESC
34
+ def build
35
+ Builder.new.build
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'builder_helpers'
4
+
5
+ module Apogee
6
+ # Processes site css for distribution
7
+ class CSSProcessor
8
+ include BuilderHelpers
9
+
10
+ def process
11
+ return unless css?
12
+
13
+ IO.write(out_path, processed_styles)
14
+ end
15
+
16
+ private
17
+
18
+ def processed_styles
19
+ css_paths.map { |path| IO.read(path) }.join("\n")
20
+ end
21
+
22
+ def out_path
23
+ File.join('dist', 'styles.css')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apogee
4
+ # Helpers related to files and file manipulation
5
+ module FileHelpers
6
+ def self.file_gsub(path, pattern, replacement)
7
+ IO.write(
8
+ path,
9
+ IO.read(path).gsub(pattern, replacement)
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'builder_helpers'
4
+
5
+ module Apogee
6
+ # Processes site images for distribution
7
+ class ImageProcessor
8
+ include Apogee::BuilderHelpers
9
+
10
+ def process
11
+ return unless images?
12
+
13
+ FileUtils.cp_r(File.join('src', 'images'), File.join('dist', 'images'))
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'apogee'
5
+
6
+ module Apogee
7
+ # Creates an empty apogee site
8
+ class Installer
9
+ VALID_FILENAME_PATTERN = /\A[A-Za-z0-9\-_]+\z/.freeze
10
+ FILES_WITH_SITE_NAME = [
11
+ 'README.md',
12
+ File.join('src', 'pages', 'index.html')
13
+ ].freeze
14
+
15
+ attr_reader :site_name, :destination_root_dir
16
+
17
+ def initialize(site_name, destination_root_dir: Dir.pwd)
18
+ @site_name = site_name
19
+ @destination_root_dir = destination_root_dir
20
+ validate
21
+ end
22
+
23
+ def install
24
+ copy_template_files
25
+ gsub_site_name
26
+ bundle_dependencies
27
+ end
28
+
29
+ def validate
30
+ validate_destination_dir
31
+ validate_site_name
32
+ end
33
+
34
+ def copy_template_files
35
+ FileUtils.mkdir_p(destination_root_dir) unless Dir.exist?(destination_root_dir)
36
+ FileUtils.cp_r(template_dir, destination_dir)
37
+ end
38
+
39
+ def gsub_site_name
40
+ FILES_WITH_SITE_NAME.each do |file|
41
+ path = File.join(destination_dir, file)
42
+ FileHelpers.file_gsub(path, '{{site_name}}', site_name)
43
+ end
44
+ end
45
+
46
+ def bundle_dependencies
47
+ Kernel.system "cd #{destination_dir}"
48
+ Kernel.system 'bundle install'
49
+ end
50
+
51
+ private
52
+
53
+ def destination_dir
54
+ File.join(destination_root_dir, site_name)
55
+ end
56
+
57
+ def template_dir
58
+ File.join(File.dirname(__FILE__), 'templates', 'new_site')
59
+ end
60
+
61
+ def validate_destination_dir
62
+ return unless Dir.exist?(destination_dir)
63
+
64
+ raise InstallDirectoryAlreadyExistsError, "#{destination_dir} already exists."
65
+ end
66
+
67
+ def validate_site_name
68
+ return if site_name.match?(VALID_FILENAME_PATTERN)
69
+
70
+ raise ApplicationNameInvalidError, \
71
+ "#{site_name} is not a valid site name. Please use only " \
72
+ 'letters, numbers, underscores and dashes in the application name'
73
+ end
74
+
75
+ class InstallDirectoryAlreadyExistsError < StandardError; end
76
+ class ApplicationNameInvalidError < StandardError; end
77
+ end
78
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'builder_helpers'
4
+
5
+ module Apogee
6
+ # Processes site js for distribution
7
+ class JSProcessor
8
+ include BuilderHelpers
9
+
10
+ def process
11
+ return unless js?
12
+
13
+ IO.write(out_path, processed_js)
14
+ end
15
+
16
+ private
17
+
18
+ def processed_js
19
+ js_paths.map { |path| IO.read(path) }.join("\n")
20
+ end
21
+
22
+ def out_path
23
+ File.join('dist', 'script.js')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'builder_helpers'
4
+
5
+ module Apogee
6
+ # Processes site pages for distribution
7
+ class PageProcessor
8
+ attr_reader :renderer
9
+
10
+ def initialize(renderer: PageRenderer.new)
11
+ @renderer = renderer
12
+ end
13
+
14
+ def process
15
+ copy_src_pages_to_dist
16
+
17
+ dist_file_paths.each do |path|
18
+ IO.write(
19
+ path,
20
+ renderer.render(IO.read(path))
21
+ )
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def copy_src_pages_to_dist
28
+ FileUtils.cp_r(File.join('src', 'pages', '.'), 'dist')
29
+ end
30
+
31
+ def dist_file_paths
32
+ Dir[File.join('dist', '**', '*.html')]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative 'builder_helpers'
5
+
6
+ module Apogee
7
+ # Processes site pages for distribution
8
+ class PageRenderer
9
+ include BuilderHelpers
10
+
11
+ TOKEN_COMMENT_PATTERN = /\A<!--[^>]*-->/.freeze
12
+
13
+ attr_reader :page_content
14
+
15
+ def render(page_content)
16
+ @page_content = page_content
17
+
18
+ tokens.inject(layout_content) do |rendered, (name, value)|
19
+ rendered.gsub("{{#{name}}}", value)
20
+ end
21
+ end
22
+
23
+ def layout_content
24
+ layout(tokens['layout'])
25
+ end
26
+
27
+ def tokens
28
+ automatic_tokens.merge(parsed_tokens)
29
+ end
30
+
31
+ def automatic_tokens
32
+ {
33
+ 'layout' => 'default',
34
+ 'css_bundle' => css_bundle,
35
+ 'js_bundle' => js_bundle,
36
+ 'page_content' => cleaned_page_content
37
+ }
38
+ end
39
+
40
+ def parsed_tokens
41
+ doc = page_content
42
+ .match(TOKEN_COMMENT_PATTERN)[0]
43
+ .delete_prefix('<!--')
44
+ .delete_suffix('-->')
45
+ .each_line
46
+ .map(&:strip)
47
+ .join("\n")
48
+
49
+ YAML.safe_load(doc)
50
+ rescue StandardError
51
+ {}
52
+ end
53
+
54
+ def css_bundle
55
+ return '' unless css?
56
+
57
+ '<link rel="stylesheet" href="styles.css">'
58
+ end
59
+
60
+ def js_bundle
61
+ return '' unless js?
62
+
63
+ '<script src="script.js"></script>'
64
+ end
65
+
66
+ def cleaned_page_content
67
+ page_content.gsub(TOKEN_COMMENT_PATTERN, '').strip
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'guard'
6
+ gem 'guard-livereload'
7
+ gem 'guard-yield'
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ WATCH_PATTERN = %r{^src/.*}.freeze
4
+
5
+ run_build = proc { system('apogee build') }
6
+
7
+ guard :yield, { run_on_modifications: run_build } do
8
+ watch(WATCH_PATTERN)
9
+ end
10
+
11
+ guard 'livereload' do
12
+ watch(WATCH_PATTERN)
13
+ end
@@ -0,0 +1,46 @@
1
+ # {{site_name}}
2
+
3
+ ## Summary
4
+ Describe your site here
5
+
6
+
7
+ ## Setup
8
+ Install Ruby gems;
9
+ ```
10
+ bundle install
11
+ ```
12
+
13
+ Build site for first time;
14
+ ```
15
+ bundle exec apogee build
16
+ ```
17
+
18
+
19
+ ## Repo Structure
20
+ Working files are available in the `/src` directory.
21
+
22
+ Rendered files are available in the `/dist` directory.
23
+
24
+
25
+ ## Suggested development workflow
26
+ Install the LiveReload plugin/extension in your browser.
27
+
28
+ Start Guard in a terminal:
29
+ ```
30
+ bundle exec guard
31
+ ```
32
+
33
+ In your browser open `/dist/index.html`.
34
+
35
+ Connect the LiveReload plugin by clicking its icon in the browser.
36
+
37
+ Now you can edit files in the `/src` directory and the changes will be rendered
38
+ after each file save in the browser.
39
+
40
+ When you are finished with a development session, type `exit` in the guard
41
+ session to end it.
42
+
43
+
44
+ ## Apogee
45
+ More informantion about apogee available here:
46
+ [https://github.com/bdavi/apogee](https://github.com/bdavi/apogee)
@@ -0,0 +1 @@
1
+ /* Your styles go here */
@@ -0,0 +1 @@
1
+ // Your Javascript goes here
@@ -0,0 +1,19 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+
7
+ <title>{{title}}</title>
8
+
9
+ <meta name="viewport" content="width=device-width, initial-scale=1">
10
+
11
+ {{css_bundle}}
12
+ {{js_bundle}}
13
+ </head>
14
+
15
+ <body>
16
+ {{page_content}}
17
+ </body>
18
+
19
+ </html>
@@ -0,0 +1,2 @@
1
+ <h1>{{site_name}}</h1>
2
+ <p>Hello, World!</p>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apogee
4
+ VERSION = '0.2.0'
5
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apogee
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Davies
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-12-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Sometimes you don't need the complexity of a full web framework.
14
+ email:
15
+ - brian@disjunct.io
16
+ executables:
17
+ - apogee
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - ".rspec"
23
+ - ".rubocop.yml"
24
+ - ".rubycritic.yml"
25
+ - ".travis.yml"
26
+ - CHANGELOG.md
27
+ - CODE_OF_CONDUCT.md
28
+ - Gemfile
29
+ - Gemfile.lock
30
+ - LICENSE.txt
31
+ - README.md
32
+ - Rakefile
33
+ - apogee.gemspec
34
+ - bin/console
35
+ - bin/reinstall
36
+ - bin/setup
37
+ - bin/verify
38
+ - exe/apogee
39
+ - lib/apogee.rb
40
+ - lib/apogee/builder.rb
41
+ - lib/apogee/builder_helpers.rb
42
+ - lib/apogee/cli.rb
43
+ - lib/apogee/css_processor.rb
44
+ - lib/apogee/file_helpers.rb
45
+ - lib/apogee/image_processor.rb
46
+ - lib/apogee/installer.rb
47
+ - lib/apogee/js_processor.rb
48
+ - lib/apogee/page_processor.rb
49
+ - lib/apogee/page_renderer.rb
50
+ - lib/apogee/templates/new_site/Gemfile
51
+ - lib/apogee/templates/new_site/Guardfile
52
+ - lib/apogee/templates/new_site/README.md
53
+ - lib/apogee/templates/new_site/src/css/styles.css
54
+ - lib/apogee/templates/new_site/src/javascript/script.js
55
+ - lib/apogee/templates/new_site/src/layouts/default.html
56
+ - lib/apogee/templates/new_site/src/pages/index.html
57
+ - lib/apogee/version.rb
58
+ homepage: https://github.com/bdavi/apogee
59
+ licenses:
60
+ - MIT
61
+ metadata:
62
+ homepage_uri: https://github.com/bdavi/apogee
63
+ source_code_uri: https://github.com/bdavi/apogee
64
+ changelog_uri: https://github.com/bdavi/apogee/blob/main/CODE_OF_CONDUCT.md
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 2.6.0
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.0.3
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Dead simple static sites
84
+ test_files: []