github.com/mavryk-network/mvgo@v1.19.9/internal/compose/alpha/run.go (about)

     1  // Copyright (c) 2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc, abdul@blockwatch.cc
     3  
     4  package alpha
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  
    10  	"github.com/mavryk-network/mvgo/internal/compose"
    11  )
    12  
    13  // 1 load yaml file
    14  // 2 create accounts
    15  // 3 process pipeline
    16  
    17  func (e *Engine) Run(ctx compose.Context, fname string) error {
    18  	spec, err := compose.ParseFile[Spec](fname)
    19  	if err != nil {
    20  		return err
    21  	}
    22  	ctx.WithPath(filepath.Dir(fname))
    23  	for _, a := range spec.Accounts {
    24  		if acc, err := ctx.MakeAccount(int(a.Id), a.Name); err != nil {
    25  			return err
    26  		} else {
    27  			ctx.Log.Infof("Account %s %s", a.Name, acc.Address)
    28  		}
    29  	}
    30  	for n, v := range spec.Variables {
    31  		ctx.AddVariable(n, v)
    32  	}
    33  	if err := spec.Validate(ctx); err != nil {
    34  		return err
    35  	}
    36  
    37  	// rewire loggers
    38  	defer ctx.RestoreLogger()
    39  	for _, p := range spec.Pipelines {
    40  		if err := ctx.Cache().Load(p.Hash64(), !ctx.ShouldResume()); err != nil {
    41  			return err
    42  		}
    43  		ctx.Log.Infof("Running pipeline %s", p.Name)
    44  		for i, task := range p.Tasks[ctx.Cache().Get():] {
    45  			ctx.SwitchLogger(fmt.Sprintf("%s[%d/%d]", p.Name, i+1, p.Len()), task.Log)
    46  			if task.Skip {
    47  				if err := ctx.Cache().Update(i); err != nil {
    48  					return err
    49  				}
    50  				continue
    51  			}
    52  			t, err := NewTask(task.Type)
    53  			if err != nil {
    54  				return fmt.Errorf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
    55  			}
    56  
    57  			ctx.Log.Debugf("%s %s", task.Type, task.Destination)
    58  
    59  			// Build
    60  			op, opts, err := t.Build(ctx, task)
    61  			if err != nil {
    62  				if err == compose.ErrSkip {
    63  					if err := ctx.Cache().Update(i); err != nil {
    64  						return err
    65  					}
    66  					continue
    67  				}
    68  				return fmt.Errorf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
    69  			}
    70  
    71  			// send
    72  			opts.Confirmations = 0
    73  			rcpt, err := ctx.Send(op, opts)
    74  			if err != nil {
    75  				switch task.OnError {
    76  				case ErrorModeFail:
    77  					return fmt.Errorf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
    78  				case ErrorModeWarn:
    79  					ctx.Log.Warnf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
    80  				}
    81  			} else {
    82  				// log receipt
    83  				ctx.Log.Infof("%s SUCCESS block=%d hash=%s", t.Type(), rcpt.Height, rcpt.Op.Hash)
    84  			}
    85  
    86  			// handle receipt
    87  			if task.Alias != "" {
    88  				addr, _ := rcpt.OriginatedContract()
    89  				ctx.AddVariable(task.Alias, addr.String())
    90  				ctx.Log.Infof("NEW contract %s %s", task.Alias, addr)
    91  			}
    92  
    93  			// update pipeline cache
    94  			if err := ctx.Cache().Update(i); err != nil {
    95  				return err
    96  			}
    97  		}
    98  		ctx.RestoreLogger()
    99  	}
   100  	return nil
   101  }
   102  
   103  func (e *Engine) Validate(ctx compose.Context, fname string) error {
   104  	spec, err := compose.ParseFile[Spec](fname)
   105  	if err != nil {
   106  		return err
   107  	}
   108  	ctx.WithPath(filepath.Dir(fname))
   109  	for _, a := range spec.Accounts {
   110  		if _, err := ctx.MakeAccount(int(a.Id), a.Name); err != nil {
   111  			return err
   112  		}
   113  	}
   114  	for n, v := range spec.Variables {
   115  		ctx.AddVariable(n, v)
   116  	}
   117  	if err := spec.Validate(ctx); err != nil {
   118  		return err
   119  	}
   120  	for _, p := range spec.Pipelines {
   121  		ctx.Log.Debugf("Validating pipeline %s", p.Name)
   122  		for i, task := range p.Tasks {
   123  			t, err := NewTask(task.Type)
   124  			if err != nil {
   125  				return fmt.Errorf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
   126  			}
   127  			if err := t.Validate(ctx, task); err != nil {
   128  				return fmt.Errorf("%s[%d] (%s): %v", p.Name, i, task.Type, err)
   129  			}
   130  			if task.Type == "deploy" && task.Alias != "" {
   131  				script, err := ParseScript(ctx, task)
   132  				if err != nil {
   133  					return fmt.Errorf("parse script: %v", err)
   134  				}
   135  				acc, _ := ctx.MakeAccount(-2, task.Alias)
   136  				ctx.AddVariable(task.Alias, acc.Address.String())
   137  				ctx.Contracts[acc.Address] = script
   138  			}
   139  		}
   140  	}
   141  	return nil
   142  }