@@ -67,6 +67,9 @@ func postProcessCreatedPlugins(ctx context.Context, plugins []createdPlugin) err
6767 if err := recreateNPMPackageLock (ctx , plugin ); err != nil {
6868 return fmt .Errorf ("failed to recreate package-lock.json for %s: %w" , newPluginRef , err )
6969 }
70+ if err := recreateSwiftPackageResolved (ctx , plugin ); err != nil {
71+ return fmt .Errorf ("failed to resolve Swift package for %s: %w" , newPluginRef , err )
72+ }
7073 }
7174 if err := runPluginTests (ctx , plugins ); err != nil {
7275 return fmt .Errorf ("failed to run plugin tests: %w" , err )
@@ -119,6 +122,85 @@ func recreateNPMPackageLock(ctx context.Context, plugin createdPlugin) error {
119122 return cmd .Run ()
120123}
121124
125+ // recreateSwiftPackageResolved resolves Swift package dependencies for plugins that use Swift packages.
126+ // It clones the git repository specified in the Dockerfile, runs 'swift package resolve',
127+ // and moves the generated Package.resolved file to the version directory.
128+ func recreateSwiftPackageResolved (ctx context.Context , plugin createdPlugin ) (retErr error ) {
129+ versionDir := filepath .Join (plugin .pluginDir , plugin .newVersion )
130+ packageResolved := filepath .Join (versionDir , "Package.resolved" )
131+ _ , err := os .Stat (packageResolved )
132+ if err != nil {
133+ if ! errors .Is (err , fs .ErrNotExist ) {
134+ return err
135+ }
136+ // no Package.resolved to update
137+ return nil
138+ }
139+
140+ // Read the Dockerfile to find the git clone command
141+ dockerfile := filepath .Join (versionDir , "Dockerfile" )
142+ file , err := os .Open (dockerfile )
143+ if err != nil {
144+ return fmt .Errorf ("failed to open Dockerfile: %w" , err )
145+ }
146+ defer file .Close ()
147+
148+ var gitCloneCmd string
149+ scanner := bufio .NewScanner (file )
150+ for scanner .Scan () {
151+ line := scanner .Text ()
152+ if strings .Contains (line , "RUN git clone" ) {
153+ // Strip the "RUN " prefix
154+ gitCloneCmd = strings .TrimSpace (strings .TrimPrefix (line , "RUN " ))
155+ break
156+ }
157+ }
158+ if err := scanner .Err (); err != nil {
159+ return fmt .Errorf ("failed to read Dockerfile: %w" , err )
160+ }
161+ if gitCloneCmd == "" {
162+ return errors .New ("no 'RUN git clone' command found in Dockerfile" )
163+ }
164+
165+ log .Printf ("resolving Swift package for %s/%s:%s" , plugin .org , plugin .name , plugin .newVersion )
166+
167+ // Create a tempdir for cloning the repo
168+ tmpDir , err := os .MkdirTemp ("" , "swift-repo-*" )
169+ if err != nil {
170+ return fmt .Errorf ("creating tmp dir: %w" , err )
171+ }
172+ defer func () {
173+ retErr = errors .Join (retErr , os .RemoveAll (tmpDir ))
174+ }()
175+
176+ // Execute the git clone command, cloning to the tmpDir
177+ cmd := exec .CommandContext (ctx , "sh" , "-c" , gitCloneCmd , "--" , tmpDir )
178+ cmd .Dir = versionDir
179+ cmd .Stdout = os .Stdout
180+ cmd .Stderr = os .Stderr
181+ if err := cmd .Run (); err != nil {
182+ return fmt .Errorf ("failed to run git clone: %w" , err )
183+ }
184+
185+ // Run `swift package resolve` in the cloned directory
186+ cmd = exec .CommandContext (ctx , "swift" , "package" , "resolve" )
187+ cmd .Dir = tmpDir
188+ cmd .Stdout = os .Stdout
189+ cmd .Stderr = os .Stderr
190+ if err := cmd .Run (); err != nil {
191+ return fmt .Errorf ("failed to run swift package resolve: %w" , err )
192+ }
193+
194+ // Move the Package.resolved file from the cloned directory to the version directory
195+ src := filepath .Join (tmpDir , "Package.resolved" )
196+ dest := packageResolved
197+ if err := os .Rename (src , dest ); err != nil {
198+ return fmt .Errorf ("failed to move Package.resolved: %w" , err )
199+ }
200+
201+ return nil
202+ }
203+
122204// runPluginTests runs 'make test PLUGINS="org/name:v<new>"' in order to generate plugin.sum files.
123205func runPluginTests (ctx context.Context , plugins []createdPlugin ) error {
124206 pluginsEnv := make ([]string , 0 , len (plugins ))
0 commit comments