github.com/hattya/nazuna@v0.7.1-0.20240331055452-55e14c275c1c/cmd/nzn/subrepo.go (about)

     1  //
     2  // nazuna/cmd/nzn :: subrepo.go
     3  //
     4  //   Copyright (c) 2013-2020 Akinori Hattori <hattya@gmail.com>
     5  //
     6  //   SPDX-License-Identifier: MIT
     7  //
     8  
     9  package main
    10  
    11  import (
    12  	"os"
    13  	"path/filepath"
    14  	"strings"
    15  
    16  	"github.com/hattya/go.cli"
    17  	"github.com/hattya/nazuna"
    18  )
    19  
    20  func init() {
    21  	flags := cli.NewFlagSet()
    22  	flags.String("l, layer", "", "layer name")
    23  	flags.Bool("a, add", false, "add <repository> to <path>")
    24  	flags.Bool("u, update", false, "clone or update repositories")
    25  
    26  	app.Add(&cli.Command{
    27  		Name: []string{"subrepo"},
    28  		Usage: []string{
    29  			"-l <layer> -a <repository> <path>",
    30  			"-u",
    31  		},
    32  		Desc: strings.TrimSpace(cli.Dedent(`
    33  			manage subrepositories
    34  
    35  			  subrepo is used to manage external repositories.
    36  
    37  			  subrepo can associate <repository> to <path> by --add flag. If <path> ends
    38  			  with a path separator, it will be associated as the basename of <repository>
    39  			  under <path>.
    40  
    41  			  subrepo can clone or update the repositories in the working copy by --update
    42  			  flag.
    43  		`)),
    44  		Flags:  flags,
    45  		Action: subrepo,
    46  		Data:   true,
    47  	})
    48  }
    49  
    50  func subrepo(ctx *cli.Context) error {
    51  	repo := ctx.Data.(*nazuna.Repository)
    52  	wc, err := repo.WC()
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	switch {
    58  	case ctx.Bool("add"):
    59  		switch {
    60  		case ctx.String("layer") == "":
    61  			return cli.FlagError("--layer flag is required")
    62  		case len(ctx.Args) != 2:
    63  			return cli.ErrArgs
    64  		}
    65  		l, err := repo.LayerOf(ctx.String("layer"))
    66  		if err != nil {
    67  			return err
    68  		}
    69  		src := ctx.Args[0]
    70  		dst := ctx.Args[1]
    71  		rel, err := wc.Rel('.', dst)
    72  		if err != nil {
    73  			return err
    74  		}
    75  		if len(dst) > 0 && os.IsPathSeparator(dst[len(dst)-1]) {
    76  			dst = rel + "/" + filepath.Base(src)
    77  		} else {
    78  			dst = rel
    79  		}
    80  		if _, err := l.NewSubrepo(src, dst); err != nil {
    81  			return err
    82  		}
    83  		return repo.Flush()
    84  	case ctx.Bool("update"):
    85  		_, err := wc.MergeLayers()
    86  		if err != nil {
    87  			return err
    88  		}
    89  		ui := newUI()
    90  		for _, e := range wc.State.WC {
    91  			if e.Type != "subrepo" {
    92  				continue
    93  			}
    94  			app.Printf("* %v\n", e.Origin)
    95  			r, err := nazuna.NewRemote(ui, e.Origin)
    96  			if err != nil {
    97  				return err
    98  			}
    99  			dst := repo.SubrepoFor(r.Root)
   100  			if nazuna.IsEmptyDir(dst) {
   101  				dst, _ = wc.Rel('.', dst)
   102  				err = r.Clone(wc.PathFor("/"), dst)
   103  			} else {
   104  				err = r.Update(dst)
   105  			}
   106  			if err != nil {
   107  				return err
   108  			}
   109  		}
   110  	}
   111  	return nil
   112  }