pray-cli 1.18.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91a549f989bb5872cf7307c16101a89c479bda9f919dd4f969917a80f4bf5958
4
- data.tar.gz: 01a7042cad4e383a95ca2b15d698b9e00a46707d27b2885381ce57f6775cb15b
3
+ metadata.gz: 6df9a00a7c009e00fdd00987564489607a77bf48cb6472e06951c7709a91a32f
4
+ data.tar.gz: 93ad851e71a69c13764f2a289d3f32dd7856a749aa341ef728b4c49ebc651149
5
5
  SHA512:
6
- metadata.gz: 52f904573df3f97eb3ad240388db1ac7d81d36cd66fe24b43be8cf32f392d59abf6283fc496a92b9844e40cec4d7058bf8db54fb97716164635c395c95a27796
7
- data.tar.gz: ccc7110154721dbc019d02c37ecdbeaaac225ccf702e8d1007cfe3af4b3f54f35627876fb78f15eb5617e691c7c7ca7016c9c05853b1719655545a087baf8eef
6
+ metadata.gz: 56060ecc2267d2f8a2c1b555591b3db551383d8350a9b3125a0647831ee2438dfb3f78b6424e2af98bbfc184ef8a91c181e1da5bf35835a160f34bcde865c1b0
7
+ data.tar.gz: 55b5590131213f639bc63be84817d65c17297354a1387b363c94d8953192ca03f80c9245b47d5cc1d7d99cd51569c2a9647147fb0de124966dfb294e125bf68b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.19.0 (2026-09-18)
4
+
5
+ - Declare named `publish` remotes in Prayfile (RFC 0118). `pray publish` uses them when dest flags are omitted, and publishes only path-owned packages.
6
+
3
7
  ## 1.18.1 (2026-09-17)
4
8
 
5
9
  - Fix `pray package` and `pray publish` when the CLI cannot create a staging directory.
@@ -2,16 +2,64 @@
2
2
 
3
3
  module Pray
4
4
  module CLI
5
- def publish_command(roots:, servers:)
5
+ def publish_command(roots:, servers:, to: [], dry_run: false)
6
6
  project = resolve_current_project
7
- roots.each { |root| Publish.publish_to_root(project, root) }
8
- servers.each { |server| Publish.publish_to_server(project, server) }
7
+ dests = PublishSelect.resolve_publish_destinations(
8
+ project.manifest.publish_remotes || [],
9
+ PublishSelect::PublishCliDest.new(to: to, roots: roots, servers: servers),
10
+ Dir.pwd
11
+ )
12
+ if dry_run
13
+ print_publish_plan(project, dests)
14
+ return
15
+ end
16
+ dests.each do |dest|
17
+ packages = selected_publish_packages(project, dest.packages)
18
+ filtered = project.dup
19
+ filtered.packages = packages
20
+ Publish.publish_to_root(filtered, dest.root) if dest.root
21
+ Publish.publish_to_server(filtered, dest.server) if dest.server
22
+ end
9
23
  end
10
24
 
11
- def serve_command(root:, host:, port:, stdio:)
25
+ def selected_publish_packages(project, listed)
26
+ allowed = PublishRemote.allowed_publish_names(project.manifest, listed)
27
+ selected = project.packages.select { |package| allowed.include?(package.declaration.name) }
28
+ if selected.empty?
29
+ raise Error.usage("no path packages to publish; remote dependencies are not published")
30
+ end
31
+ selected.each { |package| package.spec.require_release_version! }
32
+ selected
33
+ end
34
+
35
+ def print_publish_plan(project, dests)
36
+ dests.each do |dest|
37
+ packages = selected_publish_packages(project, dest.packages)
38
+ target = dest.root || dest.server || dest.name
39
+ packages.each do |package|
40
+ puts "publish #{package.declaration.name} #{package.spec.version} -> #{dest.name} (#{target})"
41
+ end
42
+ end
43
+ end
44
+
45
+ def serve_command(root:, host:, port:, stdio:, to: nil)
12
46
  raise Error.unsupported("serve --stdio is not implemented yet in pray-cli Ruby") if stdio
13
47
 
14
- Serve.run_server(root: root, host: host, port: port)
48
+ Serve.run_server(root: optional_path_remote_root(to, root), host: host, port: port)
49
+ end
50
+
51
+ def optional_path_remote_root(to, root)
52
+ remotes = begin
53
+ Pray.parse_manifest(Pray.read_manifest_text(manifest_path)).publish_remotes || []
54
+ rescue Error
55
+ return root if to.nil?
56
+
57
+ raise
58
+ end
59
+ return root if remotes.empty? && to.nil?
60
+
61
+ cli_root = (root == ".") ? nil : root
62
+ PublishSelect.resolve_path_remote(remotes, to, cli_root, Dir.pwd)
15
63
  end
16
64
  end
17
65
  end
@@ -34,6 +34,32 @@ module Pray
34
34
  FileUtils.mkdir_p(File.join(distribution_root, "v1", "artifacts"))
35
35
  Publish.write_registry_index(distribution_root, RegistryIndex.new)
36
36
  Distribution.write_settings(distribution_root)
37
+ maybe_declare_publish_remote(Dir.pwd, distribution_root)
38
+ end
39
+
40
+ def maybe_declare_publish_remote(project_root, distribution_root)
41
+ manifest_path_value = File.join(project_root, "Prayfile")
42
+ return unless File.exist?(manifest_path_value)
43
+
44
+ text = File.read(manifest_path_value)
45
+ manifest = Pray.parse_manifest(text)
46
+ return unless (manifest.publish_remotes || []).empty?
47
+
48
+ relative = if distribution_root == project_root
49
+ "."
50
+ else
51
+ prefix = project_root.end_with?("/") ? project_root : "#{project_root}/"
52
+ distribution_root.start_with?(prefix) ? distribution_root.delete_prefix(prefix).tr("\\", "/") : "prayers"
53
+ end
54
+ statement = %(publish "prayers", path: "#{relative}")
55
+ lines = text.split("\n")
56
+ insertion = lines.rindex { |line| line.lstrip.start_with?("source ") }
57
+ insertion ||= lines.index { |line| line.lstrip.start_with?("prayfile ") }
58
+ insertion = insertion ? insertion + 1 : 1
59
+ lines.insert(insertion, statement)
60
+ updated = lines.join("\n")
61
+ updated += "\n" unless updated.end_with?("\n")
62
+ File.write(manifest_path_value, updated)
37
63
  end
38
64
 
39
65
  def repo_distribution_root(root)
@@ -53,7 +53,12 @@ module Pray
53
53
 
54
54
  def package_command
55
55
  project = resolve_current_project
56
- project.packages.each do |package|
56
+ allowed = PublishRemote.path_owned_package_names(project.manifest)
57
+ packages = project.packages.select { |package| allowed.include?(package.declaration.name) }
58
+ if packages.empty?
59
+ raise Error.usage("no path packages to package; remote dependencies are not packed")
60
+ end
61
+ packages.each do |package|
57
62
  package.spec.require_release_version!
58
63
  output_path = Archive.package_archive_path(package.declaration.name, package.spec.version)
59
64
  Archive.write_package_archive(package, output_path)
data/lib/pray/cli/help.rb CHANGED
@@ -23,9 +23,9 @@ module Pray
23
23
  ].freeze
24
24
 
25
25
  DISTRIBUTION_COMMANDS = [
26
- "publish --root PATH [--server URL ...]",
26
+ "publish [--root PATH|--server URL|--to NAME] [--dry-run]",
27
27
  "login --server URL --email EMAIL",
28
- "serve [--root PATH] [--host HOST] [--port PORT] [--stdio]",
28
+ "serve [--root PATH | --to NAME] [--host HOST] [--port PORT] [--stdio]",
29
29
  "sync [--root PATH] [--peer URL ...]",
30
30
  "confess <package> | --from-lock SPAN_ID [--accepted|--rejected]"
31
31
  ].freeze
@@ -146,9 +146,11 @@ module Pray
146
146
  "vendor" => "copy resolved packages locally\n\nUsage: pray vendor",
147
147
  "clean" => "remove local cache and vendor trees, or only unused registry entries\n\nUsage: pray clean [--unused]",
148
148
  "publish" => <<~TEXT.strip,
149
- upload packages to a registry or local root
149
+ upload path packages to a registry or local root
150
150
 
151
- Usage: pray publish --root PATH [--server URL ...]
151
+ Usage: pray publish [--root PATH] [--server URL ...] [--to NAME] [--dry-run]
152
+
153
+ Prayfile publish remotes supply dests when flags are omitted.
152
154
  TEXT
153
155
  "login" => <<~TEXT.strip,
154
156
  authenticate to a registry server
@@ -158,7 +160,7 @@ module Pray
158
160
  "serve" => <<~TEXT.strip,
159
161
  run a local registry server
160
162
 
161
- Usage: pray serve [--root PATH] [--host HOST] [--port PORT] [--stdio]
163
+ Usage: pray serve [--root PATH | --to NAME] [--host HOST] [--port PORT] [--stdio]
162
164
  TEXT
163
165
  "sync" => <<~TEXT.strip,
164
166
  sync packages with peer registries
@@ -141,26 +141,33 @@ module Pray
141
141
  def parse_publish_arguments(arguments)
142
142
  roots = []
143
143
  servers = []
144
+ to = []
145
+ dry_run = false
144
146
  while (argument = arguments.shift)
145
147
  case argument
146
148
  when "--root"
147
149
  roots << arguments.shift
148
150
  when "--server"
149
151
  servers << arguments.shift
152
+ when "--to"
153
+ to << arguments.shift
154
+ when "--dry-run"
155
+ dry_run = true
156
+ when "--signing-key"
157
+ arguments.shift
150
158
  else
151
159
  raise Error.unsupported("unexpected publish argument: #{argument}")
152
160
  end
153
161
  end
154
- raise Error.unsupported("publish requires at least one --root PATH or --server URL") if roots.empty? && servers.empty?
155
-
156
- {roots: roots, servers: servers}
162
+ {roots: roots, servers: servers, to: to, dry_run: dry_run}
157
163
  end
158
164
 
159
165
  def parse_serve_arguments(arguments)
160
- options = {root: ".", host: "127.0.0.1", port: 7429, stdio: false}
166
+ options = {root: ".", to: nil, host: "127.0.0.1", port: 7429, stdio: false}
161
167
  while (argument = arguments.shift)
162
168
  case argument
163
169
  when "--root" then options[:root] = arguments.shift
170
+ when "--to" then options[:to] = arguments.shift
164
171
  when "--host" then options[:host] = arguments.shift
165
172
  when "--port" then options[:port] = Integer(arguments.shift)
166
173
  when "--stdio" then options[:stdio] = true
@@ -79,6 +79,7 @@ module Pray
79
79
  targets: [],
80
80
  packages: manifest.packages.map { |package| clone_package(package) },
81
81
  local: manifest.local.map { |local| local.dup },
82
+ publish_remotes: (manifest.publish_remotes || []).map(&:dup),
82
83
  symbols: manifest.symbols.dup,
83
84
  render: manifest.render.dup
84
85
  )
@@ -12,6 +12,11 @@ module Pray
12
12
  manifest.sources.each { |source| lines << format_source(source) }
13
13
  end
14
14
 
15
+ unless (manifest.publish_remotes || []).empty?
16
+ lines << ""
17
+ manifest.publish_remotes.each { |remote| lines << format_publish_remote(remote) }
18
+ end
19
+
15
20
  unless manifest.symbols.empty?
16
21
  lines << ""
17
22
  lines << "pray do"
@@ -109,6 +114,18 @@ module Pray
109
114
  parts.join(", ")
110
115
  end
111
116
 
117
+ def format_publish_remote(remote)
118
+ parts = [%(publish "#{remote.name}")]
119
+ parts << %(path: "#{remote.path}") if remote.path
120
+ parts << %("#{remote.url}") if remote.url
121
+ return parts.join(", ") if remote.packages.empty?
122
+
123
+ lines = ["#{parts.join(", ")} do"]
124
+ remote.packages.each { |name| lines << %( pray "#{name}") }
125
+ lines << "end"
126
+ lines.join("\n")
127
+ end
128
+
112
129
  def format_destination_entry(entry, manifest)
113
130
  if entry.kind == "local"
114
131
  return %(pray "#{entry.path}")
data/lib/pray/manifest.rb CHANGED
@@ -4,8 +4,11 @@ require_relative "manifest_json"
4
4
  require_relative "manifest_formatter"
5
5
  require_relative "manifest_parser_helpers"
6
6
  require_relative "manifest_parser_blocks"
7
+ require_relative "manifest_parser_publish"
7
8
  require_relative "manifest_parser"
8
9
  require_relative "path_safety"
10
+ require_relative "publish_remote"
11
+ require_relative "publish_select"
9
12
 
10
13
  module Pray
11
14
  RenderPolicy = Struct.new(
@@ -53,7 +56,7 @@ module Pray
53
56
  end
54
57
 
55
58
  Manifest = Struct.new(
56
- :prayfile_version, :sources, :targets, :packages, :local, :symbols, :render,
59
+ :prayfile_version, :sources, :targets, :packages, :local, :publish_remotes, :symbols, :render,
57
60
  :deprecated_keywords,
58
61
  keyword_init: true
59
62
  ) do
@@ -63,6 +66,7 @@ module Pray
63
66
  targets: [],
64
67
  packages: [],
65
68
  local: [],
69
+ publish_remotes: [],
66
70
  symbols: {},
67
71
  render: RenderPolicy.default,
68
72
  deprecated_keywords: []
@@ -99,6 +103,7 @@ module Pray
99
103
  copy.targets = targets.sort_by(&:name)
100
104
  copy.packages = packages.sort_by { |package| [package.name, package.source.to_s, package.constraint] }
101
105
  copy.local = local.sort_by(&:path)
106
+ copy.publish_remotes = (publish_remotes || []).sort_by(&:name)
102
107
  copy.deprecated_keywords = []
103
108
  end
104
109
  end
@@ -139,6 +144,7 @@ module Pray
139
144
  PathSafety.validate_project_relative_path!(local.path)
140
145
  PathSafety.validate_destination_path!(local.file) if local.file
141
146
  end
147
+ PublishRemote.validate_publish_remotes!(manifest)
142
148
  end
143
149
  end
144
150
 
@@ -17,10 +17,20 @@ module Pray
17
17
  "local" => manifest.local.map { |entry| local_fields(entry) }
18
18
  }
19
19
  fields["symbols"] = manifest.symbols.sort.to_h unless manifest.symbols.empty?
20
+ unless (manifest.publish_remotes || []).empty?
21
+ fields["publish_remotes"] = manifest.publish_remotes.map { |remote| publish_remote_fields(remote) }
22
+ end
20
23
  fields["render"] = render_fields(manifest.render)
21
24
  fields
22
25
  end
23
26
 
27
+ def publish_remote_fields(remote)
28
+ fields = {"name" => remote.name, "packages" => remote.packages}
29
+ fields["path"] = remote.path if remote.path
30
+ fields["url"] = remote.url if remote.url
31
+ fields
32
+ end
33
+
24
34
  def source_fields(source)
25
35
  fields = {
26
36
  "name" => source.name,
@@ -5,6 +5,7 @@ module Pray
5
5
  class BlockParser
6
6
  include ParserHelpers
7
7
  include ParserBlocks
8
+ include ParserPublish
8
9
 
9
10
  def initialize(lines)
10
11
  @lines = lines
@@ -41,6 +42,8 @@ module Pray
41
42
  manifest.prayfile_version = string_from_literal(Regexp.last_match(1))
42
43
  when /\Asource (.+)\z/
43
44
  manifest.sources << parse_source(Regexp.last_match(1))
45
+ when /\Apublish (.+)\z/
46
+ apply_publish(manifest, Regexp.last_match(1))
44
47
  when /\Atarget (.+)\z/
45
48
  apply_legacy_target(manifest, statement, Regexp.last_match(1), allow_target)
46
49
  when /\Agroup (.+)\z/
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pray
4
+ module ManifestMethods
5
+ module ParserPublish
6
+ def apply_publish(manifest, rest)
7
+ is_block = rest.rstrip.end_with?(" do")
8
+ header = rest.sub(/\s+do\z/, "").strip
9
+ remote = parse_publish_header(header)
10
+ parse_publish_block(remote) if is_block
11
+ manifest.publish_remotes << remote
12
+ end
13
+
14
+ def parse_publish_header(rest)
15
+ values, keywords = parse_call(rest)
16
+ raise Error.parse("manifest", "publish requires a name") if values.empty?
17
+
18
+ name = string_from_value(values.first)
19
+ if %w[git source signing_key token].any? { |key| keywords.key?(key) }
20
+ raise Error.parse(
21
+ "manifest",
22
+ "publish \"#{name}\" does not take git:, source:, signing_key:, or token:"
23
+ )
24
+ end
25
+ ManifestPublishRemote.new(
26
+ name: name,
27
+ path: keyword_string(keywords, "path"),
28
+ url: values[1] && string_from_value(values[1]),
29
+ packages: []
30
+ )
31
+ end
32
+
33
+ def parse_publish_block(remote)
34
+ while (statement = next_statement)
35
+ return if statement == "end"
36
+
37
+ pray_rest = statement[/\A(?:pray|use|include|agent|package) (.+)\z/, 1]
38
+ unless pray_rest
39
+ raise Error.parse("manifest", "publish blocks only support pray package names: #{statement}")
40
+ end
41
+
42
+ package = parse_package_decl(pray_rest)
43
+ if remote.packages.include?(package.name)
44
+ raise Error.parse("manifest", "duplicate package #{package.name} in publish \"#{remote.name}\"")
45
+ end
46
+ remote.packages << package.name
47
+ end
48
+ raise Error.parse("manifest", "missing 'end' for publish block")
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pray
4
+ ManifestPublishRemote = Struct.new(:name, :path, :url, :packages) do
5
+ def initialize(name:, path: nil, url: nil, packages: [])
6
+ super
7
+ end
8
+ end
9
+
10
+ module PublishRemote
11
+ module_function
12
+
13
+ def validate_publish_remotes!(manifest)
14
+ seen = {}
15
+ (manifest.publish_remotes || []).each do |remote|
16
+ raise Error.parse("manifest", "publish requires a name") if remote.name.to_s.strip.empty?
17
+ if seen[remote.name]
18
+ raise Error.manifest("duplicate publish remote: #{remote.name}")
19
+ end
20
+ seen[remote.name] = true
21
+ if remote.path && remote.url
22
+ raise Error.parse("manifest", "publish \"#{remote.name}\" must set path: or a URL, not both")
23
+ end
24
+ if remote.path.nil? && remote.url.nil?
25
+ raise Error.parse("manifest", "publish \"#{remote.name}\" requires path: or a URL")
26
+ end
27
+ PathSafety.validate_project_relative_path!(remote.path) if remote.path
28
+ if remote.url && !publish_url?(remote.url)
29
+ raise Error.parse(
30
+ "manifest",
31
+ "publish \"#{remote.name}\" URL must be https://, http://, pray+ssh://, or ssh+pray://"
32
+ )
33
+ end
34
+ validate_remote_packages!(manifest, remote)
35
+ end
36
+ end
37
+
38
+ def validate_remote_packages!(manifest, remote)
39
+ remote.packages.each do |package_name|
40
+ package = manifest.packages.find { |entry| entry.name == package_name }
41
+ unless package
42
+ raise Error.manifest("publish \"#{remote.name}\" lists unknown package #{package_name}")
43
+ end
44
+ next if package_is_path_owned?(package, manifest.sources)
45
+
46
+ raise Error.manifest(
47
+ "publish \"#{remote.name}\" lists #{package_name}, which is not a path package"
48
+ )
49
+ end
50
+ end
51
+
52
+ def package_is_path_owned?(package, sources)
53
+ return true if package.path
54
+ return false if package.git || package.tarball || package.oci
55
+
56
+ map = sources.to_h { |source| [source.name, source] }
57
+ name = ResolveSource.implied_source_name(package, map)
58
+ name && map[name]&.kind == "path"
59
+ rescue Error
60
+ false
61
+ end
62
+
63
+ def path_owned_package_names(manifest)
64
+ manifest.packages.select { |package| package_is_path_owned?(package, manifest.sources) }
65
+ .map(&:name)
66
+ end
67
+
68
+ def allowed_publish_names(manifest, listed)
69
+ listed.empty? ? path_owned_package_names(manifest) : listed
70
+ end
71
+
72
+ def publish_url?(url)
73
+ url.start_with?("https://", "http://", "pray+ssh://", "ssh+pray://")
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pray
4
+ module PublishSelect
5
+ module_function
6
+
7
+ PublishDestination = Struct.new(:name, :root, :server, :packages) do
8
+ def initialize(name:, root: nil, server: nil, packages: [])
9
+ super
10
+ end
11
+ end
12
+ PublishCliDest = Struct.new(:to, :roots, :servers) do
13
+ def initialize(to: [], roots: [], servers: [])
14
+ super
15
+ end
16
+ end
17
+
18
+ def resolve_publish_destinations(remotes, cli, project_root)
19
+ if !cli.to.empty? && (!cli.roots.empty? || !cli.servers.empty?)
20
+ raise Error.usage("publish --to cannot be combined with --root or --server")
21
+ end
22
+ return resolve_undeclared_destinations(cli) if remotes.empty?
23
+
24
+ select_remotes(remotes, cli, project_root).map do |remote|
25
+ PublishDestination.new(
26
+ name: remote.name,
27
+ root: remote.path && File.join(project_root, remote.path),
28
+ server: remote.url,
29
+ packages: remote.packages
30
+ )
31
+ end
32
+ end
33
+
34
+ def resolve_path_remote(remotes, to, root, project_root)
35
+ path_remotes = remotes.select(&:path)
36
+ if to
37
+ remote = remotes.find { |entry| entry.name == to }
38
+ raise Error.usage("unknown publish remote: #{to}") unless remote
39
+ unless remote.path
40
+ raise Error.usage("publish remote #{to} is a URL; yank, serve, and token need a path remote")
41
+ end
42
+ return File.join(project_root, remote.path)
43
+ end
44
+ if remotes.empty?
45
+ raise Error.usage("requires --root PATH") unless root
46
+
47
+ return root
48
+ end
49
+ if root
50
+ matched = remotes.find { |remote| remote.path && root_matches?(root, remote.path, project_root) }
51
+ raise Error.usage("path #{root} is not a declared publish remote") unless matched
52
+
53
+ return root
54
+ end
55
+ if path_remotes.length == 1 && path_remotes.first.path
56
+ return File.join(project_root, path_remotes.first.path)
57
+ end
58
+
59
+ raise Error.usage("say which path remote with --to NAME or --root PATH")
60
+ end
61
+
62
+ def resolve_undeclared_destinations(cli)
63
+ if !cli.to.empty?
64
+ raise Error.usage("Prayfile has no publish remotes; pass --root PATH or --server URL")
65
+ end
66
+ if cli.roots.empty? && cli.servers.empty?
67
+ raise Error.unsupported("publish requires at least one --root PATH or --server URL")
68
+ end
69
+
70
+ dests = cli.roots.map { |root| PublishDestination.new(name: root, root: root, packages: []) }
71
+ dests + cli.servers.map { |server| PublishDestination.new(name: server, server: server, packages: []) }
72
+ end
73
+
74
+ def select_remotes(remotes, cli, project_root)
75
+ unless cli.to.empty?
76
+ return cli.to.map do |name|
77
+ remote = remotes.find { |entry| entry.name == name }
78
+ raise Error.usage("unknown publish remote: #{name}") unless remote
79
+
80
+ remote
81
+ end
82
+ end
83
+ return remotes if cli.roots.empty? && cli.servers.empty?
84
+
85
+ selected = cli.roots.map do |root|
86
+ remote = remotes.find { |entry| entry.path && root_matches?(root, entry.path, project_root) }
87
+ raise Error.usage("path #{root} is not a declared publish remote") unless remote
88
+
89
+ remote
90
+ end
91
+ selected + cli.servers.map do |server|
92
+ remote = remotes.find { |entry| entry.url == server }
93
+ raise Error.usage("server #{server} is not a declared publish remote") unless remote
94
+
95
+ remote
96
+ end
97
+ end
98
+
99
+ def root_matches?(cli_root, remote_path, project_root)
100
+ declared = File.join(project_root, remote_path)
101
+ return true if cli_root == declared || cli_root == remote_path
102
+
103
+ strip_dot_slash(cli_root) == strip_dot_slash(remote_path)
104
+ end
105
+
106
+ def strip_dot_slash(value)
107
+ value.to_s.strip.delete_prefix("./").delete_suffix("/").tr("\\", "/")
108
+ end
109
+ end
110
+ end
data/lib/pray/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pray
4
- VERSION = "1.18.1"
5
- GENERATED_BY = "pray 1.18.1"
4
+ VERSION = "1.19.0"
5
+ GENERATED_BY = "pray 1.19.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pray-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.1
4
+ version: 1.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Makarov
@@ -156,6 +156,7 @@ files:
156
156
  - lib/pray/manifest_parser.rb
157
157
  - lib/pray/manifest_parser_blocks.rb
158
158
  - lib/pray/manifest_parser_helpers.rb
159
+ - lib/pray/manifest_parser_publish.rb
159
160
  - lib/pray/materialize.rb
160
161
  - lib/pray/package_spec.rb
161
162
  - lib/pray/package_spec_render.rb
@@ -164,6 +165,8 @@ files:
164
165
  - lib/pray/plan.rb
165
166
  - lib/pray/project_context.rb
166
167
  - lib/pray/publish.rb
168
+ - lib/pray/publish_remote.rb
169
+ - lib/pray/publish_select.rb
167
170
  - lib/pray/registry.rb
168
171
  - lib/pray/registry_http_cache.rb
169
172
  - lib/pray/registry_install.rb