Class: Helium::Deployer
- Inherits:
-
Object
- Object
- Helium::Deployer
- Includes:
- Observable
- Defined in:
- lib/helium/deployer.rb
Overview
The Deployer
class is responsible for performing all of Helium’s central functions: downloading projects from Git, exporting static copies of branches, building projects using Jake and generating the dependency file.
To run, the class requires a file called ‘deploy.yml` in the target directory, listing projects with their Git URLs. (See tests and README for examples.)
Instance Method Summary collapse
-
#checkout(project) ⇒ Object
Checks out (or updates if already checked out) a project by name from its Git repository.
-
#cleanup! ⇒ Object
Removes any repositories and static files for projects not listed in the the ‘deploy.yml` file.
-
#config ⇒ Object
Returns the deserialized contents of ‘deploy.yml`.
-
#deploy!(project, build = true) ⇒ Object
Deploys an individual project by checking it out from Git, exporting static copies of all its branches and building them using Jake.
-
#export(project) ⇒ Object
Exports static copies of a project from every branch and tag in its Git repository.
-
#initialize(path, output_dir = 'output', options = {}) ⇒ Deployer
constructor
Initialize using the directory containing the ‘deploy.yml` file, and the name of the directory to export repositories and static files to.
-
#projects ⇒ Object
Returns a hash of projects names and their Git URLs.
-
#repo_dir(project = nil) ⇒ Object
Returns the path to the Git repository for a given project.
-
#run!(project = nil) ⇒ Object
Runs all the deploy actions.
-
#run_builds!(options = nil) ⇒ Object
Scans all the checked-out projects for Jake build files and builds those projects that have such a file.
-
#static_dir(project = nil, branch = nil) ⇒ Object
Returns the path to the static export directory for a given project and branch.
Constructor Details
#initialize(path, output_dir = 'output', options = {}) ⇒ Deployer
17 18 19 20 21 22 23 |
# File 'lib/helium/deployer.rb', line 17 def initialize(path, output_dir = 'output', = {}) @path = File.(path) @config = join(@path, CONFIG_FILE) raise "Expected config file at #{@config}" unless File.file?(@config) @output_dir = join(@path, output_dir) @options = end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object (private)
We use method_missing
to create shorthands for FileUtils
methods.
218 219 220 |
# File 'lib/helium/deployer.rb', line 218 def method_missing(*args, &block) FileUtils.__send__(*args, &block) end |
Instance Method Details
#checkout(project) ⇒ Object
Checks out (or updates if already checked out) a project by name from its Git repository. If the project is new, we use ‘git clone` to copy it, otherwise we use `git fetch` to update it.
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/helium/deployer.rb', line 61 def checkout(project) dir = repo_dir(project) if File.directory?(join(dir, GIT)) log :git_fetch, "Updating Git repo in #{ dir }" cd(dir) { `git fetch origin` } else url = projects[project] log :git_clone, "Cloning Git repo #{ url } into #{ dir }" `git clone #{ url } "#{ dir }"` end end |
#cleanup! ⇒ Object
Removes any repositories and static files for projects not listed in the the ‘deploy.yml` file.
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/helium/deployer.rb', line 151 def cleanup! [repo_dir, static_dir].each do |dir| next unless File.directory?(dir) (Dir.entries(dir) - %w[. ..]).each do |entry| path = join(dir, entry) next unless File.directory?(path) rm_rf(path) unless projects.has_key?(entry) end end end |
#config ⇒ Object
Returns the deserialized contents of ‘deploy.yml`.
26 27 28 |
# File 'lib/helium/deployer.rb', line 26 def config @config_data ||= YAML.load(File.read(@config)) end |
#deploy!(project, build = true) ⇒ Object
Deploys an individual project by checking it out from Git, exporting static copies of all its branches and building them using Jake.
52 53 54 55 56 |
# File 'lib/helium/deployer.rb', line 52 def deploy!(project, build = true) checkout(project) export(project) run_builds! if build end |
#export(project) ⇒ Object
Exports static copies of a project from every branch and tag in its Git repository. Existing static copies on disk are removed. Mappings from branch/tag names to commit IDs are stored in heads.yml in the project directory.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/helium/deployer.rb', line 76 def export(project) repo_dir = repo_dir(project) repo = Grit::Repo.new(repo_dir) export_directory = static_dir(project) mkdir_p(export_directory) heads = head_mappings(project) File.open(static_dir(project, HEAD_LIST), 'w') { |f| f.write(YAML.dump(heads)) } heads.values.uniq.each do |commit| target = static_dir(project, commit) next if File.directory?(target) log :export, "Exporting commit '#{ commit }' of '#{ project }' into #{ target }" cp_r(repo_dir, target) cd(target) { `git checkout #{commit}` } end end |
#projects ⇒ Object
Returns a hash of projects names and their Git URLs.
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/helium/deployer.rb', line 31 def projects return @projects if defined?(@projects) raise "No configuration for JS.Class" unless js_class = config[JS_CLASS] @jsclass_version = js_class['version'] @projects = config['projects'] || {} @projects[JS_CLASS] = js_class['repository'] @projects end |
#repo_dir(project = nil) ⇒ Object
Returns the path to the Git repository for a given project.
163 164 165 166 |
# File 'lib/helium/deployer.rb', line 163 def repo_dir(project = nil) path = [@output_dir, REPOS, project].compact join(*path) end |
#run!(project = nil) ⇒ Object
Runs all the deploy actions. If given a project name, only checks out and builds the given project, otherwise builds all projects in ‘deploy.yml`.
44 45 46 47 48 |
# File 'lib/helium/deployer.rb', line 44 def run!(project = nil) return deploy!(project) if project projects.each { |project, url| deploy!(project, false) } run_builds! end |
#run_builds!(options = nil) ⇒ Object
Scans all the checked-out projects for Jake build files and builds those projects that have such a file. As the build progresses we use Jake event hooks to collect dependencies and generated file paths, and when all builds are finished we generate a JS.Packages file listing all the files discovered. This file should be included in web pages to set up the the packages manager for loading our projects.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/helium/deployer.rb', line 102 def run_builds!( = nil) ||= @options @tree = Trie.new @custom = [:custom] @location = [:location] manifest = [] # Loop over checked-out projects. Skip directories with no Jake file. Find.find(static_dir) do |path| next unless File.directory?(path) and File.file?(join(path, JAKE_FILE)) project, commit = *path.split(SEP)[-2..-1] heads = YAML.load(File.read(join(path, '..', HEAD_LIST))) branches = heads.select { |(head, id)| id == commit }.map { |pair| pair.first } Jake.clear_hooks! # Event listener to capture file information from Jake hook = lambda do |build, package, build_type, file| if build_type == :min @js_loader = file if File.basename(file) == LOADER_FILE and project == JS_CLASS and branches.include?(@jsclass_version) file = file.sub(path, '') manifest << join(project, commit, file) branches.each do |branch| @tree[[project, branch]] = commit @tree[[project, branch, file]] = package. end end end jake_hook(:file_created, &hook) jake_hook(:file_not_changed, &hook) log :jake_build, "Building branch '#{ branches * "', '" }' of '#{ project }' from #{ join(path, JAKE_FILE) }" begin; Jake.build!(path) rescue; end end generate_manifest! manifest + [PACKAGES, PACKAGES_MIN] end |
#static_dir(project = nil, branch = nil) ⇒ Object
Returns the path to the static export directory for a given project and branch.
169 170 171 172 |
# File 'lib/helium/deployer.rb', line 169 def static_dir(project = nil, branch = nil) path = [@output_dir, STATIC, project, branch].compact join(*path) end |