Module: Pray::CLI
- Extended by:
- CLI
- Included in:
- CLI
- Defined in:
- lib/pray/cli.rb,
lib/pray/cli/help.rb,
lib/pray/cli/parse.rb,
lib/pray/cli/helpers.rb,
lib/pray/cli/suggest.rb,
lib/pray/cli/parse_auth.rb,
lib/pray/cli/parse_trust.rb,
lib/pray/cli/commands/auth.rb,
lib/pray/cli/commands/init.rb,
lib/pray/cli/commands/meta.rb,
lib/pray/cli/commands/trust.rb,
lib/pray/cli/commands/packages.rb,
lib/pray/cli/commands/workflow.rb,
lib/pray/cli/commands/distribution.rb
Defined Under Namespace
Constant Summary collapse
- MANIFEST_PATH =
"Prayfile"- LOCKFILE_PATH =
"Prayfile.lock"
Instance Method Summary collapse
- #add_command(name:, constraint: nil, path: nil) ⇒ Object
- #build_lockfile(project, rendered) ⇒ Object
- #canonical_marker_line(line) ⇒ Object
- #clean_command ⇒ Object
- #confess_command(package:, from_lock:, version:, accepted:, rejected:, note:, url:) ⇒ Object
- #default_output_for_target(target) ⇒ Object
- #dispatch(command) ⇒ Object
- #drift_command(flags) ⇒ Object
- #ensure_existing_lockfile(path) ⇒ Object
- #ensure_lockfile_current(project, rendered, existing) ⇒ Object
- #ensure_rendered_outputs_current(project, rendered) ⇒ Object
- #explain_command(name) ⇒ Object
- #extract_flag!(arguments, flag) ⇒ Object
- #format_command ⇒ Object
- #format_drift_report(report) ⇒ Object
- #format_list(values) ⇒ Object
- #format_marker_comments(text) ⇒ Object
- #format_verification_report(report) ⇒ Object
- #init_command(targets) ⇒ Object
- #insert_manifest_statement(text, statement) ⇒ Object
- #install_command(flags) ⇒ Object
- #list_command ⇒ Object
- #lockfile_path ⇒ Object
- #login_command(servers:, email:, mode:, passkey_key: nil, credential_id: nil, public_key: nil) ⇒ Object
- #manifest_command ⇒ Object
- #manifest_path ⇒ Object
- #maybe_print_help(arguments) ⇒ Object
- #merge_selected_package_update(previous, updated, selected_package) ⇒ Object
- #outdated_command(_arguments) ⇒ Object
- #package_command ⇒ Object
- #package_source_summary(package) ⇒ Object
- #parse_add_arguments(arguments) ⇒ Object
- #parse_bool_flag(value) ⇒ Object
- #parse_command(arguments) ⇒ Object
- #parse_confess_arguments(arguments) ⇒ Object
- #parse_login_arguments(arguments) ⇒ Object
- #parse_publish_arguments(arguments) ⇒ Object
- #parse_serve_arguments(arguments) ⇒ Object
- #parse_sync_arguments(arguments) ⇒ Object
- #parse_trust_command(arguments) ⇒ Object
- #parse_trust_import_registry_arguments(arguments) ⇒ Object
- #parse_trust_import_repo_arguments(arguments) ⇒ Object
- #parse_trust_key_arguments(arguments, label) ⇒ Object
- #parse_trust_list_arguments(arguments) ⇒ Object
- #parse_trust_set_allow_arguments(arguments) ⇒ Object
- #parse_trust_set_signed_arguments(arguments) ⇒ Object
- #plan_command(_arguments) ⇒ Object
- #prayer_init_command ⇒ Object
- #project_root ⇒ Object
- #publish_command(roots:, servers:) ⇒ Object
- #remove_command(name) ⇒ Object
- #remove_manifest_statement(text, name) ⇒ Object
- #remove_path_if_exists(path) ⇒ Object
- #render_command(flags) ⇒ Object
- #render_tree_node(package, package_map, depth, ancestry, lines) ⇒ Object
- #repo_distribution_root(root) ⇒ Object
- #repo_init_command ⇒ Object
- #resolve_current_project(options = ResolveOptions.new) ⇒ Object
- #run(arguments) ⇒ Object
- #serve_command(root:, host:, port:, stdio:) ⇒ Object
- #sync_command(root:, peers:) ⇒ Object
- #tree_command ⇒ Object
- #trust_add_key_command(key, match_prefix: nil) ⇒ Object
- #trust_check_command(source = nil) ⇒ Object
- #trust_import_registry_command(source_url, match_prefix: nil, include_host_key: false) ⇒ Object
- #trust_import_repo_command(source_url, match_prefix: nil) ⇒ Object
- #trust_list_command(scope: :all, source_url: nil) ⇒ Object
- #trust_remove_key_command(key, match_prefix: nil) ⇒ Object
- #trust_set_allow_command(match_prefix:, allow:) ⇒ Object
- #trust_set_signed_command(match_prefix:, enabled:) ⇒ Object
- #trust_show_command ⇒ Object
- #unlock_command(name) ⇒ Object
- #update_command(arguments) ⇒ Object
- #verify_command(flags) ⇒ Object
- #version_command ⇒ Object
Instance Method Details
#add_command(name:, constraint: nil, path: nil) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/pray/cli/commands/packages.rb', line 7 def add_command(name:, constraint: nil, path: nil) manifest_path_value = manifest_path manifest_text = Pray.read_manifest_text(manifest_path_value) manifest = Pray.parse_manifest(manifest_text) if manifest.packages.any? { |package| package.name == name } raise Error.manifest("package #{name} already exists") end declaration = Pray.format_package_declaration( ManifestPackage.new(name: name, constraint: constraint || "*", path: path) ) File.write(manifest_path_value, insert_manifest_statement(manifest_text, declaration)) end |
#build_lockfile(project, rendered) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/pray/cli/helpers.rb', line 31 def build_lockfile(project, rendered) LockfileIO.build_lockfile( project.manifest_hash, project.environment, project.project_root, project.manifest.sources, project.manifest.targets, rendered, project.packages, project.source_revisions, project.source_host_keys ) end |
#canonical_marker_line(line) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/pray/cli/helpers.rb', line 107 def canonical_marker_line(line) trimmed = line.strip remainder = trimmed.delete_prefix("<!--").strip return nil unless remainder.start_with?("pray:") content = remainder.delete_prefix("pray:").strip.delete_suffix("-->").strip return "<!-- pray:0 ignore-comments -->" if content == "0 ignore-comments" return "<!-- pray:#{content} -->" if content.match?(/\A[a-z0-9]+\z/) nil end |
#clean_command ⇒ Object
9 10 11 12 13 |
# File 'lib/pray/cli/commands/meta.rb', line 9 def clean_command remove_path_if_exists(".pray/cache") remove_path_if_exists(".pray/vendor") remove_path_if_exists(".pray/state.json") end |
#confess_command(package:, from_lock:, version:, accepted:, rejected:, note:, url:) ⇒ Object
24 25 26 27 28 29 |
# File 'lib/pray/cli/commands/auth.rb', line 24 def confess_command(package:, from_lock:, version:, accepted:, rejected:, note:, url:) Confess.submit( package: package, from_lock: from_lock, version: version, accepted: accepted, rejected: rejected, note: note, url: url ) end |
#default_output_for_target(target) ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/pray/cli/helpers.rb', line 23 def default_output_for_target(target) case target when "tool_a" then "INSTRUCTIONS" when "tool_b" then "TOOL_B" else target.upcase end end |
#dispatch(command) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/pray/cli.rb', line 72 def dispatch(command) case command in [:manifest] then manifest_command in [:init, targets] then init_command(targets) in [:prayer_init] then prayer_init_command in [:repo_init] then repo_init_command in [:install, flags] then install_command(flags) in [:add, add_args] then add_command(**add_args) in [:remove, name] then remove_command(name) in [:update, arguments] then update_command(arguments) in [:unlock, name] then unlock_command(name) in [:render, flags] then render_command(flags) in [:plan, arguments] then plan_command(arguments) in [:apply] then install_command({locked: false, frozen: false, offline: false}) in [:verify, flags] then verify_command(flags) in [:drift, flags] then drift_command(flags) in [:format] then format_command in [:package] then package_command in [:publish, publish_args] then publish_command(**publish_args) in [:unsupported, name] then raise Error.unsupported("#{name} is not implemented yet in pray-cli Ruby") in [:serve, serve_args] then serve_command(**serve_args) in [:login, login_args] then login_command(**login_args) in [:confess, confess_args] then confess_command(**confess_args) in [:sync, sync_args] then sync_command(**sync_args) in [:list] then list_command in [:outdated, arguments] then outdated_command(arguments) in [:explain, name] then explain_command(name) in [:vendor] then raise Error.unsupported("vendor is not implemented yet in pray-cli Ruby") in [:clean] then clean_command in [:tree] then tree_command in [:trust_list, ] then trust_list_command(**) in [:trust_show] then trust_show_command in [:trust_add_key, ] then trust_add_key_command(**) in [:trust_remove_key, ] then trust_remove_key_command(**) in [:trust_set_signed, ] then trust_set_signed_command(**) in [:trust_set_allow, ] then trust_set_allow_command(**) in [:trust_import_repo, ] then trust_import_repo_command(**) in [:trust_import_registry, ] then trust_import_registry_command(**) in [:trust_check, source] then trust_check_command(source) in [:version] then version_command end end |
#drift_command(flags) ⇒ Object
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/pray/cli/commands/workflow.rb', line 34 def drift_command(flags) project = resolve_current_project lockfile = ensure_existing_lockfile(lockfile_path) report = if flags[:semantic] Verify.inspect_project(project, lockfile) else Verify.drift_project(project, lockfile) end puts format_drift_report(report) unless report.clean? end |
#ensure_existing_lockfile(path) ⇒ Object
45 46 47 48 49 |
# File 'lib/pray/cli/helpers.rb', line 45 def ensure_existing_lockfile(path) raise Error.verify("missing Prayfile.lock; run pray install first") unless File.exist?(path) Pray.read_lockfile(path) end |
#ensure_lockfile_current(project, rendered, existing) ⇒ Object
51 52 53 54 55 56 |
# File 'lib/pray/cli/helpers.rb', line 51 def ensure_lockfile_current(project, rendered, existing) current = build_lockfile(project, rendered) return if Pray.lockfiles_equivalent?(current, existing) raise Error.verify("lockfile needs update; rerun pray install to refresh Prayfile.lock") end |
#ensure_rendered_outputs_current(project, rendered) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/pray/cli/helpers.rb', line 58 def ensure_rendered_outputs_current(project, rendered) rendered.each do |target| path = File.join(project.project_root, target.path) on_disk = File.read(path) if on_disk != target.content raise Error.render("#{path} is stale; rerun pray install to regenerate it or pray plan to inspect the diff") end end end |
#explain_command(name) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/pray/cli/commands/packages.rb', line 62 def explain_command(name) raise Error.resolution("explain requires a package name") unless name project = resolve_current_project package = project.packages.find { |entry| entry.declaration.name == name } raise Error.resolution("package #{name} not found") unless package lockfile = File.exist?(lockfile_path) ? Pray.read_lockfile(lockfile_path) : nil lockfile_package = lockfile&.package&.find { |entry| entry.name == name } lines = ["Package explanation"] lines << "name: #{package.declaration.name}" lines << "constraint: #{package.declaration.constraint}" lines << "resolved version: #{package.spec.version}" if package.registry_latest_version lines << "registry latest: #{package.registry_latest_version}" end lines << "source: #{package_source_summary(package)}" lines << "exports: #{format_list(package.selected_exports)}" lines << "dependencies: #{format_list(package.spec.dependencies.map(&:name))}" lines << "tree hash: #{package.tree_hash}" lines << "artifact hash: #{package.artifact_hash}" if lockfile_package lines << "lockfile version: #{lockfile_package.version}" lines << "lockfile path: #{lockfile_package.path}" lines << "lockfile exports: #{format_list(lockfile_package.exports)}" else lines << "lockfile record: missing" end puts lines.join("\n") end |
#extract_flag!(arguments, flag) ⇒ Object
80 81 82 83 84 |
# File 'lib/pray/cli/parse.rb', line 80 def extract_flag!(arguments, flag) found = arguments.include?(flag) arguments.reject! { |argument| argument == flag } found end |
#format_command ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/pray/cli/commands/workflow.rb', line 45 def format_command path = manifest_path original = Pray.read_manifest_text(path) manifest = Pray.parse_manifest(original) project = begin resolve_current_project(ResolveOptions.new(offline: true)) rescue Error resolve_current_project end hints = FormatManifest.classify_format_hints(project) formatted = FormatManifest.format_recommended(manifest, hints) File.write(path, formatted) if formatted != original return unless File.exist?(lockfile_path) lockfile = Pray.read_lockfile(lockfile_path) lockfile.target.each do |target| target.outputs.each do |output| next unless File.exist?(output) original_output = File.read(output) formatted_output = format_marker_comments(Hashing.normalize_line_endings(original_output)) File.write(output, formatted_output) if formatted_output != original_output end end end |
#format_drift_report(report) ⇒ Object
137 138 139 |
# File 'lib/pray/cli/helpers.rb', line 137 def format_drift_report(report) Verify.format_drift_report(report) end |
#format_list(values) ⇒ Object
129 130 131 |
# File 'lib/pray/cli/helpers.rb', line 129 def format_list(values) values.empty? ? "none" : values.join(", ") end |
#format_marker_comments(text) ⇒ Object
98 99 100 101 102 103 104 105 |
# File 'lib/pray/cli/helpers.rb', line 98 def format_marker_comments(text) lines = text.split("\n", -1).map do |line| canonical_marker_line(line) || line end output = lines.join("\n") output += "\n" unless output.end_with?("\n") output end |
#format_verification_report(report) ⇒ Object
133 134 135 |
# File 'lib/pray/cli/helpers.rb', line 133 def format_verification_report(report) Verify.format_verification_report(report) end |
#init_command(targets) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/pray/cli/commands/init.rb', line 13 def init_command(targets) path = manifest_path raise Error.manifest("Prayfile already exists") if File.exist?(path) targets = ["tool_a"] if targets.empty? lines = ['prayfile "1"'] targets.each do |target| output = default_output_for_target(target) lines << "target :#{target} do" lines << " output \"#{output}.md\"" lines << "end" end File.write(path, "#{lines.join("\n")}\n") end |
#insert_manifest_statement(text, statement) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/pray/cli/helpers.rb', line 68 def insert_manifest_statement(text, statement) lines = text.lines.map(&:chomp) insertion_index = lines.index do |line| trimmed = line.lstrip trimmed.start_with?("local ", "render ") end || lines.length lines.insert(insertion_index, statement) output = lines.join("\n") output += "\n" unless output.end_with?("\n") output end |
#install_command(flags) ⇒ Object
7 8 9 10 11 12 13 14 15 |
# File 'lib/pray/cli/commands/workflow.rb', line 7 def install_command(flags) Pray.materialize_project( manifest_path: manifest_path, frozen: flags[:frozen], locked: flags[:locked], offline: flags[:offline], refresh: flags[:refresh] ) end |
#list_command ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/pray/cli/commands/packages.rb', line 35 def list_command project = resolve_current_project lines = ["Package list"] project.packages.each do |package| lines << "#{package.declaration.name} #{package.spec.version} source=#{package_source_summary(package)} exports=#{format_list(package.selected_exports)}" end puts lines.join("\n") end |
#lockfile_path ⇒ Object
11 12 13 |
# File 'lib/pray/cli/helpers.rb', line 11 def lockfile_path Invocation.lockfile_path end |
#login_command(servers:, email:, mode:, passkey_key: nil, credential_id: nil, public_key: nil) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/pray/cli/commands/auth.rb', line 5 def login_command(servers:, email:, mode:, passkey_key: nil, credential_id: nil, public_key: nil) session_root = Dir.pwd servers.each do |server_url| session = case mode when :passkey AuthClient.login_with_passkey( server_url, credential_id, passkey_key, session_root, email: email ) when :ssh_agent AuthClient.login_with_ssh_agent( server_url, public_key, session_root, email: email ) else raise Error.unsupported("unknown login mode: #{mode}") end puts "logged in as #{session.email} via #{session.kind} on #{server_url}" end end |
#manifest_command ⇒ Object
8 9 10 11 |
# File 'lib/pray/cli/commands/init.rb', line 8 def manifest_command manifest = Pray.parse_manifest(Pray.read_manifest_text(manifest_path)) puts JSON.pretty_generate(ManifestJson.manifest_fields(manifest.canonicalized)) end |
#manifest_path ⇒ Object
7 8 9 |
# File 'lib/pray/cli/helpers.rb', line 7 def manifest_path Invocation.manifest_path end |
#maybe_print_help(arguments) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/pray/cli.rb', line 35 def maybe_print_help(arguments) if arguments.empty? Help.print_concise_help return true end if arguments.length == 1 && %w[help -h --help].include?(arguments[0]) Help.print_concise_help return true end if arguments[0] == "help" target = arguments[1] || "" if target.empty? || %w[-h --help].include?(target) Help.print_concise_help return true end return true if Help.print_command_help(target) raise Error.usage(Suggest.(target)) end help_position = arguments.index { |argument| %w[--help -h].include?(argument) } if help_position if help_position.zero? Help.print_concise_help return true end command = arguments[0] return true if Help.print_command_help(command) raise Error.usage("unknown command: #{command}") end false end |
#merge_selected_package_update(previous, updated, selected_package) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/pray/cli/commands/workflow.rb', line 115 def merge_selected_package_update(previous, updated, selected_package) merged = updated.dup merged.package = updated.package.map do |package| next package if package.name == selected_package previous_package = previous.package.find { |entry| entry.name == package.name } previous_package ? package.dup.tap { |copy| copy.version = previous_package.version } : package end merged end |
#outdated_command(_arguments) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/pray/cli/commands/packages.rb', line 94 def outdated_command(_arguments) previous_lockfile = File.exist?(lockfile_path) ? Pray.read_lockfile(lockfile_path) : nil project = resolve_current_project rendered = Render.render_project(project) latest_lockfile = build_lockfile(project, rendered) puts "Outdated packages" if previous_lockfile && Pray.lockfiles_equivalent?(latest_lockfile, previous_lockfile) puts "All packages up to date" else Plan.package_summary_lines(previous_lockfile, latest_lockfile, project).each { |line| puts line } end end |
#package_command ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/pray/cli/commands/packages.rb', line 54 def package_command project = resolve_current_project project.packages.each do |package| output_path = Archive.package_archive_path(package.declaration.name, package.spec.version) Archive.write_package_archive(package, output_path) end end |
#package_source_summary(package) ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/pray/cli/helpers.rb', line 119 def package_source_summary(package) if package.declaration.path "path:#{package.declaration.path}" elsif package.declaration.source "source:#{package.declaration.source}" else "root:#{package.root}" end end |
#parse_add_arguments(arguments) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/pray/cli/parse.rb', line 86 def parse_add_arguments(arguments) name = arguments.shift raise Error.unsupported("add requires a package name") unless name constraint = nil path = nil while (argument = arguments.shift) case argument when "--path" path = arguments.shift else constraint ||= argument end end {name: name, constraint: constraint, path: path} end |
#parse_bool_flag(value) ⇒ Object
143 144 145 146 147 148 149 150 |
# File 'lib/pray/cli/parse_trust.rb', line 143 def parse_bool_flag(value) case value.downcase when "true", "1", "yes", "on" then true when "false", "0", "no", "off" then false else raise Error.unsupported("expected true|false, got #{value}") end end |
#parse_command(arguments) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/pray/cli/parse.rb', line 8 def parse_command(arguments) arguments = arguments.dup flags = { check: extract_flag!(arguments, "--check"), strict: extract_flag!(arguments, "--strict"), semantic: extract_flag!(arguments, "--semantic"), locked: false, frozen: false, offline: false, targets: [] } arguments.each do |argument| case argument when "--locked" then flags[:locked] = true when "--frozen" then flags[:locked] = flags[:frozen] = true when "--offline" then flags[:offline] = true end end arguments.reject! { |argument| %w[--locked --frozen --offline].include?(argument) } command = arguments.shift raise Error.usage("pray requires a command; run pray --help") unless command case command when "manifest" then [:manifest] when "init" targets = [] while (argument = arguments.shift) if argument == "--targets" targets = arguments.shift.to_s.split(",").map(&:strip).reject(&:empty?) end end [:init, targets] when "prayer" raise Error.unsupported("prayer requires init") unless arguments.shift == "init" [:prayer_init] when "repo" raise Error.unsupported("repo requires init") unless arguments.shift == "init" [:repo_init] when "install" then [:install, flags] when "add" then [:add, parse_add_arguments(arguments)] when "remove" then [:remove, arguments.shift] when "update" then [:update, arguments] when "unlock" then [:unlock, arguments.shift] when "render" then [:render, flags] when "plan" then [:plan, arguments] when "apply" then [:apply] when "verify" then [:verify, flags] when "drift" then [:drift, flags] when "format", "fmt" then [:format] when "package" then [:package] when "publish" then [:publish, parse_publish_arguments(arguments)] when "login" then [:login, parse_login_arguments(arguments)] when "serve" then [:serve, parse_serve_arguments(arguments)] when "confess" then [:confess, parse_confess_arguments(arguments)] when "list" then [:list] when "outdated" then [:outdated, arguments] when "explain" then [:explain, arguments.shift] when "vendor" then [:vendor] when "clean" then [:clean] when "tree" then [:tree] when "sync" then [:sync, parse_sync_arguments(arguments)] when "trust" then parse_trust_command(arguments) when "version", "-V", "--version" then [:version] else raise Error.usage(Suggest.(command)) end end |
#parse_confess_arguments(arguments) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/pray/cli/parse_auth.rb', line 45 def parse_confess_arguments(arguments) package = nil from_lock = nil version = nil accepted = false rejected = false note = nil url = nil while (argument = arguments.shift) case argument when "--from-lock" then from_lock = arguments.shift when "--version" then version = arguments.shift when "--accepted" then accepted = true when "--rejected" then rejected = true when "--note" then note = arguments.shift when "--url" then url = arguments.shift when /\A-/ then raise Error.unsupported("unknown confess argument: #{argument}") else package = argument end end if accepted == rejected raise Error.unsupported("confess requires exactly one of --accepted or --rejected") end if package && from_lock raise Error.unsupported("confess accepts either a package name or --from-lock") end raise Error.unsupported("confess requires a package name") if package.nil? && from_lock.nil? {package: package, from_lock: from_lock, version: version, accepted: accepted, rejected: rejected, note: note, url: url} end |
#parse_login_arguments(arguments) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/pray/cli/parse_auth.rb', line 5 def parse_login_arguments(arguments) servers = [] email = nil passkey_key = nil credential_id = nil ssh_agent = false public_key = nil while (argument = arguments.shift) case argument when "--server" then servers << arguments.shift when "--email" then email = arguments.shift when "--passkey-key" then passkey_key = arguments.shift when "--credential-id" then credential_id = arguments.shift when "--ssh-agent" then ssh_agent = true when "--public-key" then public_key = arguments.shift else raise Error.unsupported("unknown login argument: #{argument}") end end raise Error.unsupported("login requires --server URL") if servers.empty? raise Error.unsupported("login requires --email EMAIL") if email.to_s.empty? passkey = passkey_key || credential_id if passkey && ssh_agent raise Error.unsupported("login accepts either passkey or ssh-agent mode, not both") end if passkey_key raise Error.unsupported("passkey login requires --credential-id") if credential_id.to_s.empty? {servers: servers, email: email, mode: :passkey, passkey_key: passkey_key, credential_id: credential_id} elsif ssh_agent raise Error.unsupported("ssh-agent login requires --public-key") if public_key.to_s.empty? {servers: servers, email: email, mode: :ssh_agent, public_key: public_key} else raise Error.unsupported("login requires --passkey-key/--credential-id or --ssh-agent") end end |
#parse_publish_arguments(arguments) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/pray/cli/parse.rb', line 103 def parse_publish_arguments(arguments) roots = [] servers = [] while (argument = arguments.shift) case argument when "--root" roots << arguments.shift when "--server" servers << arguments.shift else raise Error.unsupported("unexpected publish argument: #{argument}") end end raise Error.unsupported("publish requires at least one --root PATH or --server URL") if roots.empty? && servers.empty? {roots: roots, servers: servers} end |
#parse_serve_arguments(arguments) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/pray/cli/parse.rb', line 121 def parse_serve_arguments(arguments) = {root: ".", host: "127.0.0.1", port: 7429, stdio: false} while (argument = arguments.shift) case argument when "--root" then [:root] = arguments.shift when "--host" then [:host] = arguments.shift when "--port" then [:port] = Integer(arguments.shift) when "--stdio" then [:stdio] = true else raise Error.unsupported("unexpected serve argument: #{argument}") end end end |
#parse_sync_arguments(arguments) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/pray/cli/parse_auth.rb', line 77 def parse_sync_arguments(arguments) root = "." peers = [] while (argument = arguments.shift) case argument when "--root" then root = arguments.shift when "--peer" then peers << arguments.shift else raise Error.unsupported("unknown sync argument: #{argument}") end end {root: root, peers: peers} end |
#parse_trust_command(arguments) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/pray/cli/parse_trust.rb', line 5 def parse_trust_command(arguments) subcommand = arguments.shift raise Error.unsupported("trust requires a subcommand") unless subcommand case subcommand when "list" then [:trust_list, parse_trust_list_arguments(arguments)] when "show" raise Error.unsupported("unknown trust show argument: #{arguments.first}") if arguments.any? [:trust_show] when "add-key" then [:trust_add_key, parse_trust_key_arguments(arguments, "add-key")] when "remove-key", "revoke" [:trust_remove_key, parse_trust_key_arguments(arguments, "remove-key")] when "set-signed" then [:trust_set_signed, parse_trust_set_signed_arguments(arguments)] when "set-allow" then [:trust_set_allow, parse_trust_set_allow_arguments(arguments)] when "import-repo" then [:trust_import_repo, parse_trust_import_repo_arguments(arguments)] when "import-registry" [:trust_import_registry, parse_trust_import_registry_arguments(arguments)] when "check" source = arguments.shift raise Error.unsupported("trust check accepts at most one SOURCE argument") if arguments.any? [:trust_check, source] else raise Error.unsupported("unknown trust command: #{subcommand}") end end |
#parse_trust_import_registry_arguments(arguments) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/pray/cli/parse_trust.rb', line 123 def parse_trust_import_registry_arguments(arguments) source_url = arguments.shift raise Error.unsupported("trust import-registry requires SOURCE_URL") unless source_url match_prefix = nil include_host_key = source_url.start_with?("pray+ssh://", "ssh+pray://") while (argument = arguments.shift) case argument when "--match-prefix" match_prefix = arguments.shift raise Error.unsupported("--match-prefix requires VALUE") unless match_prefix when "--host-key" then include_host_key = true when "--no-host-key" then include_host_key = false else raise Error.unsupported("unknown trust import-registry argument: #{argument}") end end {source_url: source_url, match_prefix: match_prefix, include_host_key: include_host_key} end |
#parse_trust_import_repo_arguments(arguments) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/pray/cli/parse_trust.rb', line 107 def parse_trust_import_repo_arguments(arguments) source_url = arguments.shift raise Error.unsupported("trust import-repo requires SOURCE_URL") unless source_url match_prefix = nil while (argument = arguments.shift) if argument == "--match-prefix" match_prefix = arguments.shift raise Error.unsupported("--match-prefix requires VALUE") unless match_prefix else raise Error.unsupported("unknown trust import-repo argument: #{argument}") end end {source_url: source_url, match_prefix: match_prefix} end |
#parse_trust_key_arguments(arguments, label) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/pray/cli/parse_trust.rb', line 47 def parse_trust_key_arguments(arguments, label) key = arguments.shift raise Error.unsupported("trust #{label} requires KEY") unless key match_prefix = nil while (argument = arguments.shift) if argument == "--match-prefix" match_prefix = arguments.shift raise Error.unsupported("--match-prefix requires VALUE") unless match_prefix else raise Error.unsupported("unknown trust #{label} argument: #{argument}") end end {key: key, match_prefix: match_prefix} end |
#parse_trust_list_arguments(arguments) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/pray/cli/parse_trust.rb', line 33 def parse_trust_list_arguments(arguments) scope = :all source_url = nil arguments.each do |argument| case argument when "--global" then scope = :global when "--local" then scope = :local when /\A-/ then raise Error.unsupported("unknown trust list argument: #{argument}") else source_url = argument end end {scope: scope, source_url: source_url} end |
#parse_trust_set_allow_arguments(arguments) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/pray/cli/parse_trust.rb', line 85 def parse_trust_set_allow_arguments(arguments) match_prefix = nil allow = true while (argument = arguments.shift) case argument when "--match-prefix" match_prefix = arguments.shift raise Error.unsupported("--match-prefix requires VALUE") unless match_prefix when "--allow" value = arguments.shift raise Error.unsupported("--allow requires true|false") unless value allow = parse_bool_flag(value) else raise Error.unsupported("unknown trust set-allow argument: #{argument}") end end raise Error.unsupported("trust set-allow requires --match-prefix PREFIX") unless match_prefix {match_prefix: match_prefix, allow: allow} end |
#parse_trust_set_signed_arguments(arguments) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/pray/cli/parse_trust.rb', line 63 def parse_trust_set_signed_arguments(arguments) match_prefix = nil enabled = true while (argument = arguments.shift) case argument when "--match-prefix" match_prefix = arguments.shift raise Error.unsupported("--match-prefix requires VALUE") unless match_prefix when "--enabled" value = arguments.shift raise Error.unsupported("--enabled requires true|false") unless value enabled = parse_bool_flag(value) else raise Error.unsupported("unknown trust set-signed argument: #{argument}") end end raise Error.unsupported("trust set-signed requires --match-prefix PREFIX") unless match_prefix {match_prefix: match_prefix, enabled: enabled} end |
#plan_command(_arguments) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/pray/cli/commands/workflow.rb', line 72 def plan_command(_arguments) project = Invocation.resolve_current_project_with_git_refresh_fallback( ResolveOptions.new, allow_git_refresh_fallback: true ) rendered = Render.render_project(project) lockfile = build_lockfile(project, rendered) previous_lockfile = File.exist?(lockfile_path) ? Pray.read_lockfile(lockfile_path) : nil preview = Plan.build_materialization_preview( project, rendered, lockfile, lockfile_path, previous_lockfile ) Plan.print_materialization_report(preview, :plan) end |
#prayer_init_command ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/pray/cli/commands/init.rb', line 28 def prayer_init_command root = Dir.pwd package_name = File.basename(root) package_name = "prayer-package" if package_name.strip.empty? prayspec_path = File.join(root, "#{package_name}.prayspec") raise Error.manifest("package spec already exists: #{prayspec_path}") if File.exist?(prayspec_path) File.write( prayspec_path, <<~SPEC Package::Specification.new do |spec| spec.name = "#{package_name}" spec.version = "0.1.0" spec.summary = "Prayer package" spec.files = [] end SPEC ) end |
#project_root ⇒ Object
15 16 17 |
# File 'lib/pray/cli/helpers.rb', line 15 def project_root Invocation.project_root end |
#publish_command(roots:, servers:) ⇒ Object
5 6 7 8 9 |
# File 'lib/pray/cli/commands/distribution.rb', line 5 def publish_command(roots:, servers:) project = resolve_current_project roots.each { |root| Publish.publish_to_root(project, root) } servers.each { |server| Publish.publish_to_server(project, server) } end |
#remove_command(name) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/pray/cli/commands/packages.rb', line 21 def remove_command(name) raise Error.manifest("remove requires a package name") unless name manifest_path_value = manifest_path manifest_text = Pray.read_manifest_text(manifest_path_value) manifest = Pray.parse_manifest(manifest_text) unless manifest.packages.any? { |package| package.name == name } raise Error.manifest("package #{name} not found") end File.write(manifest_path_value, remove_manifest_statement(manifest_text, name)) install_command({locked: false, frozen: false, offline: false}) end |
#remove_manifest_statement(text, name) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/pray/cli/helpers.rb', line 80 def remove_manifest_statement(text, name) lines = text.lines.map(&:chomp) package_prefix = "agent \"#{name}\"" alternate_prefix = "agent '#{name}'" index = lines.index do |line| trimmed = line.lstrip trimmed.start_with?(package_prefix, alternate_prefix) end if index lines.delete_at(index) lines.delete_at(index) if index < lines.length && lines[index].strip.empty? lines.delete_at(index - 1) if index.positive? && lines[index - 1].strip.empty? end output = lines.join("\n") output += "\n" unless output.end_with?("\n") output end |
#remove_path_if_exists(path) ⇒ Object
160 161 162 163 164 |
# File 'lib/pray/cli/helpers.rb', line 160 def remove_path_if_exists(path) return unless File.exist?(path) File.directory?(path) ? FileUtils.rm_rf(path) : File.delete(path) end |
#render_command(flags) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/pray/cli/commands/workflow.rb', line 17 def render_command(flags) project = resolve_current_project rendered = Render.render_project(project) if flags[:check] ensure_rendered_outputs_current(project, rendered) else Render.write_rendered_targets(project, rendered) end end |
#render_tree_node(package, package_map, depth, ancestry, lines) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/pray/cli/helpers.rb', line 141 def render_tree_node(package, package_map, depth, ancestry, lines) indent = " " * depth lines << "#{indent}#{package.declaration.name} #{package.spec.version}" return unless ancestry.add?(package.declaration.name) package.spec.dependencies.each do |dependency| resolved = package_map[dependency.name] if resolved if ancestry.include?(resolved.declaration.name) lines << "#{indent} #{resolved.declaration.name} #{resolved.spec.version} (cycle)" else render_tree_node(resolved, package_map, depth + 1, ancestry, lines) end else lines << "#{indent} #{dependency.name} (missing)" end end end |
#repo_distribution_root(root) ⇒ Object
58 59 60 |
# File 'lib/pray/cli/commands/init.rb', line 58 def repo_distribution_root(root) (File.basename(root) == "prayers") ? root : File.join(root, "prayers") end |
#repo_init_command ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/pray/cli/commands/init.rb', line 48 def repo_init_command distribution_root = repo_distribution_root(Dir.pwd) index_path = File.join(distribution_root, "v1", "index.json") raise Error.manifest("distribution repo already exists") if File.exist?(index_path) FileUtils.mkdir_p(File.join(distribution_root, "v1", "packages")) FileUtils.mkdir_p(File.join(distribution_root, "v1", "artifacts")) Publish.write_registry_index(distribution_root, RegistryIndex.new) end |
#resolve_current_project(options = ResolveOptions.new) ⇒ Object
19 20 21 |
# File 'lib/pray/cli/helpers.rb', line 19 def resolve_current_project( = ResolveOptions.new) Invocation.resolve_current_project() end |
#run(arguments) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/pray/cli.rb', line 23 def run(arguments) arguments = arguments.dup if arguments.delete("--no-input") ENV["PRAY_NO_INPUT"] = "1" end arguments = Invocation.initialize(arguments) return if maybe_print_help(arguments) command = parse_command(arguments) dispatch(command) end |
#serve_command(root:, host:, port:, stdio:) ⇒ Object
11 12 13 14 15 |
# File 'lib/pray/cli/commands/distribution.rb', line 11 def serve_command(root:, host:, port:, stdio:) raise Error.unsupported("serve --stdio is not implemented yet in pray-cli Ruby") if stdio Serve.run_server(root: root, host: host, port: port) end |
#sync_command(root:, peers:) ⇒ Object
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/pray/cli/commands/auth.rb', line 31 def sync_command(root:, peers:) peer_sources = if peers.empty? Sync.load_sync_peers(root).map { |peer| peer["url"] } else peers end summary = Sync.synchronize_registry(root, peer_sources) puts "Synchronized #{summary[:packages]} package(s) from #{summary[:peers]} peer(s); " \ "learned #{summary[:known_peers]} peer(s)" end |
#tree_command ⇒ Object
44 45 46 47 48 49 50 51 52 |
# File 'lib/pray/cli/commands/packages.rb', line 44 def tree_command project = resolve_current_project package_map = project.packages.to_h { |package| [package.declaration.name, package] } lines = ["Dependency tree"] project.packages.each do |package| render_tree_node(package, package_map, 0, Set.new, lines) end puts lines.join("\n") end |
#trust_add_key_command(key, match_prefix: nil) ⇒ Object
13 14 15 |
# File 'lib/pray/cli/commands/trust.rb', line 13 def trust_add_key_command(key, match_prefix: nil) Trust.add_allowed_signing_key(key, match_prefix: match_prefix) end |
#trust_check_command(source = nil) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/pray/cli/commands/trust.rb', line 52 def trust_check_command(source = nil) source_description, hits = Trust.check_compromised(source) if hits.empty? puts "no compromised trusted signing keys detected (checked against #{source_description})" return end hits.each do |key, scopes, matches| puts "[compromised] #{key}" puts " scopes: #{scopes.join(", ")}" matches.each do |entry| puts " reason: #{entry.reason}" if entry.reason puts " reference: #{entry.reference}" if entry.reference puts " reported_at: #{entry.reported_at}" if entry.reported_at end end raise Error.integrity( "found #{hits.length} compromised trusted key(s) in #{source_description}" ) end |
#trust_import_registry_command(source_url, match_prefix: nil, include_host_key: false) ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/pray/cli/commands/trust.rb', line 44 def trust_import_registry_command(source_url, match_prefix: nil, include_host_key: false) result = Trust.import_registry( source_url, match_prefix: match_prefix, include_host_key: include_host_key ) puts "imported #{result[:publishers_added]} publisher fingerprint(s) and " \ "#{result[:host_keys_added]} host key(s) for #{match_prefix || source_url}" end |
#trust_import_repo_command(source_url, match_prefix: nil) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/pray/cli/commands/trust.rb', line 29 def trust_import_repo_command(source_url, match_prefix: nil) clone_url = source_url.delete_prefix("git+") repository = GitSources.git_source_cache_directory(Dir.pwd, clone_url) unless File.directory?(File.join(repository, ".git")) raise Error.resolution( "no cached git repository for #{clone_url} at #{repository}" ) end added = Trust.import_repo( clone_url, repository, match_prefix: match_prefix || clone_url ) puts "imported #{added} key(s) from #{repository}" end |
#trust_list_command(scope: :all, source_url: nil) ⇒ Object
5 6 7 |
# File 'lib/pray/cli/commands/trust.rb', line 5 def trust_list_command(scope: :all, source_url: nil) puts Trust.list_policy(scope: scope, source_url: source_url) end |
#trust_remove_key_command(key, match_prefix: nil) ⇒ Object
17 18 19 |
# File 'lib/pray/cli/commands/trust.rb', line 17 def trust_remove_key_command(key, match_prefix: nil) Trust.remove_allowed_signing_key(key, match_prefix: match_prefix) end |
#trust_set_allow_command(match_prefix:, allow:) ⇒ Object
25 26 27 |
# File 'lib/pray/cli/commands/trust.rb', line 25 def trust_set_allow_command(match_prefix:, allow:) Trust.set_allow(match_prefix, allow) end |
#trust_set_signed_command(match_prefix:, enabled:) ⇒ Object
21 22 23 |
# File 'lib/pray/cli/commands/trust.rb', line 21 def trust_set_signed_command(match_prefix:, enabled:) Trust.set_require_signed_commit(match_prefix, enabled) end |
#trust_show_command ⇒ Object
9 10 11 |
# File 'lib/pray/cli/commands/trust.rb', line 9 def trust_show_command puts Trust.show_policy_toml end |
#unlock_command(name) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/pray/cli/commands/workflow.rb', line 98 def unlock_command(name) raise Error.manifest("unlock requires a package name") unless name project = resolve_current_project unless project.manifest.packages.any? { |entry| entry.name == name } raise Error.manifest("package #{name} not found") end previous_lockfile = Pray.read_lockfile(lockfile_path) rendered = Render.render_project(project) updated_lockfile = build_lockfile(project, rendered) merged_lockfile = merge_selected_package_update(previous_lockfile, updated_lockfile, name) Pray.write_lockfile(lockfile_path, merged_lockfile) Render.write_rendered_targets(project, rendered) puts "Unlocked #{name}" end |
#update_command(arguments) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/pray/cli/commands/workflow.rb', line 86 def update_command(arguments) package = arguments.reject { |argument| argument.start_with?("--") }.first offline = arguments.include?("--offline") if package manifest = Pray.parse_manifest(Pray.read_manifest_text(manifest_path)) unless manifest.packages.any? { |entry| entry.name == package } raise Error.manifest("package #{package} not found") end end install_command({locked: false, frozen: false, offline: offline, refresh: true}) end |
#verify_command(flags) ⇒ Object
27 28 29 30 31 32 |
# File 'lib/pray/cli/commands/workflow.rb', line 27 def verify_command(flags) project = resolve_current_project lockfile = ensure_existing_lockfile(lockfile_path) report = Verify.verify_project(project, lockfile, strict: flags[:strict]) puts format_verification_report(report) unless report.clean? end |