github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/management/source.go (about)

     1  package management
     2  
     3  import (
     4  	"crypto/md5"
     5  	"encoding/base64"
     6  	"io"
     7  	"os"
     8  	"time"
     9  
    10  	"github.com/lmorg/murex/lang"
    11  	"github.com/lmorg/murex/lang/ref"
    12  	"github.com/lmorg/murex/lang/runmode"
    13  	"github.com/lmorg/murex/lang/types"
    14  )
    15  
    16  func init() {
    17  	lang.DefineFunction("source", cmdSource, types.Null)
    18  	lang.DefineFunction(".", cmdSource, types.Null)
    19  }
    20  
    21  func cmdSource(p *lang.Process) error {
    22  	var (
    23  		block []rune
    24  		name  string
    25  		err   error
    26  		b     []byte
    27  	)
    28  
    29  	if p.IsMethod {
    30  		b, err = p.Stdin.ReadAll()
    31  		if err != nil {
    32  			return err
    33  		}
    34  		block = []rune(string(b))
    35  		name = "<stdin>"
    36  
    37  	} else {
    38  		block, err = p.Parameters.Block(0)
    39  		if err == nil {
    40  			b = []byte(string(block))
    41  			name = "N/A"
    42  
    43  		} else {
    44  			// get block from file
    45  			name, err = p.Parameters.String(0)
    46  			if err != nil {
    47  				return err
    48  			}
    49  
    50  			file, err := os.Open(name)
    51  			if err != nil {
    52  				return err
    53  			}
    54  
    55  			b, err = io.ReadAll(file)
    56  			if err != nil {
    57  				return err
    58  			}
    59  			block = []rune(string(b))
    60  		}
    61  	}
    62  
    63  	hash := ":" + quickHash(name+time.Now().String())
    64  	fileRef := &ref.File{Source: ref.History.AddSource(name, p.FileRef.Source.Module+hash, b)}
    65  
    66  	p.RunMode = runmode.Normal
    67  	fork := p.Fork(lang.F_FUNCTION | lang.F_NEW_MODULE | lang.F_NO_STDIN)
    68  
    69  	fork.Name.Set(p.Name.String())
    70  	fork.FileRef = fileRef
    71  	p.ExitNum, err = fork.Execute(block)
    72  	return err
    73  }
    74  
    75  func quickHash(s string) string {
    76  	hasher := md5.New()
    77  	hasher.Write([]byte(s))
    78  	return base64.RawURLEncoding.EncodeToString(hasher.Sum(nil))
    79  }