github.com/speakeasy-api/sdk-gen-config@v1.14.2/workflow/lockfile.go (about)

     1  package workflow
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/speakeasy-api/sdk-gen-config/workspace"
     7  	"gopkg.in/yaml.v3"
     8  	"io/fs"
     9  	"os"
    10  	"path/filepath"
    11  )
    12  
    13  const workflowLockfile = "workflow.lock"
    14  
    15  type LockFile struct {
    16  	SpeakeasyVersion string                `yaml:"speakeasyVersion"`
    17  	Sources          map[string]SourceLock `yaml:"sources"`
    18  	Targets          map[string]TargetLock `yaml:"targets"`
    19  
    20  	Workflow Workflow `yaml:"workflow"`
    21  }
    22  
    23  type SourceLock struct {
    24  	SourceNamespace      string   `yaml:"sourceNamespace,omitempty"`
    25  	SourceRevisionDigest string   `yaml:"sourceRevisionDigest,omitempty"`
    26  	SourceBlobDigest     string   `yaml:"sourceBlobDigest,omitempty"`
    27  	Tags                 []string `yaml:"tags,omitempty"`
    28  }
    29  
    30  type TargetLock struct {
    31  	Source               string `yaml:"source"`
    32  	SourceNamespace      string `yaml:"sourceNamespace,omitempty"`
    33  	SourceRevisionDigest string `yaml:"sourceRevisionDigest,omitempty"`
    34  	SourceBlobDigest     string `yaml:"sourceBlobDigest,omitempty"`
    35  	OutLocation          string `yaml:"outLocation,omitempty"`
    36  }
    37  
    38  func LoadLockfile(dir string) (*LockFile, error) {
    39  	res, err := workspace.FindWorkspace(dir, workspace.FindWorkspaceOptions{
    40  		FindFile:  workflowLockfile,
    41  		Recursive: true,
    42  	})
    43  	if err != nil {
    44  		if !errors.Is(err, fs.ErrNotExist) {
    45  			return nil, err
    46  		}
    47  		return nil, fmt.Errorf("%w in %s", err, filepath.Join(dir, workspace.SpeakeasyFolder, workflowLockfile))
    48  	}
    49  
    50  	var lockfile LockFile
    51  	if err := yaml.Unmarshal(res.Data, &lockfile); err != nil {
    52  		return nil, fmt.Errorf("failed to unmarshal workflow.lock: %w", err)
    53  	}
    54  
    55  	return &lockfile, nil
    56  }
    57  
    58  // Save the workflow lockfile to the given directory, dir should generally be the root of the project,
    59  // and the lockfile will be saved to ${projectRoot}/.speakeasy/workflow.lock
    60  func SaveLockfile(dir string, lockfile *LockFile) error {
    61  	data, err := yaml.Marshal(lockfile)
    62  	if err != nil {
    63  		return fmt.Errorf("failed to marshal workflow lockfile: %w", err)
    64  	}
    65  
    66  	res, err := workspace.FindWorkspace(dir, workspace.FindWorkspaceOptions{
    67  		FindFile:  workflowLockfile,
    68  		Recursive: true,
    69  	})
    70  	if err != nil {
    71  		if !errors.Is(err, fs.ErrNotExist) {
    72  			return err
    73  		}
    74  		res = &workspace.FindWorkspaceResult{
    75  			Path: filepath.Join(dir, workspace.SpeakeasyFolder, workflowLockfile),
    76  		}
    77  	}
    78  
    79  	if err := os.WriteFile(res.Path, data, 0o644); err != nil {
    80  		return fmt.Errorf("failed to write workflow.lock: %w", err)
    81  	}
    82  
    83  	return nil
    84  }