Skip to content

Commit

Permalink
Extract class on Project#bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
maxfierke committed Feb 12, 2024
1 parent 5f4cdd2 commit 7cb86b6
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 103 deletions.
3 changes: 2 additions & 1 deletion src/mstrap.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ require "./mstrap/profile_fetcher"
require "./mstrap/user"
require "./mstrap/configuration"
require "./mstrap/supports/**"
require "./mstrap/web_bootstrapper"
require "./mstrap/bootstrapper"
require "./mstrap/bootstrappers/**"
require "./mstrap/runtime_manager"
require "./mstrap/runtime_managers/**"
require "./mstrap/runtime"
Expand Down
28 changes: 28 additions & 0 deletions src/mstrap/bootstrapper.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module MStrap
abstract class Bootstrapper
include DSL

def initialize(@config : Configuration)
end

def self.for(config : Configuration, project : Project) : Array(Bootstrapper)
bootstrappers = Array(Bootstrapper).new

if project.run_scripts? && Bootstrappers::ScriptBootstrapper.has_scripts?(project)
bootstrappers << Bootstrappers::ScriptBootstrapper.new(config)
else
bootstrappers << Bootstrappers::DefaultBootstrapper.new(config)

if project.web?
bootstrappers << Bootstrappers::WebBootstrapper.new(config)
end
end

bootstrappers
end

abstract def bootstrap(project : Project) : Bool

protected getter :config
end
end
35 changes: 35 additions & 0 deletions src/mstrap/bootstrappers/default_bootstrapper.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module MStrap
module Bootstrappers
class DefaultBootstrapper < Bootstrapper
# Conventional bootstrapping from mstrap. This will auto-detect the runtimes
# used by the project and run the standard bootstrapping for each runtime.
# This **does not** run any bootstrapping scripts, and is used mainly for
# calling into conventional bootstrapping within a project's
# `script/bootstrap` or `script/setup` from `mstrap project`.
def bootstrap(project : Project) : Bool
logd "Bootstrapping '#{project.name}' with runtime defaults."

runtime_impls(project).each do |runtime|
Dir.cd(project.path) do
if runtime.matches?
logd "Detected #{runtime.language_name}. Installing #{runtime.language_name}, project #{runtime.language_name} packages, and other relevant dependencies"
runtime.setup
end
end
end

true
end

def runtime_impls(project)
if project.runtimes.empty?
config.runtime_manager.runtimes
else
config.runtime_manager.runtimes.select do |runtime|
project.runtimes.includes?(runtime.language_name)
end
end
end
end
end
end
38 changes: 38 additions & 0 deletions src/mstrap/bootstrappers/script_bootstrapper.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module MStrap
module Bootstrappers
class ScriptBootstrapper < Bootstrapper
# :nodoc:
BOOTSTRAP_SCRIPT = File.join("script", "bootstrap")

# :nodoc:
SETUP_SCRIPT = File.join("script", "setup")

# Executes `script/bootstrap` and `script/setup` (if either exists and are
# configured to run)
def bootstrap(project : Project) : Bool
logd "Found bootstrapping scripts, executing instead of using defaults."

begin
ENV["__MSTRAP_EXEC_SCRIPTS"] = "true"

Dir.cd(project.path) do
cmd BOOTSTRAP_SCRIPT if File.exists?(BOOTSTRAP_SCRIPT)
cmd SETUP_SCRIPT if File.exists?(SETUP_SCRIPT)
end
ensure
ENV.delete("__MSTRAP_EXEC_SCRIPTS")
end

true
end

# Whether project has any bootstrapping/setup scripts a-la
# [`scripts-to-rule-them-all`](https://github.com/github/scripts-to-rule-them-all)
def self.has_scripts?(project)
[BOOTSTRAP_SCRIPT, SETUP_SCRIPT].any? do |script_path|
File.exists?(File.join(project.path, script_path))
end
end
end
end
end
33 changes: 33 additions & 0 deletions src/mstrap/bootstrappers/web_bootstrapper.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module MStrap
module Bootstrappers
# The `WebBootstrapper` is responsible for bootstrapping web-based projects.
# Currently, this is just setting up an NGINX configuration for the project.
class WebBootstrapper < Bootstrapper
include DSL

def initialize(@config : Configuration)
super
@mkcert = Mkcert.new
end

# Executes the bootstrapper
def bootstrap(project : Project) : Bool
logd "'#{project.name}' is a web project. Running web bootstrapper."

if mkcert.installed?
Dir.cd(Paths::PROJECT_CERTS) do
mkcert.install!
mkcert.install_cert!(project.hostname)
end
else
logw "mkcert not found. Skipping cert setup."
end

Templates::NginxConf.new(project).write_to_config!
true
end

private getter :mkcert
end
end
end
2 changes: 1 addition & 1 deletion src/mstrap/cli.cr
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ DESC
project_def.runtimes = options.string["runtimes"].split(',') if options.string.has_key?("runtimes")

project = MStrap::Project.for(project_def)
project.bootstrap(config.runtime_manager)
Bootstrapper.for(config, project).each { |bs| bs.bootstrap(project) }
end
end

Expand Down
68 changes: 0 additions & 68 deletions src/mstrap/project.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ module MStrap
# :nodoc:
SCP_REPO_REGEX = /\A(.+@)?[\w\d\.\-_]+:/

# :nodoc:
BOOTSTRAP_SCRIPT = File.join("script", "bootstrap")

# :nodoc:
SETUP_SCRIPT = File.join("script", "setup")

@cname : String
@hostname : String
@name : String
Expand Down Expand Up @@ -117,14 +111,6 @@ module MStrap
end
end

# Whether project has any bootstrapping/setup scripts a-la
# [`scripts-to-rule-them-all`](https://github.com/github/scripts-to-rule-them-all)
def has_scripts?
[BOOTSTRAP_SCRIPT, SETUP_SCRIPT].any? do |script_path|
File.exists?(File.join(path, script_path))
end
end

# Clones the project from Git
def clone
success = cmd("git", "clone", git_uri, path, quiet: true)
Expand Down Expand Up @@ -165,60 +151,6 @@ module MStrap
end
end

# Executes `script/bootstrap` and `script/setup` (if either exists and are
# configured to run) or executes conventional runtime bootstrapping as
# determined by mstrap.
def bootstrap(runtime_manager : RuntimeManager)
if has_scripts? && run_scripts?
logd "Found bootstrapping scripts, executing instead of using defaults."
begin
ENV["__MSTRAP_EXEC_SCRIPTS"] = "true"

Dir.cd(path) do
cmd BOOTSTRAP_SCRIPT if File.exists?(BOOTSTRAP_SCRIPT)
cmd SETUP_SCRIPT if File.exists?(SETUP_SCRIPT)
end
ensure
ENV.delete("__MSTRAP_EXEC_SCRIPTS")
end
else
logd "Bootstrapping '#{name}' with runtime defaults."
default_bootstrap(runtime_manager)
end
end

# Conventional bootstrapping from mstrap. This will auto-detect the runtimes
# used by the project and run the standard bootstrapping for each runtime.
# This **does not** run any bootstrapping scripts, and is used mainly for
# calling into conventional bootstrapping within a project's
# `script/bootstrap` or `script/setup` from `mstrap project`.
#
# TODO: Move this somewhere more appropriate
protected def default_bootstrap(runtime_manager : RuntimeManager)
runtime_impls =
if runtimes.empty?
runtime_manager.runtimes
else
runtime_manager.runtimes.select do |runtime|
runtimes.includes?(runtime.language_name)
end
end

runtime_impls.each do |runtime|
Dir.cd(path) do
if runtime.matches?
logd "Detected #{runtime.language_name}. Installing #{runtime.language_name}, project #{runtime.language_name} packages, and other relevant dependencies"
runtime.setup
end
end
end

if web?
logd "'#{name}' is a web project. Running web bootstrapper."
WebBootstrapper.new(self).bootstrap
end
end

private def current_branch
`git rev-parse --abbrev-ref HEAD`.chomp
end
Expand Down
4 changes: 2 additions & 2 deletions src/mstrap/steps/projects_step.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module MStrap
# updating, and bootstrapping all configured projects.
class ProjectsStep < Step
@has_web_projects = false
@projects : Array(Project) | Nil
@projects : Array(Project)?

def self.description
"Bootstraps configured projects"
Expand Down Expand Up @@ -38,7 +38,7 @@ module MStrap
end

logn "--> Bootstrapping: "
project.bootstrap(runtime_manager)
Bootstrapper.for(config, project).each { |bs| bs.bootstrap(project) }
success "Finished bootstrapping #{project.name}"
end

Expand Down
31 changes: 0 additions & 31 deletions src/mstrap/web_bootstrapper.cr

This file was deleted.

0 comments on commit 7cb86b6

Please sign in to comment.