class Spout::Commands::Deploy
Deploys a data dictionary and associated dataset to the server.
Constants
- INDENT
- INDENT_LENGTH
Attributes
config[RW]
environment[RW]
slug[RW]
subjects[RW]
token[RW]
url[RW]
version[RW]
webserver_name[RW]
Public Class Methods
new(argv, version)
click to toggle source
# File lib/spout/commands/deploy.rb, line 48 def initialize(argv, version) argv.shift # Remove "download" command from argv list @environment = argv.shift @version = version @skip_checks = !(argv.delete("--skip-checks").nil? && argv.delete("--no-checks").nil?) @skip_tests = !(argv.delete("--skip-tests").nil? && argv.delete("--no-tests").nil?) @skip_coverage = !(argv.delete("--skip-coverage").nil? && argv.delete("--no-coverage").nil?) @skip_variables = !(argv.delete("--skip-variables").nil? && argv.delete("--no-variables").nil?) @skip_dataset = !(argv.delete("--skip-dataset").nil? && argv.delete("--no-dataset").nil?) @skip_dictionary = !(argv.delete("--skip-dictionary").nil? && argv.delete("--no-dictionary").nil?) @skip_documentation = !(argv.delete("--skip-documentation").nil? && argv.delete("--no-documentation").nil?) @clean = !(argv.delete("--no-resume").nil? && argv.delete("--clean").nil?) @skip_server_scripts = !(argv.delete("--skip-server-scripts").nil? && argv.delete("--no-server-scripts").nil?) @archive_only = !(argv.delete("--archive-only").nil?) token_arg = argv.find { |arg| /^--token=/ =~ arg } argv.delete(token_arg) @token = token_arg.gsub(/^--token=/, "") if token_arg rows_arg = argv.find { |arg| /^--rows=(\d*)/ =~ arg } argv.delete(rows_arg) @number_of_rows = rows_arg.gsub(/--rows=/, "").to_i if rows_arg @argv = argv @created_folders = [] begin run_all rescue Interrupt puts "\nINTERRUPTED".red end end
Public Instance Methods
config_file_load()
click to toggle source
# File lib/spout/commands/deploy.rb, line 100 def config_file_load print " `.spout.yml` Check: " @config = Spout::Helpers::ConfigReader.new @slug = @config.slug if @slug == "" message = "#{INDENT}Please specify a dataset slug in your `.spout.yml` file!".red + " Ex:\n---\nslug: mydataset\n".gray failure(message) end if @config.webservers.empty? message = "#{INDENT}Please specify a webserver in your `.spout.yml` file!".red + " Ex:\n---\nwebservers:\n - name: production\n url: https://sleepdata.org\n - name: staging\n url: https://staging.sleepdata.org\n".gray failure(message) end matching_webservers = @config.webservers.select { |wh| /^#{@environment}/i =~ wh["name"].to_s.downcase } if matching_webservers.count == 0 message = "#{INDENT}0 webservers match '#{@environment}'.".red + " The following webservers exist in your `.spout.yml` file:\n" + "#{INDENT}#{@config.webservers.collect{|wh| wh['name'].to_s.downcase}.join(', ')}".white failure(message) elsif matching_webservers.count > 1 message = "#{INDENT}#{matching_webservers.count} webservers match '#{@environment}'.".red + " Did you mean one of the following?\n" + "#{INDENT}#{matching_webservers.collect{|wh| wh['name'].to_s.downcase}.join(', ')}".white failure(message) end @webserver_name = matching_webservers.first["name"].to_s.strip rescue @webserver_name = "" @url = URI.parse(matching_webservers.first["url"].to_s.strip) rescue @url = nil if @url.to_s == "" message = "#{INDENT}Invalid URL format for #{matching_webservers.first['name'].to_s.strip.downcase} webserver: ".red + "'#{matching_webservers.first['url'].to_s.strip}'".white failure(message) end puts "PASS".green puts " Target Server: " + "#{@url}".white puts " Target Dataset: " + "#{@slug}".white end
coverage_check()
click to toggle source
# File lib/spout/commands/deploy.rb, line 204 def coverage_check if @skip_coverage puts " Dataset Coverage: " + "SKIP".blue return end puts " Dataset Coverage: " + "NOT IMPLEMENTED".yellow end
data_dictionary_uploads()
click to toggle source
# File lib/spout/commands/deploy.rb, line 276 def data_dictionary_uploads if @skip_dictionary puts " Dictionary Uploads: " + "SKIP".blue return end print " Dictionary Uploads:" require "spout/commands/exporter" Spout::Commands::Exporter.new(@version, ["--quiet"]) csv_files = Dir.glob("exports/#{@version}/*.csv") csv_files.each_with_index do |csv_file, index| print "\r Dictionary Uploads: " + "#{index + 1} of #{csv_files.count}".green @created_folders << "datasets" @created_folders << "datasets/archive" @created_folders << "datasets/archive/#{@version}" upload_file(csv_file, "datasets") unless @archive_only upload_file(csv_file, "datasets/archive/#{@version}") end puts "\r Dictionary Uploads: " + "DONE ".green end
dataset_uploads()
click to toggle source
# File lib/spout/commands/deploy.rb, line 252 def dataset_uploads if @skip_dataset puts " Dataset Uploads: " + "SKIP".blue return end available_folders = (Dir.exist?("csvs") ? Dir.entries("csvs").select { |e| File.directory? File.join("csvs", e) }.reject { |e| [".", ".."].include?(e) }.sort : []) semantic = Spout::Helpers::Semantic.new(@version, available_folders) csv_directory = semantic.selected_folder csv_files = Dir.glob("csvs/#{csv_directory}/**/*.csv") csv_files.each_with_index do |csv_file, index| print "\r Dataset Uploads: " + "#{index + 1} of #{csv_files.count}".green folder = csv_file.gsub(%r{^csvs/#{csv_directory}}, "").gsub(/#{File.basename(csv_file)}$/, "") folder = folder.gsub(%r{/$}, "") @created_folders << "datasets#{folder}" @created_folders << "datasets/archive" @created_folders << "datasets/archive/#{@version}#{folder}" upload_file(csv_file, "datasets#{folder}") unless @archive_only upload_file(csv_file, "datasets/archive/#{@version}#{folder}") end puts "\r Dataset Uploads: " + "DONE ".green end
failure(message)
click to toggle source
# File lib/spout/commands/deploy.rb, line 352 def failure(message) puts "FAIL".red puts message raise DeployError end
graph_generation()
click to toggle source
# File lib/spout/commands/deploy.rb, line 244 def graph_generation # failure "" require "spout/commands/graphs" @argv << "--clean" if @clean Spout::Commands::Graphs.new(@argv, @version, true, @url, @slug, @token, @webserver_name, @subjects) puts "\r Upload Variables: " + "DONE ".green end
load_subjects_from_csvs()
click to toggle source
# File lib/spout/commands/deploy.rb, line 236 def load_subjects_from_csvs @dictionary_root = Dir.pwd @variable_files = Dir.glob(File.join(@dictionary_root, "variables", "**", "*.json")) @subject_loader = Spout::Helpers::SubjectLoader.new(@variable_files, [], @version, @number_of_rows, @config.visit) @subject_loader.load_subjects_from_csvs! @subjects = @subject_loader.subjects end
markdown_uploads()
click to toggle source
# File lib/spout/commands/deploy.rb, line 299 def markdown_uploads if @skip_documentation puts "Documentation Uploads: " + "SKIP".blue return end print "Documentation Uploads:" markdown_files = Dir.glob(%w(CHANGELOG.md KNOWNISSUES.md)) markdown_files.each_with_index do |markdown_file, index| print "\rDocumentation Uploads: " + "#{index + 1} of #{markdown_files.count}".green @created_folders << "datasets" @created_folders << "datasets/archive" @created_folders << "datasets/archive/#{@version}" upload_file(markdown_file, "datasets") unless @archive_only upload_file(markdown_file, "datasets/archive/#{@version}") end puts "\rDocumentation Uploads: " + "DONE ".green end
run_all()
click to toggle source
# File lib/spout/commands/deploy.rb, line 84 def run_all config_file_load version_check test_check coverage_check user_authorization upload_variables dataset_uploads data_dictionary_uploads markdown_uploads trigger_server_updates set_default_dataset_version rescue DeployError # Nothing on Deploy Error end
set_default_dataset_version()
click to toggle source
# File lib/spout/commands/deploy.rb, line 335 def set_default_dataset_version if @archive_only puts " Set Default Version: " + "SKIP".blue return end print " Set Default Version: " params = { auth_token: @token, dataset: @slug, version: @version } (json, _status) = Spout::Helpers::SendJson.post( "#{@url}/api/v1/dictionary/update_default_version.json", params ) if json.is_a?(Hash) && json["version_update"] == "success" puts @version.to_s.green else failure("#{INDENT}Unable to set default version\n#{INDENT}to " + @version.to_s.white + " for " + @slug.to_s.white + " dataset.") end end
test_check()
click to toggle source
# File lib/spout/commands/deploy.rb, line 184 def test_check if @skip_tests puts " Spout Tests: " + "SKIP".blue return end print " Spout Tests: " stdout = quietly do `spout t` end if stdout.match(/[^\d]0 failures, 0 errors,/) puts "PASS".green else message = "#{INDENT}spout t".white + " had errors or failures".red + "\n#{INDENT}Please fix all errors and failures and then run spout deploy again." failure message end end
trigger_server_updates()
click to toggle source
# File lib/spout/commands/deploy.rb, line 318 def trigger_server_updates if @skip_server_scripts puts "Launch Server Scripts: " + "SKIP".blue return end print "Launch Server Scripts: " params = { auth_token: @token, dataset: @slug, version: @version, folders: @created_folders.compact.uniq } (json, _status) = Spout::Helpers::SendJson.post("#{@url}/api/v1/dictionary/refresh.json", params) if json.is_a?(Hash) && json["refresh"] == "success" puts "DONE".green else puts "FAIL".red raise DeployError end end
upload_file(file, folder)
click to toggle source
# File lib/spout/commands/deploy.rb, line 358 def upload_file(file, folder) Spout::Helpers::SendFile.post("#{@url}/api/v1/dictionary/upload_file.json", file, @version, @token, @slug, folder) end
upload_variables()
click to toggle source
# File lib/spout/commands/deploy.rb, line 227 def upload_variables if @skip_variables puts " Upload Variables: " + "SKIP".blue return end load_subjects_from_csvs graph_generation end
version_check()
click to toggle source
-
**Version Check**
-
Git Repo should have zero uncommitted changes
-
`CHANGELOG.md` top line should include version, ex: `## 0.1.0`
-
“v#{VERSION}” matches HEAD git tag annotation
-
# File lib/spout/commands/deploy.rb, line 142 def version_check if @skip_checks puts " Version Check: " + "SKIP".blue return end stdout = quietly do `git status --porcelain` end print " Git Status Check: " if stdout.to_s.strip == "" puts "PASS".green + " " + "nothing to commit, working directory clean".white else message = "#{INDENT}working directory contains uncomitted changes\n#{INDENT}use `".red + "--skip-checks".white + "` to ignore this step".red failure message end changelog = File.open("CHANGELOG.md", &:readline).strip rescue changelog = "" if changelog.match(/^## #{@version.split('.')[0..2].join('.')}/) puts " CHANGELOG.md: " + "PASS".green + " " + changelog.white else print " CHANGELOG.md: " message = "#{INDENT}Expected: ".red + "## #{@version}".white + "\n#{INDENT} Actual: ".red + changelog.white failure message end stdout = quietly do `git describe --exact-match HEAD --tags` end print " Version Check: " tag = stdout.to_s.strip if "v#{@version}" != tag message = "#{INDENT}Version specified in `VERSION` file ".red + "'v#{@version}'".white + " does not match git tag on HEAD commit ".red + "'#{tag}'".white failure message else puts "PASS".green + " VERSION " + "'v#{@version}'".white + " matches git tag " + "'#{tag}'".white end end