integtest/spec/helper/dest.rb (178 lines of code) (raw):
# frozen_string_literal: true
require 'fileutils'
require 'open3'
require_relative 'opened_docs'
require_relative 'preview'
require_relative 'sh'
require_relative 'shell_repo'
##
# Helper class for initiating a conversion and dealing with the results.
class Dest
include Sh
##
# Stdout and stderr of running the conversions in convert_single
# or convert_all.
attr_reader :convert_outputs
##
# Status of the conversions. If any conversion fails it'll raise an error
# unless called with expect_failure. If it is called with expect_failure
# then it'll fail if there *isn't* a failure.
attr_reader :convert_statuses
def initialize(tmp)
@repos_cache = File.expand_path 'repos', tmp
@bare_dest = File.expand_path 'dest.git', tmp
@dest = File.expand_path 'dest', tmp
Dir.mkdir @dest
@initialized_bare_repo = false
@convert_outputs = []
@convert_statuses = []
@init_from_shell = true
end
##
# Expands a path relative to the destination.
def path(relative_path)
File.expand_path relative_path, @dest
end
##
# Create the fluent builder that you can use to convert a single book.
def prepare_convert_single(from, to)
ConvertSingle.new from, to, self
end
def prepare_convert_all(conf)
ConvertAll.new conf, @repos_cache, bare_repo, self
end
##
# Checks out the results of the last call to convert_all
def checkout_conversion(branch: nil)
branch_cmd = ''
branch_cmd = "--branch #{branch} " if branch
sh "git clone #{branch_cmd}#{bare_repo} #{@dest}"
end
##
# Executes `git show`.
def commit_info
Dir.chdir bare_repo do
sh 'git show'
end
end
##
# Executes `git show` for a single file.
def commit_info_for_file(file)
Dir.chdir bare_repo do
sh "git show -- #{file}"
end
end
##
# Start the preview service.
def start_preview
Preview.new(bare_repo)
end
##
# Start the preview service in air gapped mode.
def start_air_gapped
# The air gapped build expects the built docs to be *exactly* where the
# Dockerfile puts them. So we put them there too.
FileUtils.rm_rf '/docs_build/.repos/target_repo.git'
FileUtils.mkdir_p '/docs_build/.repos'
FileUtils.cp_r bare_repo, '/docs_build/.repos/target_repo.git'
Preview.new(bare_repo, air_gapped: true)
end
def remove_target_brach(branch_name)
Dir.chdir bare_repo do
sh "git branch -D #{branch_name}"
end
end
##
# The location of the bare repository. The first time this is called in a
# given context the bare repository is initialized
def bare_repo
unless @initialized_bare_repo
if @init_from_shell
ShellRepo.build!
sh "git clone --bare /tmp/shell #{@bare_dest}"
else
sh "git init --bare #{@bare_dest}"
end
@initialized_bare_repo = true
end
@bare_dest
end
##
# Should the bare repository that holds the destination docs be initailized
# from a "shell" repository for speed or not to actually test adding
# everything to an empty repository
def init_from_shell=(init_from_shell)
if @initialized_bare_repo
raise "can't change initialization after initialized"
end
@init_from_shell = init_from_shell
end
def run_convert(env, cmd, expect_failure)
cmd.unshift '/docs_build/build_docs.pl', '--in_standard_docker'
# Use popen here instead of capture to keep stdin open to appease the
# docker-image-always-removed paranoia in build_docs.pl
_stdin, out, wait_thr = Open3.popen2e(env, *cmd)
status = wait_thr.value
out = out.read.force_encoding 'UTF-8'
ok = status.success?
ok = !ok if expect_failure
raise_status cmd, out, status unless ok
check_for_perl_warnings out
save_conversion out, status.exitstatus
end
def check_for_perl_warnings(out)
raise "Perl warnings:\n#{out}" if out.include? 'Use of uninitialized value'
raise "Perl warnings:\n#{out}" if out.include? 'masks earlier declaration'
end
def save_conversion(out, status)
@convert_outputs << out
@convert_statuses << status
end
def run_convert_and_open(cmd, uses_preview)
cmd.unshift '/docs_build/build_docs.pl', '--in_standard_docker'
cmd += ['--open']
OpenedDocs.new cmd, uses_preview
end
class CmdBuilder
def initialize
@env = {}
end
def open
raise 'env unsupported' unless @env.empty?
@dest.run_convert_and_open @cmd, uses_preview
end
def node_name(node_name)
@env['NODE_NAME'] = node_name
self
end
def convert(expect_failure: false)
@dest.run_convert @env, @cmd, expect_failure
end
end
class ConvertSingle < CmdBuilder
def initialize(from, to, dest)
super()
@cmd = %W[
--doc #{from}
--out #{dest.path(to)}
]
@dest = dest
end
def suppress_migration_warnings
@cmd += ['--suppress_migration_warnings']
self
end
def alternatives(source_lang, dest_lang, dir)
@cmd += ['--alternatives', "#{source_lang}:#{dest_lang}:#{dir}"]
self
end
def single
@cmd += ['--single']
self
end
def uses_preview
true
end
end
class ConvertAll < CmdBuilder
def initialize(conf, repos_cache, target_repo, dest)
super()
@cmd = %W[
--all
--push
--reposcache #{repos_cache}
--target_repo #{target_repo}
--conf #{conf}
]
@dest = dest
end
def target_branch(target_branch)
@cmd += ['--target_branch', target_branch]
self
end
def announce_preview(preview_location)
@cmd += ['--announce_preview', preview_location]
self
end
def skip_link_check
@cmd += ['--skiplinkcheck']
self
end
def keep_hash
@cmd += ['--keep_hash']
self
end
def sub_dir(repo, branch)
@cmd += ['--sub_dir', "#{repo.name}:#{branch}:#{repo.root}"]
self
end
def uses_preview
false
end
end
end