geb 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +37 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE +21 -0
- data/README.md +384 -0
- data/Rakefile +21 -0
- data/bin/geb +21 -0
- data/lib/geb/cli.rb +40 -0
- data/lib/geb/commands/build.rb +59 -0
- data/lib/geb/commands/init.rb +70 -0
- data/lib/geb/commands/release.rb +54 -0
- data/lib/geb/commands/remote.rb +48 -0
- data/lib/geb/commands/server.rb +77 -0
- data/lib/geb/commands/upload.rb +48 -0
- data/lib/geb/commands/version.rb +36 -0
- data/lib/geb/config.rb +103 -0
- data/lib/geb/defaults.rb +44 -0
- data/lib/geb/git.rb +112 -0
- data/lib/geb/page.rb +217 -0
- data/lib/geb/partial.rb +150 -0
- data/lib/geb/samples/basic/assets/css/site.css +7 -0
- data/lib/geb/samples/basic/assets/images/android-chrome-192x192.png +0 -0
- data/lib/geb/samples/basic/assets/images/android-chrome-512x512.png +0 -0
- data/lib/geb/samples/basic/assets/images/apple-touch-icon.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon-16x16.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon-32x32.png +0 -0
- data/lib/geb/samples/basic/assets/images/favicon.ico +0 -0
- data/lib/geb/samples/basic/assets/images/hero.png +0 -0
- data/lib/geb/samples/basic/assets/images/og-thumb.png +0 -0
- data/lib/geb/samples/basic/assets/images/twitter-thumb.png +0 -0
- data/lib/geb/samples/basic/assets/js/site.js +5 -0
- data/lib/geb/samples/basic/geb.config.yml +70 -0
- data/lib/geb/samples/basic/index.html +11 -0
- data/lib/geb/samples/basic/page.html +11 -0
- data/lib/geb/samples/basic/shared/partials/_analytics.html +9 -0
- data/lib/geb/samples/basic/shared/partials/_footer.html +3 -0
- data/lib/geb/samples/basic/shared/partials/_global_assets.html +19 -0
- data/lib/geb/samples/basic/shared/partials/_header.html +0 -0
- data/lib/geb/samples/basic/shared/partials/_meta_tags.html +34 -0
- data/lib/geb/samples/basic/shared/templates/_blog_post.html +0 -0
- data/lib/geb/samples/basic/shared/templates/_site.html +19 -0
- data/lib/geb/samples/basic/site.webmanifest +1 -0
- data/lib/geb/samples/bootstrap_jquery/assets/css/site.css +7 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-192x192.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-512x512.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/apple-touch-icon.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-16x16.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-32x32.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/favicon.ico +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/hero.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/og-thumb.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/images/twitter-thumb.png +0 -0
- data/lib/geb/samples/bootstrap_jquery/assets/js/site.js +5 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_1.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_2.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/blog_post_3.html +35 -0
- data/lib/geb/samples/bootstrap_jquery/blog/index.html +17 -0
- data/lib/geb/samples/bootstrap_jquery/geb.config.yml +69 -0
- data/lib/geb/samples/bootstrap_jquery/index.html +11 -0
- data/lib/geb/samples/bootstrap_jquery/page.html +11 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_analytics.html +9 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_footer.html +3 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_global_assets.html +19 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_header.html +0 -0
- data/lib/geb/samples/bootstrap_jquery/shared/partials/_meta_tags.html +34 -0
- data/lib/geb/samples/bootstrap_jquery/shared/templates/_blog_post.html +0 -0
- data/lib/geb/samples/bootstrap_jquery/shared/templates/_site.html +19 -0
- data/lib/geb/samples/bootstrap_jquery/site.webmanifest +1 -0
- data/lib/geb/samples/geb.config.yml +70 -0
- data/lib/geb/server.rb +138 -0
- data/lib/geb/site/build.rb +189 -0
- data/lib/geb/site/core.rb +229 -0
- data/lib/geb/site/release.rb +70 -0
- data/lib/geb/site/remote.rb +142 -0
- data/lib/geb/site/template.rb +208 -0
- data/lib/geb/site.rb +83 -0
- data/lib/geb/template.rb +166 -0
- data/lib/geb/utilities.rb +110 -0
- data/lib/geb.rb +36 -0
- data/lib/seth.rb +50 -0
- data/sig/geb.rbs +4 -0
- data/test/api tests/test_cli.rb +200 -0
- data/test/api tests/test_config.rb +330 -0
- data/test/api tests/test_defaults.rb +62 -0
- data/test/api tests/test_git.rb +105 -0
- data/test/api tests/test_page.rb +320 -0
- data/test/api tests/test_partial.rb +152 -0
- data/test/api tests/test_server.rb +416 -0
- data/test/api tests/test_site.rb +1315 -0
- data/test/api tests/test_template.rb +249 -0
- data/test/api tests/test_utilities.rb +162 -0
- data/test/command tests/test_geb_build.rb +199 -0
- data/test/command tests/test_geb_init.rb +312 -0
- data/test/command tests/test_geb_release.rb +166 -0
- data/test/command tests/test_geb_remote.rb +66 -0
- data/test/command tests/test_geb_server.rb +122 -0
- data/test/command tests/test_geb_upload.rb +96 -0
- data/test/command tests/test_geb_version.rb +58 -0
- data/test/support/geb_api_test.rb +37 -0
- data/test/support/geb_cli_test.rb +275 -0
- data/test/support/geb_minitest_ext.rb +35 -0
- data/test/support/geb_test_helpers.rb +84 -0
- data/test/support/geb_web_server_proxy.rb +128 -0
- data/test/test_helper.rb +61 -0
- metadata +301 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Build command definition, based on Dry::CLI framework
|
4
|
+
# Builds the site, this is the core of what Geb does
|
5
|
+
#
|
6
|
+
# @title Geb - Build Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @see https://github.com/mainfram-work/geb for more information
|
12
|
+
|
13
|
+
module Geb
|
14
|
+
module CLI
|
15
|
+
module Commands
|
16
|
+
|
17
|
+
# Define build command
|
18
|
+
class Build < Dry::CLI::Command
|
19
|
+
|
20
|
+
# Command description, usage and examples
|
21
|
+
desc "Build the full site, includes pages and assets"
|
22
|
+
example [" ", "--skip_assets", "--skip_pages"]
|
23
|
+
|
24
|
+
# Define command options
|
25
|
+
option :skip_assets, type: :boolean, default: false, desc: "Skip building assets (images, css, js)"
|
26
|
+
option :skip_pages, type: :boolean, default: false, desc: "Skip building pages"
|
27
|
+
|
28
|
+
# Call method for the build command
|
29
|
+
def call(**options)
|
30
|
+
|
31
|
+
# initialise a new site and load the site from the current directory
|
32
|
+
site = Geb::Site.new
|
33
|
+
site.load(Dir.pwd)
|
34
|
+
|
35
|
+
# build the pages unless the skip_pages option is set
|
36
|
+
# it is important to build assets first as there may be pages in the assets directory
|
37
|
+
Geb.log "Skipping building pages as told." if options[:skip_pages]
|
38
|
+
site.build_pages unless options[:skip_pages]
|
39
|
+
|
40
|
+
# build the assets (images, css, js) unless the skip_assets option is set
|
41
|
+
Geb.log "Skipping building assets as told." if options[:skip_assets]
|
42
|
+
site.build_assets unless options[:skip_assets]
|
43
|
+
|
44
|
+
# put a smartarse message to the console if both options are set
|
45
|
+
Geb.log "You told me to skip everything, so I did." if options[:skip_assets] && options[:skip_pages]
|
46
|
+
|
47
|
+
rescue Geb::Error => e
|
48
|
+
|
49
|
+
# print error message
|
50
|
+
puts
|
51
|
+
warn e.message
|
52
|
+
|
53
|
+
end # def call
|
54
|
+
|
55
|
+
end # class Build < Dry::CLI::Command
|
56
|
+
|
57
|
+
end # module Commands
|
58
|
+
end # module CLI
|
59
|
+
end # module Geb
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Init command definition, based on Dry::CLI framework
|
4
|
+
# Initializes the site, creates a basic folder structure and git repository
|
5
|
+
#
|
6
|
+
# @title Geb - Init Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @see https://github.com/mainfram-work/geb for more information
|
12
|
+
|
13
|
+
# include the required libraries
|
14
|
+
require 'fileutils'
|
15
|
+
|
16
|
+
module Geb
|
17
|
+
module CLI
|
18
|
+
module Commands
|
19
|
+
|
20
|
+
# define init command
|
21
|
+
class Init < Dry::CLI::Command
|
22
|
+
|
23
|
+
# command description, usage and examples
|
24
|
+
desc "Initialise geb site, creates folder locations, git repository and initial file structures"
|
25
|
+
example ["new_site ", "new_site [options]", "new_site --skip_template --skip_git"]
|
26
|
+
|
27
|
+
# define project name command argument
|
28
|
+
argument :site_path, type: :string, required: true, desc: "Path to the site folder / site name"
|
29
|
+
|
30
|
+
# define command options
|
31
|
+
option :template, type: :string, required: false, desc: "Template site, either a path to a folder or one of the following: #{Geb::Defaults::AVAILABLE_TEMPLATES.join(", ")}. Default: #{Geb::Defaults::AVAILABLE_TEMPLATES.first}"
|
32
|
+
option :skip_template, type: :boolean, default: false, desc: "Skip generating a site from template, ignores the template option."
|
33
|
+
option :skip_git, type: :boolean, default: false, desc: "Skip initialising git repository"
|
34
|
+
option :force, type: :boolean, default: false, desc: "Force overwrite of existing files and git repository. Use with caution."
|
35
|
+
|
36
|
+
# call method for the init command
|
37
|
+
def call(site_path:, **options)
|
38
|
+
|
39
|
+
# initialize a new site object, this does all sorts of validations and checks, raises errors if something is wrong
|
40
|
+
new_site = Geb::Site.new
|
41
|
+
|
42
|
+
# validate the site
|
43
|
+
new_site.validate(site_path, options[:template], options[:skip_template], options[:force])
|
44
|
+
|
45
|
+
# validate proposed git repository in the site path if we are not skipping git, will raise error if git situation is unacceptable
|
46
|
+
Geb.log "Skipping git repository validation as told." if options[:skip_git]
|
47
|
+
Geb::Git.validate_git_repo(site_path) unless options[:skip_git]
|
48
|
+
|
49
|
+
# create the site folder and populate it with the template if we are not skipping the whole process
|
50
|
+
new_site.create
|
51
|
+
|
52
|
+
# create the git repository if we are not skipping git
|
53
|
+
Geb.log "Skipping git repository creation as told." if options[:skip_git]
|
54
|
+
Geb::Git.create_git_repo(site_path) unless options[:skip_git]
|
55
|
+
|
56
|
+
rescue Geb::Error => e
|
57
|
+
|
58
|
+
# print error message
|
59
|
+
puts
|
60
|
+
warn e.message
|
61
|
+
|
62
|
+
end # def call
|
63
|
+
|
64
|
+
# ::: Methods ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
65
|
+
|
66
|
+
end # class Init < Dry::CLI::Command
|
67
|
+
|
68
|
+
end # module Commands
|
69
|
+
end # module CLI
|
70
|
+
end # module Geb
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Release command definition, based on Dry::CLI framework
|
4
|
+
# Builds the site into the release directory with optional template archive
|
5
|
+
#
|
6
|
+
# @title Geb - Release Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @todo Consider some option or check to see if the release would override previous release --with_template
|
12
|
+
#
|
13
|
+
# @see https://github.com/mainfram-work/geb for more information
|
14
|
+
|
15
|
+
module Geb
|
16
|
+
module CLI
|
17
|
+
module Commands
|
18
|
+
|
19
|
+
# Define release command
|
20
|
+
class Release < Dry::CLI::Command
|
21
|
+
|
22
|
+
# Command description, usage and examples
|
23
|
+
desc "Builds the release version of the site (pages and assets)"
|
24
|
+
example [" ", "--with_template"]
|
25
|
+
|
26
|
+
# Define command options
|
27
|
+
option :with_template, type: :boolean, default: false, desc: "Build the release site with a template archive so you can share it."
|
28
|
+
|
29
|
+
# Call method for the release command
|
30
|
+
def call(**options)
|
31
|
+
|
32
|
+
# initialise a new site and load the site from the current directory
|
33
|
+
site = Geb::Site.new
|
34
|
+
site.load(Dir.pwd)
|
35
|
+
|
36
|
+
# create a new release for the site
|
37
|
+
site.release()
|
38
|
+
|
39
|
+
# bundle the site with a template archive if the with_template option is set
|
40
|
+
site.bundle_template() if options[:with_template]
|
41
|
+
|
42
|
+
rescue Geb::Error => e
|
43
|
+
|
44
|
+
# print error message
|
45
|
+
puts
|
46
|
+
warn e.message
|
47
|
+
|
48
|
+
end # def call
|
49
|
+
|
50
|
+
end # class Release < Dry::CLI::Command
|
51
|
+
|
52
|
+
end # module Commands
|
53
|
+
end # module CLI
|
54
|
+
end # module Geb
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Remote command definition, based on Dry::CLI framework
|
4
|
+
# Just a proxy for the ssh command
|
5
|
+
#
|
6
|
+
# @title Geb - Remote Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @see https://github.com/mainfram-work/geb for more information
|
12
|
+
|
13
|
+
module Geb
|
14
|
+
module CLI
|
15
|
+
module Commands
|
16
|
+
|
17
|
+
# Define remote command
|
18
|
+
class Remote < Dry::CLI::Command
|
19
|
+
|
20
|
+
# Command description, usage and examples
|
21
|
+
desc "Launch remote ssh session using the config file settings"
|
22
|
+
example [" "]
|
23
|
+
|
24
|
+
# Define command options
|
25
|
+
|
26
|
+
# Call method for the remote command
|
27
|
+
def call(*)
|
28
|
+
|
29
|
+
# initialise a new site and load the site from the current directory
|
30
|
+
site = Geb::Site.new
|
31
|
+
site.load(Dir.pwd)
|
32
|
+
|
33
|
+
# launch the remote session
|
34
|
+
site.launch_remote()
|
35
|
+
|
36
|
+
rescue Geb::Error => e
|
37
|
+
|
38
|
+
# print error message
|
39
|
+
puts
|
40
|
+
warn e.message
|
41
|
+
|
42
|
+
end # def call
|
43
|
+
|
44
|
+
end # class Remote < Dry::CLI::Command
|
45
|
+
|
46
|
+
end # module Commands
|
47
|
+
end # module CLI
|
48
|
+
end # module Geb
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Build command definition, based on Dry::CLI framework
|
4
|
+
# Run a webrick http server to view the site output, it optionally monitors
|
5
|
+
# for file changes and rebuilds the site when a file changes.
|
6
|
+
#
|
7
|
+
# @title Geb - Remote Command
|
8
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
9
|
+
# @copyright 2024 Edin Mustajbegovic
|
10
|
+
# @license MIT
|
11
|
+
#
|
12
|
+
# @see https://github.com/mainfram-work/geb for more information
|
13
|
+
|
14
|
+
module Geb
|
15
|
+
module CLI
|
16
|
+
module Commands
|
17
|
+
|
18
|
+
# Define server command
|
19
|
+
class Server < Dry::CLI::Command
|
20
|
+
|
21
|
+
# Command description, usage and examples
|
22
|
+
desc "Start a local server to view the site output (runs build first), uses webrick"
|
23
|
+
example [" ", "--port 8080", "--skip_auto_build", "--skip_build"]
|
24
|
+
|
25
|
+
# Define command options
|
26
|
+
option :port, type: :int, default: 0, desc: "Port to run the server on, otherwise it will use config file setting"
|
27
|
+
option :skip_build, type: :boolean, default: false, desc: "Skip building the site before starting the server"
|
28
|
+
option :skip_auto_build, type: :boolean, default: false, desc: "Don't automatically rebuild the site when a file changes"
|
29
|
+
|
30
|
+
# Call method for the server command
|
31
|
+
# @param options [Hash] the options hash for the command
|
32
|
+
def call(**options)
|
33
|
+
|
34
|
+
# initialise a site and load it from the current directory
|
35
|
+
site = Geb::Site.new
|
36
|
+
site.load(Dir.pwd)
|
37
|
+
|
38
|
+
# build the site if the skip_build option is not set
|
39
|
+
site.build() unless options[:skip_build]
|
40
|
+
|
41
|
+
# start a new queue for the shutdown signal (instead of using trap to shutdown the server and file watcher directly)
|
42
|
+
@shutdown_queue = Queue.new
|
43
|
+
trap('INT') { @shutdown_queue << :shutdown }
|
44
|
+
|
45
|
+
# get the server port from the options, site configuration or auto generated (0), in that order
|
46
|
+
server_port = options[:port] || site.site_config.local_port || 0
|
47
|
+
|
48
|
+
# initialize the server
|
49
|
+
server = Geb::Server.new(site, server_port, !options[:skip_auto_build])
|
50
|
+
|
51
|
+
# start the server
|
52
|
+
server.start()
|
53
|
+
|
54
|
+
# wait for the shutdown signal
|
55
|
+
@shutdown_queue.pop
|
56
|
+
|
57
|
+
# stop the server
|
58
|
+
server.stop()
|
59
|
+
|
60
|
+
rescue Geb::Error => e
|
61
|
+
|
62
|
+
# print error message
|
63
|
+
puts
|
64
|
+
warn e.message
|
65
|
+
|
66
|
+
end # def call
|
67
|
+
|
68
|
+
# Force shutdown of the server
|
69
|
+
def force_shutdown
|
70
|
+
@shutdown_queue << :shutdown if @shutdown_queue
|
71
|
+
end # force_shutdown
|
72
|
+
|
73
|
+
end # class Server < Dry::CLI::Command
|
74
|
+
|
75
|
+
end # module Commands
|
76
|
+
end # module CLI
|
77
|
+
end # module Geb
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Upload command definition, based on Dry::CLI framework
|
4
|
+
# Upload the site to a remote server
|
5
|
+
#
|
6
|
+
# @title Geb - Upload Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @see https://github.com/mainfram-work/geb for more information
|
12
|
+
|
13
|
+
module Geb
|
14
|
+
module CLI
|
15
|
+
module Commands
|
16
|
+
|
17
|
+
# Define upload command
|
18
|
+
class Upload < Dry::CLI::Command
|
19
|
+
|
20
|
+
# Command description, usage and examples
|
21
|
+
desc "Upload the site to the remote server"
|
22
|
+
example [" "]
|
23
|
+
|
24
|
+
# Define command options
|
25
|
+
|
26
|
+
# Call method for the remote command
|
27
|
+
def call(*)
|
28
|
+
|
29
|
+
# initialise a new site and load the site from the current directory
|
30
|
+
site = Geb::Site.new
|
31
|
+
site.load(Dir.pwd)
|
32
|
+
|
33
|
+
# check if the site has been released before uploading
|
34
|
+
site.upload_release_to_remote()
|
35
|
+
|
36
|
+
rescue Geb::Error => e
|
37
|
+
|
38
|
+
# print error message
|
39
|
+
puts
|
40
|
+
warn e.message
|
41
|
+
|
42
|
+
end # def call
|
43
|
+
|
44
|
+
end # class Upload < Dry::CLI::Upload
|
45
|
+
|
46
|
+
end # module Commands
|
47
|
+
end # module CLI
|
48
|
+
end # module Geb
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Version command definition, based on Dry::CLI framework
|
4
|
+
# Prints the current version of the Geb
|
5
|
+
#
|
6
|
+
# @title Geb - Version Command
|
7
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
8
|
+
# @copyright 2024 Edin Mustajbegovic
|
9
|
+
# @license MIT
|
10
|
+
#
|
11
|
+
# @see https://github.com/mainfram-work/geb for more information
|
12
|
+
|
13
|
+
module Geb
|
14
|
+
module CLI
|
15
|
+
module Commands
|
16
|
+
|
17
|
+
# Define version command
|
18
|
+
class Version < Dry::CLI::Command
|
19
|
+
|
20
|
+
# Command description, usage and examples
|
21
|
+
desc "Print version"
|
22
|
+
example [" "]
|
23
|
+
|
24
|
+
# Call method for the version command
|
25
|
+
def call(*)
|
26
|
+
|
27
|
+
# Print the version
|
28
|
+
puts "Geb version #{Geb::VERSION}"
|
29
|
+
|
30
|
+
end # def call
|
31
|
+
|
32
|
+
end # class Version < Dry::CLI::Command
|
33
|
+
|
34
|
+
end # module Commands
|
35
|
+
end # module CLI
|
36
|
+
end # module Geb
|
data/lib/geb/config.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Geb configuration. It merges the geb.yml configuration file with the defaults.
|
4
|
+
#
|
5
|
+
# @title Geb - Command Registry
|
6
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
7
|
+
# @copyright 2024 Edin Mustajbegovic
|
8
|
+
# @license MIT
|
9
|
+
#
|
10
|
+
# @see https://github.com/mainfram-work/geb for more information
|
11
|
+
|
12
|
+
# include the required libraries
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
module Geb
|
16
|
+
class Config
|
17
|
+
|
18
|
+
class ConfigFileNotFound < Geb::Error
|
19
|
+
MESSAGE = "Could not find geb config file.".freeze
|
20
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
21
|
+
end # class ConfigFileNotFound < Geb::Error
|
22
|
+
|
23
|
+
# check if the site directory specified has the required geb.config.yml file
|
24
|
+
def self.site_directory_has_config?(site_path)
|
25
|
+
File.exist?(File.join(site_path, Geb::Defaults::SITE_CONFIG_FILENAME))
|
26
|
+
end # def self.site_directory_has_config?
|
27
|
+
|
28
|
+
# initialize the site configuration\
|
29
|
+
# @param site [Geb::Site] the site object
|
30
|
+
# @raise ConfigFileNotFound if the site directory has no geb.config.yml file
|
31
|
+
def initialize(site)
|
32
|
+
|
33
|
+
# set the site path
|
34
|
+
@site = site
|
35
|
+
|
36
|
+
# make sure the site directory has the required geb.config.yml file
|
37
|
+
raise ConfigFileNotFound.new("Site path [#{@site.site_path}] has no geb configuration.") unless Geb::Config.site_directory_has_config?(@site.site_path)
|
38
|
+
|
39
|
+
# load the site configuration, if no configuration is found in the file, set it to an empty hash
|
40
|
+
@config = YAML.load_file(File.join(@site.site_path, Geb::Defaults::SITE_CONFIG_FILENAME))
|
41
|
+
@config ||= {}
|
42
|
+
|
43
|
+
end # def initialize
|
44
|
+
|
45
|
+
# get the configured site name, if not set, use the site directory name
|
46
|
+
# @return [String] the site name
|
47
|
+
def site_name
|
48
|
+
return @config['site_name'] || File.basename(@site.site_path)
|
49
|
+
end # def site_name
|
50
|
+
|
51
|
+
# get the configured remote uri
|
52
|
+
# @return [String] the remote uri
|
53
|
+
def remote_uri
|
54
|
+
return @config['remote_uri'] || nil
|
55
|
+
end # def remote_uri
|
56
|
+
|
57
|
+
# get the configured remote path
|
58
|
+
# @return [String] the remote path
|
59
|
+
def remote_path
|
60
|
+
return @config['remote_path'] || nil
|
61
|
+
end # def remote_path
|
62
|
+
|
63
|
+
# get the configured local port
|
64
|
+
# @return [Integer] the local port
|
65
|
+
def local_port
|
66
|
+
return @config['local_port'] || nil
|
67
|
+
end # def local_port
|
68
|
+
|
69
|
+
# get the configured output directory
|
70
|
+
# @return [String] the output directory
|
71
|
+
# @note the assets directory is relative to the site root
|
72
|
+
def output_dir
|
73
|
+
return @config['output_dir'] || Geb::Defaults::OUTPUT_DIR
|
74
|
+
end # def output_dir
|
75
|
+
|
76
|
+
# get the configured assets directory
|
77
|
+
# @return [String] the assets directory
|
78
|
+
# @note the assets directory is relative to the site root
|
79
|
+
def assets_dir
|
80
|
+
return @config['assets_dir'] || Geb::Defaults::ASSETS_DIR
|
81
|
+
end # def assets_dir
|
82
|
+
|
83
|
+
# get the configured page extensions
|
84
|
+
# @return [Array] the page extensions
|
85
|
+
def page_extensions
|
86
|
+
return @config['page_extensions'] || Geb::Defaults::PAGE_EXTENSIONS
|
87
|
+
end # def page_extensions
|
88
|
+
|
89
|
+
# get the configured template and partial identifier
|
90
|
+
# @return [Regexp] the template and partial identifier
|
91
|
+
def template_and_partial_identifier
|
92
|
+
return @config['template_and_partial_identifier'] || Geb::Defaults::TEMPLATE_AND_PARTIAL_IDENTIFIER
|
93
|
+
end # def template_and_partial_identifier
|
94
|
+
|
95
|
+
# get the configured template paths
|
96
|
+
# @return [Array] the template paths
|
97
|
+
# @note the template paths are relative to the site root
|
98
|
+
def template_paths
|
99
|
+
return @config['template_paths'] || []
|
100
|
+
end # def template_paths
|
101
|
+
|
102
|
+
end # class Config
|
103
|
+
end # module Geb
|
data/lib/geb/defaults.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# A simple list of defaults for the Geb gem
|
4
|
+
#
|
5
|
+
# @title Geb - Defaults
|
6
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
7
|
+
# @copyright 2024 Edin Mustajbegovic
|
8
|
+
# @license MIT
|
9
|
+
#
|
10
|
+
# @see https://github.com/mainfram-work/geb for more information
|
11
|
+
|
12
|
+
# include the required libraries
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
module Geb
|
16
|
+
module Defaults
|
17
|
+
|
18
|
+
# default values for site templates
|
19
|
+
TEMPLATE_ARCHIVE_FILENAME = 'geb-template.tar.gz' # default the template archive filename
|
20
|
+
AVAILABLE_TEMPLATES = # list of bundled templates (first one is the default template)
|
21
|
+
['bootstrap_jquery', 'basic']
|
22
|
+
SITE_CONFIG_FILENAME = 'geb.config.yml' # site config file name
|
23
|
+
HTTP_TEMPLATE_CONTENT_TYPES = # acceptable remote template content types
|
24
|
+
['application/x-gzip', 'application/gzip', 'application/octet-stream']
|
25
|
+
BUNDLED_TEMPLATES_DIR = # bundled template directory
|
26
|
+
File.join(__dir__, 'samples')
|
27
|
+
DEFAULT_TEMPLATE_DIR = # default template directory
|
28
|
+
File.join(BUNDLED_TEMPLATES_DIR, AVAILABLE_TEMPLATES.first)
|
29
|
+
DEFAULT_TEMPLATE = # default template
|
30
|
+
AVAILABLE_TEMPLATES.first
|
31
|
+
|
32
|
+
# default values for site configuration (all paths are relative to the site root)
|
33
|
+
OUTPUT_DIR = 'output' # output directory (relative to site root)
|
34
|
+
LOCAL_OUTPUT_DIR = 'local' # local output directory (relative to output directory)
|
35
|
+
RELEASE_OUTPUT_DIR = 'release' # release output directory (relative to output directory)
|
36
|
+
ASSETS_DIR = 'assets' # location for assets (images, js and css)
|
37
|
+
|
38
|
+
# default values for site pages
|
39
|
+
PAGE_EXTENSIONS = # list of file extention to treat as pages
|
40
|
+
['.md', '.markdown', '.html', '.htm', '.txt', '.js', '.css']
|
41
|
+
TEMPLATE_AND_PARTIAL_IDENTIFIER = /^_/ # filename pattern for templates or partials
|
42
|
+
|
43
|
+
end # module Defaults
|
44
|
+
end # module Geb
|
data/lib/geb/git.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Simple set of git utilities used by the cli commands
|
4
|
+
#
|
5
|
+
# @title Geb - Git
|
6
|
+
# @author Edin Mustajbegovic <edin@actiontwelve.com>
|
7
|
+
# @copyright 2024 Edin Mustajbegovic
|
8
|
+
# @license MIT
|
9
|
+
#
|
10
|
+
# @see https://github.com/mainfram-work/geb for more information
|
11
|
+
|
12
|
+
# include the required libraries
|
13
|
+
require 'tmpdir'
|
14
|
+
require 'open3'
|
15
|
+
require 'shellwords'
|
16
|
+
|
17
|
+
module Geb
|
18
|
+
module Git
|
19
|
+
|
20
|
+
class FailedValidationError < Geb::Error
|
21
|
+
MESSAGE = "Could not evaluate if the specified SITE_PATH is within a git repository, please choose a different location or use the --skip_git option.".freeze
|
22
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
23
|
+
end # class FailedValidationError < Geb::Error
|
24
|
+
|
25
|
+
class InsideGitRepoError < Geb::Error
|
26
|
+
MESSAGE = "You are already inside a git repository, please choose a different location or use the --skip_git option.".freeze
|
27
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
28
|
+
end # class InsideGitRepoError < Geb::Error
|
29
|
+
|
30
|
+
class GitError < Geb::Error
|
31
|
+
MESSAGE = "An error occurred while executing a git command.".freeze
|
32
|
+
def initialize(e = ""); super(e, MESSAGE); end
|
33
|
+
end # class GitError < Geb
|
34
|
+
|
35
|
+
# ::: Class Methods ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
36
|
+
|
37
|
+
# validate if the proposed directory is a git repository, raise an error if it is
|
38
|
+
# or if the directory is inside a git repository
|
39
|
+
# @param site_directory [String] the proposed site directory
|
40
|
+
# @raise [FailedValidationError] if the directory could not be evaluated
|
41
|
+
# @raise [InsideGitRepoError] if the directory is inside a git repository
|
42
|
+
# @raise [GitError] if an error occurred while executing the git command
|
43
|
+
# @return [void]
|
44
|
+
def self.validate_git_repo(site_directory)
|
45
|
+
|
46
|
+
Geb.log_start "Validating proposed site path as a git repository ... "
|
47
|
+
|
48
|
+
# initialize the closest directory to the site directory that actually exists
|
49
|
+
closest_existing_directory = site_directory
|
50
|
+
|
51
|
+
|
52
|
+
# find the closest existing directory
|
53
|
+
until Dir.exist?(closest_existing_directory)
|
54
|
+
closest_existing_directory = File.dirname(closest_existing_directory)
|
55
|
+
end # until
|
56
|
+
|
57
|
+
# raise an error if we reached the root directory
|
58
|
+
raise FailedValidationError if closest_existing_directory == '/'
|
59
|
+
|
60
|
+
# perform the git check in the closest existing directory
|
61
|
+
_, stderr, status = Open3.capture3("cd #{Shellwords.shellescape(closest_existing_directory)} && git rev-parse --is-inside-work-tree")
|
62
|
+
|
63
|
+
# check if the error message is that the directory is not in a git repository
|
64
|
+
raise InsideGitRepoError if status.success?
|
65
|
+
|
66
|
+
# the above git command will fail if the directory is not in a git repository (we want that)
|
67
|
+
# raise error for all other errors
|
68
|
+
raise FailedValidationError.new(stderr.chomp) unless stderr.include?("not a git repository")
|
69
|
+
|
70
|
+
Geb.log "done."
|
71
|
+
|
72
|
+
end # def self.validate_git_repo(site_directory)
|
73
|
+
|
74
|
+
# Create a new git repository in the specified folder. It also creates a .gitignore file
|
75
|
+
# @param site_directory [String] the proposed site directory
|
76
|
+
# @raise [GitError] if an error occurred while executing the git command
|
77
|
+
# @return [void]
|
78
|
+
def self.create_git_repo(site_directory)
|
79
|
+
|
80
|
+
Geb.log_start "Initialising git repository ... "
|
81
|
+
|
82
|
+
# initialize the git repository
|
83
|
+
_, stderr, status = Open3.capture3("git -C #{Shellwords.shellescape(site_directory)} init")
|
84
|
+
|
85
|
+
# raise an error if the git command failed
|
86
|
+
raise GitError.new(stderr.chomp) unless status.success?
|
87
|
+
|
88
|
+
# attempt to create a .gitignore file
|
89
|
+
begin
|
90
|
+
|
91
|
+
# create a .gitignore file
|
92
|
+
File.open(File.join(site_directory, '.gitignore'), 'w') do |f|
|
93
|
+
|
94
|
+
# ignore everything withint the output folder
|
95
|
+
f.puts "/output"
|
96
|
+
f.puts "/.DS_Store"
|
97
|
+
|
98
|
+
end # File.open
|
99
|
+
|
100
|
+
rescue StandardError => e
|
101
|
+
|
102
|
+
# raise an error if the gitignore file could not be created
|
103
|
+
raise GitError.new("Could not create .gitignore file: #{e.message}")
|
104
|
+
|
105
|
+
end # begin ... rescue
|
106
|
+
|
107
|
+
Geb.log "done."
|
108
|
+
|
109
|
+
end # def self.create_git_repo
|
110
|
+
|
111
|
+
end # module Git
|
112
|
+
end # module Geb
|