geb 0.1.11

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 (106) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +37 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/LICENSE +21 -0
  6. data/README.md +384 -0
  7. data/Rakefile +21 -0
  8. data/bin/geb +21 -0
  9. data/lib/geb/cli.rb +40 -0
  10. data/lib/geb/commands/build.rb +59 -0
  11. data/lib/geb/commands/init.rb +70 -0
  12. data/lib/geb/commands/release.rb +54 -0
  13. data/lib/geb/commands/remote.rb +48 -0
  14. data/lib/geb/commands/server.rb +77 -0
  15. data/lib/geb/commands/upload.rb +48 -0
  16. data/lib/geb/commands/version.rb +36 -0
  17. data/lib/geb/config.rb +103 -0
  18. data/lib/geb/defaults.rb +44 -0
  19. data/lib/geb/git.rb +112 -0
  20. data/lib/geb/page.rb +217 -0
  21. data/lib/geb/partial.rb +150 -0
  22. data/lib/geb/samples/basic/assets/css/site.css +7 -0
  23. data/lib/geb/samples/basic/assets/images/android-chrome-192x192.png +0 -0
  24. data/lib/geb/samples/basic/assets/images/android-chrome-512x512.png +0 -0
  25. data/lib/geb/samples/basic/assets/images/apple-touch-icon.png +0 -0
  26. data/lib/geb/samples/basic/assets/images/favicon-16x16.png +0 -0
  27. data/lib/geb/samples/basic/assets/images/favicon-32x32.png +0 -0
  28. data/lib/geb/samples/basic/assets/images/favicon.ico +0 -0
  29. data/lib/geb/samples/basic/assets/images/hero.png +0 -0
  30. data/lib/geb/samples/basic/assets/images/og-thumb.png +0 -0
  31. data/lib/geb/samples/basic/assets/images/twitter-thumb.png +0 -0
  32. data/lib/geb/samples/basic/assets/js/site.js +5 -0
  33. data/lib/geb/samples/basic/geb.config.yml +70 -0
  34. data/lib/geb/samples/basic/index.html +11 -0
  35. data/lib/geb/samples/basic/page.html +11 -0
  36. data/lib/geb/samples/basic/shared/partials/_analytics.html +9 -0
  37. data/lib/geb/samples/basic/shared/partials/_footer.html +3 -0
  38. data/lib/geb/samples/basic/shared/partials/_global_assets.html +19 -0
  39. data/lib/geb/samples/basic/shared/partials/_header.html +0 -0
  40. data/lib/geb/samples/basic/shared/partials/_meta_tags.html +34 -0
  41. data/lib/geb/samples/basic/shared/templates/_blog_post.html +0 -0
  42. data/lib/geb/samples/basic/shared/templates/_site.html +19 -0
  43. data/lib/geb/samples/basic/site.webmanifest +1 -0
  44. data/lib/geb/samples/bootstrap_jquery/assets/css/site.css +7 -0
  45. data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-192x192.png +0 -0
  46. data/lib/geb/samples/bootstrap_jquery/assets/images/android-chrome-512x512.png +0 -0
  47. data/lib/geb/samples/bootstrap_jquery/assets/images/apple-touch-icon.png +0 -0
  48. data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-16x16.png +0 -0
  49. data/lib/geb/samples/bootstrap_jquery/assets/images/favicon-32x32.png +0 -0
  50. data/lib/geb/samples/bootstrap_jquery/assets/images/favicon.ico +0 -0
  51. data/lib/geb/samples/bootstrap_jquery/assets/images/hero.png +0 -0
  52. data/lib/geb/samples/bootstrap_jquery/assets/images/og-thumb.png +0 -0
  53. data/lib/geb/samples/bootstrap_jquery/assets/images/twitter-thumb.png +0 -0
  54. data/lib/geb/samples/bootstrap_jquery/assets/js/site.js +5 -0
  55. data/lib/geb/samples/bootstrap_jquery/blog/blog_post_1.html +35 -0
  56. data/lib/geb/samples/bootstrap_jquery/blog/blog_post_2.html +35 -0
  57. data/lib/geb/samples/bootstrap_jquery/blog/blog_post_3.html +35 -0
  58. data/lib/geb/samples/bootstrap_jquery/blog/index.html +17 -0
  59. data/lib/geb/samples/bootstrap_jquery/geb.config.yml +69 -0
  60. data/lib/geb/samples/bootstrap_jquery/index.html +11 -0
  61. data/lib/geb/samples/bootstrap_jquery/page.html +11 -0
  62. data/lib/geb/samples/bootstrap_jquery/shared/partials/_analytics.html +9 -0
  63. data/lib/geb/samples/bootstrap_jquery/shared/partials/_footer.html +3 -0
  64. data/lib/geb/samples/bootstrap_jquery/shared/partials/_global_assets.html +19 -0
  65. data/lib/geb/samples/bootstrap_jquery/shared/partials/_header.html +0 -0
  66. data/lib/geb/samples/bootstrap_jquery/shared/partials/_meta_tags.html +34 -0
  67. data/lib/geb/samples/bootstrap_jquery/shared/templates/_blog_post.html +0 -0
  68. data/lib/geb/samples/bootstrap_jquery/shared/templates/_site.html +19 -0
  69. data/lib/geb/samples/bootstrap_jquery/site.webmanifest +1 -0
  70. data/lib/geb/samples/geb.config.yml +70 -0
  71. data/lib/geb/server.rb +138 -0
  72. data/lib/geb/site/build.rb +189 -0
  73. data/lib/geb/site/core.rb +229 -0
  74. data/lib/geb/site/release.rb +70 -0
  75. data/lib/geb/site/remote.rb +142 -0
  76. data/lib/geb/site/template.rb +208 -0
  77. data/lib/geb/site.rb +83 -0
  78. data/lib/geb/template.rb +166 -0
  79. data/lib/geb/utilities.rb +110 -0
  80. data/lib/geb.rb +36 -0
  81. data/lib/seth.rb +50 -0
  82. data/sig/geb.rbs +4 -0
  83. data/test/api tests/test_cli.rb +200 -0
  84. data/test/api tests/test_config.rb +330 -0
  85. data/test/api tests/test_defaults.rb +62 -0
  86. data/test/api tests/test_git.rb +105 -0
  87. data/test/api tests/test_page.rb +320 -0
  88. data/test/api tests/test_partial.rb +152 -0
  89. data/test/api tests/test_server.rb +416 -0
  90. data/test/api tests/test_site.rb +1315 -0
  91. data/test/api tests/test_template.rb +249 -0
  92. data/test/api tests/test_utilities.rb +162 -0
  93. data/test/command tests/test_geb_build.rb +199 -0
  94. data/test/command tests/test_geb_init.rb +312 -0
  95. data/test/command tests/test_geb_release.rb +166 -0
  96. data/test/command tests/test_geb_remote.rb +66 -0
  97. data/test/command tests/test_geb_server.rb +122 -0
  98. data/test/command tests/test_geb_upload.rb +96 -0
  99. data/test/command tests/test_geb_version.rb +58 -0
  100. data/test/support/geb_api_test.rb +37 -0
  101. data/test/support/geb_cli_test.rb +275 -0
  102. data/test/support/geb_minitest_ext.rb +35 -0
  103. data/test/support/geb_test_helpers.rb +84 -0
  104. data/test/support/geb_web_server_proxy.rb +128 -0
  105. data/test/test_helper.rb +61 -0
  106. 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
@@ -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