toggle-local-spm 2.2.2 → 3.0.1
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 +4 -4
- data/README.md +14 -8
- data/lib/toggle_local_spm/cli.rb +27 -6
- data/lib/toggle_local_spm/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 32196698f6117197a108c6250d2adb35b2c3002166facfe7fb9298882fb0cc6d
|
|
4
|
+
data.tar.gz: 9eeaf34c8e8414ef256bb8a6874397f9ca072abf2824e886ca2e3af67b242452
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9259e3b22e9f7970d5bc752311fa3551fdd4b1d4a654116d19eb19b09ca625109a9b5578bac842ace1f374d481c7e3e465dd2eea92fde46ac5f834ad97318ffb
|
|
7
|
+
data.tar.gz: c6224ec033fee21369ec52e15a31f59e22a530f131d509c91be4ac281ac4a88496b60c66c87581cee7f7daeaba7834f2bdafb9d3974f1540a486a011860ef417
|
data/README.md
CHANGED
|
@@ -73,14 +73,20 @@ bundle exec toggle-local-spm
|
|
|
73
73
|
|
|
74
74
|
The interactive menu lists every direct dependency (from the project itself)
|
|
75
75
|
and every indirect one (from `Package.resolved`) as a table, each tagged with
|
|
76
|
-
its type, current state, and whether it has a
|
|
77
|
-
`spm-local-overrides.json` (see below),
|
|
76
|
+
its type, current state, and whether it has a known local checkout recorded
|
|
77
|
+
in `spm-local-overrides.json` (see below), followed by a legend explaining
|
|
78
|
+
the Managed column, e.g.:
|
|
78
79
|
|
|
79
80
|
```
|
|
80
|
-
# Package
|
|
81
|
-
1
|
|
82
|
-
2 DeviceKit
|
|
83
|
-
3
|
|
81
|
+
# Package Type State Managed
|
|
82
|
+
1 my-shared-ios 🎯 direct 📁 local ✅
|
|
83
|
+
2 DeviceKit 🎯 direct 🌏 remote ⚠️
|
|
84
|
+
3 my-model-lib 🧩 indirect 🌏 remote 📁
|
|
85
|
+
|
|
86
|
+
Legend:
|
|
87
|
+
✅ Local mock set
|
|
88
|
+
📁 Mock not set. Mock found (localPath in spm-local-overrides.json exists)
|
|
89
|
+
⚠️ Mock not set. Mock not found (localPath in spm-local-overrides.json not existing)
|
|
84
90
|
```
|
|
85
91
|
|
|
86
92
|
Each package toggles independently based on what's currently wired up in the
|
|
@@ -133,8 +139,8 @@ since the project genuinely, permanently depends on it.
|
|
|
133
139
|
|
|
134
140
|
An **indirect** dependency has no such entry — it's only known because it
|
|
135
141
|
shows up in `Package.resolved`, meaning some *other* dependency's own
|
|
136
|
-
`Package.swift` depends on it (e.g. `
|
|
137
|
-
`
|
|
142
|
+
`Package.swift` depends on it (e.g. `my-shared-ios` depending on
|
|
143
|
+
`my-model-lib`). Toggling one of these on doesn't edit that
|
|
138
144
|
other package's `Package.swift` at all. Instead it adds a brand-new,
|
|
139
145
|
*unlinked* local package reference directly to the project — not attached to
|
|
140
146
|
any target — purely so Xcode/SwiftPM's identity-based dependency resolution
|
data/lib/toggle_local_spm/cli.rb
CHANGED
|
@@ -41,7 +41,7 @@ module ToggleLocalSpm
|
|
|
41
41
|
LocalRef = Xcodeproj::Project::Object::XCLocalSwiftPackageReference
|
|
42
42
|
ProductDependency = Xcodeproj::Project::Object::XCSwiftPackageProductDependency
|
|
43
43
|
|
|
44
|
-
Candidate = Struct.new(:name, :ref, :type, :resolved_entry, :
|
|
44
|
+
Candidate = Struct.new(:name, :ref, :type, :resolved_entry, :local_path_known) do
|
|
45
45
|
def local?
|
|
46
46
|
ref.is_a?(LocalRef)
|
|
47
47
|
end
|
|
@@ -50,6 +50,13 @@ module ToggleLocalSpm
|
|
|
50
50
|
TYPE_LABELS = { "direct" => "🎯 direct", "indirect" => "🧩 indirect" }.freeze
|
|
51
51
|
STATE_LABELS = { local: "📁 local", remote: "🌏 remote" }.freeze
|
|
52
52
|
|
|
53
|
+
MANAGED_LABELS = { set: "✅", found: "📁", not_found: "⚠️" }.freeze
|
|
54
|
+
MANAGED_LEGEND = [
|
|
55
|
+
"#{MANAGED_LABELS[:set]} Local mock set",
|
|
56
|
+
"#{MANAGED_LABELS[:found]} Mock not set. Mock found (localPath in spm-local-overrides.json exists)",
|
|
57
|
+
"#{MANAGED_LABELS[:not_found]} Mock not set. Mock not found (localPath in spm-local-overrides.json not existing)"
|
|
58
|
+
].freeze
|
|
59
|
+
|
|
53
60
|
def self.run(argv)
|
|
54
61
|
new(argv).run
|
|
55
62
|
end
|
|
@@ -166,16 +173,20 @@ module ToggleLocalSpm
|
|
|
166
173
|
direct = refs.map do |ref|
|
|
167
174
|
name = ref_name(ref)
|
|
168
175
|
type = state.dig(name, "type") || "direct"
|
|
169
|
-
Candidate.new(name, ref, type, nil,
|
|
176
|
+
Candidate.new(name, ref, type, nil, local_path_known?(state, name))
|
|
170
177
|
end
|
|
171
178
|
|
|
172
179
|
resolved = load_resolved_packages(xcodeproj_path)
|
|
173
180
|
indirect = resolved.reject { |name, _| direct.any? { |c| c.name.casecmp(name).zero? } }
|
|
174
|
-
.map { |name, info| Candidate.new(name, nil, "indirect", info,
|
|
181
|
+
.map { |name, info| Candidate.new(name, nil, "indirect", info, local_path_known?(state, name)) }
|
|
175
182
|
|
|
176
183
|
direct + indirect
|
|
177
184
|
end
|
|
178
185
|
|
|
186
|
+
def local_path_known?(state, name)
|
|
187
|
+
!!state.dig(name, "localPath")
|
|
188
|
+
end
|
|
189
|
+
|
|
179
190
|
def resolved_file_path(xcodeproj_path)
|
|
180
191
|
workspace = find_workspace_path
|
|
181
192
|
if workspace
|
|
@@ -242,10 +253,13 @@ module ToggleLocalSpm
|
|
|
242
253
|
candidates.each_with_index do |c, i|
|
|
243
254
|
type_label = TYPE_LABELS.fetch(c.type, c.type).ljust(type_width)
|
|
244
255
|
state_label = STATE_LABELS[c.local? ? :local : :remote].ljust(state_width)
|
|
245
|
-
|
|
246
|
-
puts " #{(i + 1).to_s.rjust(index_width)} #{c.name.ljust(name_width)} #{type_label} #{state_label} #{managed_label}"
|
|
256
|
+
puts " #{(i + 1).to_s.rjust(index_width)} #{c.name.ljust(name_width)} #{type_label} #{state_label} #{managed_label_for(c)}"
|
|
247
257
|
end
|
|
248
258
|
|
|
259
|
+
puts
|
|
260
|
+
puts "Legend:"
|
|
261
|
+
MANAGED_LEGEND.each { |line| puts " #{line}" }
|
|
262
|
+
|
|
249
263
|
print "\n> "
|
|
250
264
|
choice = $stdin.gets&.strip
|
|
251
265
|
abort_with("invalid selection") if choice.nil? || choice.empty?
|
|
@@ -260,6 +274,13 @@ module ToggleLocalSpm
|
|
|
260
274
|
end.uniq
|
|
261
275
|
end
|
|
262
276
|
|
|
277
|
+
def managed_label_for(candidate)
|
|
278
|
+
return MANAGED_LABELS[:set] if candidate.local?
|
|
279
|
+
return MANAGED_LABELS[:found] if candidate.local_path_known
|
|
280
|
+
|
|
281
|
+
MANAGED_LABELS[:not_found]
|
|
282
|
+
end
|
|
283
|
+
|
|
263
284
|
# --- Toggling -------------------------------------------------------
|
|
264
285
|
|
|
265
286
|
def toggle(project, xcodeproj_path, candidate, state)
|
|
@@ -330,7 +351,7 @@ module ToggleLocalSpm
|
|
|
330
351
|
# in packageReferences is enough for SwiftPM to unify the identity with
|
|
331
352
|
# the local checkout wherever else in the graph it's referenced
|
|
332
353
|
# (verified: it overrides the transitive pin even when the package that
|
|
333
|
-
# actually declares the dependency, e.g.
|
|
354
|
+
# actually declares the dependency, e.g. my-shared-ios, stays remote).
|
|
334
355
|
def add_indirect_local_ref(project, xcodeproj_path, candidate, state)
|
|
335
356
|
name = candidate.name
|
|
336
357
|
entry = state[name] || {}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: toggle-local-spm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sushant Verma
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: xcodeproj
|