mv : mv to new descriptor while updating header
This commit is contained in:
parent
14d124b8a6
commit
b903fe46a4
4 changed files with 104 additions and 3 deletions
|
|
@ -8,5 +8,6 @@ const (
|
||||||
Last Subcommand = "last"
|
Last Subcommand = "last"
|
||||||
Sort Subcommand = "sort"
|
Sort Subcommand = "sort"
|
||||||
Cat Subcommand = "cat"
|
Cat Subcommand = "cat"
|
||||||
|
Mv Subcommand = "mv"
|
||||||
Help Subcommand = "help"
|
Help Subcommand = "help"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
97
mv/mv.go
Normal file
97
mv/mv.go
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
package mv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/brtholomy/um/go/cat"
|
||||||
|
"github.com/brtholomy/um/go/cmd"
|
||||||
|
"github.com/brtholomy/um/go/flags"
|
||||||
|
"github.com/brtholomy/um/go/next"
|
||||||
|
"github.com/brtholomy/um/go/pipe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CMD = cmd.Mv
|
||||||
|
SUMMARY = "rename an um file descriptor field while updating its header"
|
||||||
|
)
|
||||||
|
|
||||||
|
type options struct {
|
||||||
|
Filename flags.Arg
|
||||||
|
Descriptor flags.Arg
|
||||||
|
Help flags.Flag[bool]
|
||||||
|
}
|
||||||
|
|
||||||
|
func initOpts() options {
|
||||||
|
return options{
|
||||||
|
flags.Arg{"", "old filename"},
|
||||||
|
flags.Arg{"", "new descriptor"},
|
||||||
|
flags.Flag[bool]{"--help", "-h", false, "show help"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generates new filename and its content with updated H1 header
|
||||||
|
func newNameAndContent(olds string, opts options) (name string, content string, err error) {
|
||||||
|
// name and title
|
||||||
|
num, err := next.NumFromLast(opts.Filename.Val)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
name = fmt.Sprintf("%s.%s.md", num, opts.Descriptor.Val)
|
||||||
|
title := fmt.Sprintf("# %s", name)
|
||||||
|
|
||||||
|
// content
|
||||||
|
head, tail, ok := strings.Cut(olds, pipe.Newline)
|
||||||
|
// the file has no newline at all?
|
||||||
|
if !ok {
|
||||||
|
tail = head
|
||||||
|
}
|
||||||
|
// there was no title in the original
|
||||||
|
if !strings.HasPrefix(head, cat.H1) {
|
||||||
|
tail = olds
|
||||||
|
}
|
||||||
|
return name, fmt.Sprintf("%s%s%s", title, pipe.Newline, tail), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// effectively does a mv to the new filename, while updating the H1 header to match.
|
||||||
|
func mv(opts options) error {
|
||||||
|
oldb, err := os.ReadFile(opts.Filename.Val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
olds := string(oldb)
|
||||||
|
|
||||||
|
name, content, err := newNameAndContent(olds, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create
|
||||||
|
newf, err := os.Create(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer newf.Close()
|
||||||
|
_, err = newf.WriteString(content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroy
|
||||||
|
err = os.Remove(opts.Filename.Val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Mv(args []string) {
|
||||||
|
opts := initOpts()
|
||||||
|
flags.ParseArgs(CMD, SUMMARY, args, &opts)
|
||||||
|
err := mv(opts)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("um %s: %v", CMD, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ func initOpts() options {
|
||||||
|
|
||||||
// takes the complete last file string
|
// takes the complete last file string
|
||||||
// returns the number as string
|
// returns the number as string
|
||||||
func numFromLast(l string) (string, error) {
|
func NumFromLast(l string) (string, error) {
|
||||||
res := fileRegexp.FindStringSubmatch(l)
|
res := fileRegexp.FindStringSubmatch(l)
|
||||||
num := ""
|
num := ""
|
||||||
if len(res) < 2 {
|
if len(res) < 2 {
|
||||||
|
|
@ -51,7 +51,7 @@ func numFromLast(l string) (string, error) {
|
||||||
// takes the complete last file string and new descriptor
|
// takes the complete last file string and new descriptor
|
||||||
// returns the complete next file string
|
// returns the complete next file string
|
||||||
func next(last string, desc string) (string, error) {
|
func next(last string, desc string) (string, error) {
|
||||||
num, err := numFromLast(last)
|
num, err := NumFromLast(last)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
um.go
5
um.go
|
|
@ -8,12 +8,13 @@ import (
|
||||||
"github.com/brtholomy/um/go/cat"
|
"github.com/brtholomy/um/go/cat"
|
||||||
"github.com/brtholomy/um/go/cmd"
|
"github.com/brtholomy/um/go/cmd"
|
||||||
"github.com/brtholomy/um/go/last"
|
"github.com/brtholomy/um/go/last"
|
||||||
|
"github.com/brtholomy/um/go/mv"
|
||||||
"github.com/brtholomy/um/go/next"
|
"github.com/brtholomy/um/go/next"
|
||||||
"github.com/brtholomy/um/go/sort"
|
"github.com/brtholomy/um/go/sort"
|
||||||
"github.com/brtholomy/um/go/tag"
|
"github.com/brtholomy/um/go/tag"
|
||||||
)
|
)
|
||||||
|
|
||||||
var helpShort string = fmt.Sprintf("um [%s | %s | %s | %s | %s | %s]", cmd.Next, cmd.Last, cmd.Tag, cmd.Cat, cmd.Sort, cmd.Help)
|
var helpShort string = fmt.Sprintf("um [%s | %s | %s | %s | %s | %s | %s]", cmd.Next, cmd.Last, cmd.Tag, cmd.Cat, cmd.Sort, cmd.Mv, cmd.Help)
|
||||||
var helpLong string = fmt.Sprintf(`%s
|
var helpLong string = fmt.Sprintf(`%s
|
||||||
|
|
||||||
An (U)ltralight database for (M)arkdown composition.
|
An (U)ltralight database for (M)arkdown composition.
|
||||||
|
|
@ -47,6 +48,8 @@ func main() {
|
||||||
cat.Cat(args)
|
cat.Cat(args)
|
||||||
case cmd.Sort:
|
case cmd.Sort:
|
||||||
sort.Sort(args)
|
sort.Sort(args)
|
||||||
|
case cmd.Mv:
|
||||||
|
mv.Mv(args)
|
||||||
case cmd.Help:
|
case cmd.Help:
|
||||||
log.Fatalln(helpLong)
|
log.Fatalln(helpLong)
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue