github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bob/bob.go (about)

     1  package bob
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  
     7  	"github.com/Benchkram/bob/pkg/usererror"
     8  
     9  	"github.com/hashicorp/go-version"
    10  
    11  	"gopkg.in/yaml.v3"
    12  
    13  	"github.com/Benchkram/errz"
    14  
    15  	"github.com/Benchkram/bob/pkg/buildinfostore"
    16  	"github.com/Benchkram/bob/pkg/file"
    17  	"github.com/Benchkram/bob/pkg/store"
    18  )
    19  
    20  var Version = "0.0.0"
    21  
    22  type B struct {
    23  	// Repositories to track.
    24  	Repositories []Repo `yaml:"repositories"`
    25  
    26  	// dir is bob's working directory.
    27  	dir string
    28  
    29  	// local the place to store artifacts localy
    30  	local store.Store
    31  	// TODO: add a remote store
    32  	// remotestore cas.Store
    33  
    34  	buildInfoStore buildinfostore.Store
    35  
    36  	// readConfig some commands need a fully initialised bob.
    37  	// When this is true a `.bob.workspace` file must exist,
    38  	// usually done by calling `bob init`
    39  	readConfig bool
    40  
    41  	// enableCaching allows to save and load artifacts
    42  	// from the cache Default: true
    43  	enableCaching bool
    44  }
    45  
    46  func newBob(opts ...Option) *B {
    47  	wd, err := os.Getwd()
    48  	if err != nil {
    49  		errz.Fatal(err)
    50  	}
    51  
    52  	b := &B{
    53  		dir:           wd,
    54  		enableCaching: true,
    55  	}
    56  
    57  	for _, opt := range opts {
    58  		if opt == nil {
    59  			continue
    60  		}
    61  		opt(b)
    62  	}
    63  
    64  	return b
    65  }
    66  
    67  // BobWithBaseStoreDir initialises stores in the given directory
    68  func BobWithBaseStoreDir(baseStoreDir string, opts ...Option) (*B, error) {
    69  	bob := newBob(opts...)
    70  
    71  	_, err := version.NewVersion(Version)
    72  	if err != nil {
    73  		return nil, ErrInvalidVersion
    74  	}
    75  
    76  	fs, err := Filestore(baseStoreDir)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	bob.local = fs
    81  
    82  	bis, err := BuildinfoStore(baseStoreDir)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	bob.buildInfoStore = bis
    87  
    88  	for _, opt := range opts {
    89  		if opt == nil {
    90  			continue
    91  		}
    92  		opt(bob)
    93  	}
    94  
    95  	return bob, nil
    96  }
    97  
    98  func Bob(opts ...Option) (*B, error) {
    99  	bob := newBob(opts...)
   100  
   101  	_, err := version.NewVersion(Version)
   102  	if err != nil {
   103  		return nil, ErrInvalidVersion
   104  	}
   105  
   106  	if bob.readConfig {
   107  		err := bob.read()
   108  		if err != nil {
   109  			return nil, err
   110  		}
   111  	}
   112  
   113  	if bob.local == nil {
   114  		fs, err := DefaultFilestore()
   115  		if err != nil {
   116  			return nil, err
   117  		}
   118  		bob.local = fs
   119  	}
   120  
   121  	if bob.buildInfoStore == nil {
   122  		bis, err := DefaultBuildinfoStore()
   123  		if err != nil {
   124  			return nil, err
   125  		}
   126  		bob.buildInfoStore = bis
   127  	}
   128  
   129  	return bob, nil
   130  }
   131  
   132  func (b *B) Dir() string {
   133  	return b.dir
   134  }
   135  
   136  func (b *B) write() (err error) {
   137  	defer errz.Recover(&err)
   138  
   139  	bin, err := yaml.Marshal(b)
   140  	errz.Fatal(err)
   141  
   142  	const mode = 0644
   143  	return ioutil.WriteFile(b.WorkspaceFilePath(), bin, mode)
   144  }
   145  
   146  func (b *B) read() (err error) {
   147  	defer errz.Recover(&err)
   148  
   149  	if !file.Exists(b.WorkspaceFilePath()) {
   150  		// Initialise with default values if it does not exist.
   151  		err := b.write()
   152  		errz.Fatal(err)
   153  	}
   154  
   155  	bin, err := ioutil.ReadFile(b.WorkspaceFilePath())
   156  	errz.Fatal(err, "Failed to read config file")
   157  
   158  	err = yaml.Unmarshal(bin, b)
   159  	if err != nil {
   160  		return usererror.Wrapm(err, "YAML unmarshal failed")
   161  	}
   162  
   163  	return nil
   164  }