geb 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
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