github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/config/profile/profile.go (about)

     1  package profile
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/lmorg/murex/app"
     9  	"github.com/lmorg/murex/builtins/pipes/term"
    10  	"github.com/lmorg/murex/lang"
    11  	"github.com/lmorg/murex/lang/ref"
    12  	"github.com/lmorg/murex/shell/autocomplete"
    13  	"github.com/lmorg/murex/utils"
    14  	"github.com/lmorg/murex/utils/ansi"
    15  	"github.com/lmorg/murex/utils/home"
    16  )
    17  
    18  const preloadMessage = `# This file is loaded before any murex modules. It should only contain
    19  # environmental variables required for the modules to work eg:
    20  #
    21  #     export PATH=...
    22  #
    23  # Any other profile config belongs in your profile script instead:
    24  # `
    25  
    26  const (
    27  	F_PRELOAD = 1 << iota
    28  	F_MODULES
    29  	F_PROFILE
    30  )
    31  
    32  // Execute runs the preload script, then murex modules followed by your murex profile
    33  func Execute(flags int) {
    34  	if flags == 0 {
    35  		panic("no flags specified")
    36  	}
    37  
    38  	autocomplete.UpdateGlobalExeList()
    39  
    40  	pwd, err := os.Getwd()
    41  	if err != nil {
    42  		os.Stderr.WriteString(err.Error())
    43  	}
    44  
    45  	if flags&F_PRELOAD != 0 {
    46  		if err := profile(preloadFileName, PreloadPath()); err != nil {
    47  			os.Stderr.WriteString("There were problems loading profile `" + PreloadPath() + "`:" + utils.NewLineString)
    48  			os.Stderr.WriteString(err.Error() + utils.NewLineString)
    49  		}
    50  	}
    51  
    52  	if flags&F_MODULES != 0 {
    53  		if err := modules(ModulePath()); err != nil {
    54  			os.Stderr.WriteString("There were problems loading modules `" + ModulePath() + "`:" + utils.NewLineString)
    55  			os.Stderr.WriteString(err.Error() + utils.NewLineString)
    56  		}
    57  	}
    58  
    59  	if flags&F_PROFILE != 0 {
    60  		if err := profile(profileFileName, ProfilePath()); err != nil {
    61  			os.Stderr.WriteString("There were problems loading profile `" + ProfilePath() + "`:" + utils.NewLineString)
    62  			os.Stderr.WriteString(err.Error() + utils.NewLineString)
    63  		}
    64  	}
    65  
    66  	err = os.Chdir(pwd)
    67  	if err != nil {
    68  		os.Stderr.WriteString(err.Error())
    69  	}
    70  
    71  	lang.ShellProcess.FileRef = ref.NewModule(app.ShellModule)
    72  }
    73  
    74  func profile(name, path string) error {
    75  	file, err := os.OpenFile(path, os.O_RDONLY|os.O_CREATE, 0640)
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	defer file.Close()
    81  
    82  	b, err := io.ReadAll(file)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	if len(b) == 0 && path == PreloadPath() {
    88  		err := file.Close()
    89  		if err != nil {
    90  			return err
    91  		}
    92  		file, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0640)
    93  		if err != nil {
    94  			return err
    95  		}
    96  		_, err = file.WriteString(preloadMessage + ProfilePath() + strings.Repeat(utils.NewLineString, 3))
    97  		if err != nil {
    98  			return err
    99  		}
   100  	}
   101  
   102  	err = os.Chdir(home.MyDir)
   103  	if err != nil {
   104  		os.Stderr.WriteString(err.Error())
   105  	}
   106  
   107  	block := []rune(string(b))
   108  
   109  	os.Stderr.WriteString("Loading profile `" + name + "`" + utils.NewLineString)
   110  
   111  	// lets redirect all output to STDERR just in case this thing gets piped for any strange reason
   112  	fork := lang.ShellProcess.Fork(lang.F_NEW_MODULE | lang.F_NEW_TESTS | lang.F_NO_STDIN)
   113  	fork.Stdout = term.NewErr(false)
   114  	fork.Stderr = term.NewErr(ansi.IsAllowed())
   115  	moduleName := "profile/" + name
   116  	fork.FileRef = &ref.File{Source: &ref.Source{Module: moduleName}}
   117  	fork.FileRef.Source = ref.History.AddSource(path, moduleName, b)
   118  
   119  	_, err = fork.Execute(block)
   120  
   121  	autocomplete.UpdateGlobalExeList()
   122  
   123  	return err
   124  }