github.com/rcowham/go-libgitfastimport@v0.1.6/cmd_comment.go (about)

     1  // Copyright (C) 2017-2018, 2021  Luke Shumaker <lukeshu@lukeshu.com>
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  
    16  package libfastimport
    17  
    18  import (
    19  	"strconv"
    20  	"strings"
    21  
    22  	"github.com/pkg/errors"
    23  )
    24  
    25  // This file deals with comments, and with commands for which the
    26  // specification says (or said) that the command "can be used anywhere
    27  // in the stream that comments are accepted".
    28  
    29  // comment /////////////////////////////////////////////////////////////////////
    30  
    31  // CmdComment is a comment line; not a real command.
    32  type CmdComment struct {
    33  	Comment string
    34  }
    35  
    36  func (c CmdComment) fiCmdClass() cmdClass { return cmdClassComment }
    37  func (c CmdComment) fiCmdWrite(fiw fiWriter) error {
    38  	return fiw.WriteLine("#" + c.Comment)
    39  }
    40  func init() { parser_registerCmd("#", CmdComment{}) }
    41  func (CmdComment) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
    42  	line, err := fir.ReadLine()
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	return CmdComment{Comment: trimLinePrefix(line, "#")}, nil
    47  }
    48  
    49  // get-mark ////////////////////////////////////////////////////////////////////
    50  
    51  // CmdGetMark requests that the Backend to report back (over the
    52  // auxiliary cat-blob stream) with the SHA-1 corresponding to the
    53  // given Mark.
    54  type CmdGetMark struct {
    55  	Mark int
    56  }
    57  
    58  func (c CmdGetMark) fiCmdClass() cmdClass {
    59  	// Prior to git v2.22.0 this was 'cmdClassComment', but in
    60  	// v2.22.0 it was changed to a stricter
    61  	// 'cmdClassCommand|cmdClassInCommit'.  I want to have better
    62  	// backward compatibility, so I'm keeping it as
    63  	// 'cmdClassComment'.
    64  	return cmdClassComment
    65  }
    66  func (c CmdGetMark) fiCmdWrite(fiw fiWriter) error {
    67  	return fiw.WriteLine("get-mark", ":"+strconv.Itoa(c.Mark))
    68  }
    69  func init() { parser_registerCmd("get-mark :", CmdGetMark{}) }
    70  func (CmdGetMark) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
    71  	line, err := fir.ReadLine()
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	c := CmdGetMark{}
    76  	c.Mark, err = strconv.Atoi(trimLinePrefix(line, "get-mark :"))
    77  	if err != nil {
    78  		return nil, errors.Wrap(err, "get-mark")
    79  	}
    80  	return c, nil
    81  }
    82  
    83  // cat-blob ////////////////////////////////////////////////////////////////////
    84  
    85  // CmdCatBlob requests that the Backend to report back (over the
    86  // auxiliary cat-blob stream) with the SHA-1 and content of the
    87  // requested blob.  The blob can be specified either by a mark
    88  // reference (":<idnum>") or by a full 40-byte SHA-1.
    89  type CmdCatBlob struct {
    90  	DataRef string
    91  }
    92  
    93  func (c CmdCatBlob) fiCmdClass() cmdClass {
    94  	// Prior to git v2.22.0 this was 'cmdClassComment', but in
    95  	// v2.22.0 it was changed to a stricter
    96  	// 'cmdClassCommand|cmdClassInCommit|cmdClassInFileModify'.  I
    97  	// don't want to implement cmdClassInFileModify for just this
    98  	// one command, and also I want to have better backward
    99  	// compatibility; so I'm keeping it as 'cmdClassComment'.
   100  	return cmdClassComment
   101  }
   102  func (c CmdCatBlob) fiCmdWrite(fiw fiWriter) error {
   103  	return fiw.WriteLine("cat-blob", c.DataRef)
   104  }
   105  func init() { parser_registerCmd("cat-blob ", CmdCatBlob{}) }
   106  func (CmdCatBlob) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
   107  	line, err := fir.ReadLine()
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	return CmdCatBlob{DataRef: trimLinePrefix(line, "cat-blob ")}, nil
   112  }
   113  
   114  // ls //////////////////////////////////////////////////////////////////////////
   115  
   116  // CmdLs requests that the Backend to report back (over the auxiliary
   117  // cat-blob stream) with information about the object at a path in the
   118  // specified commit.  If inside of a commit, specifying the commit is
   119  // optional, and the ongoing commit is used.  The commit can be
   120  // specified either by a mark reference (":<idnum>") or by a full
   121  // 40-byte SHA-1.
   122  type CmdLs struct {
   123  	DataRef string // optional if inside of a commit
   124  	Path    Path
   125  }
   126  
   127  func (c CmdLs) fiCmdClass() cmdClass {
   128  	// Prior to git v2.22.0 the docs said 'ls' was allowed
   129  	// anywhere a comment was allowed, but that was never really
   130  	// true, and in v2.22.0 the docs were updated to match the
   131  	// code.
   132  	if c.DataRef == "" {
   133  		// Yeah, this will give slightly misleading info to
   134  		// parser_registerCmd(), but that's OK,
   135  		// parser_registerCmd() only really cares about the
   136  		// cmdClassInCommand bit.
   137  		return cmdClassInCommit
   138  	}
   139  	return cmdClassCommand | cmdClassInCommit
   140  }
   141  func (c CmdLs) fiCmdWrite(fiw fiWriter) error {
   142  	if c.DataRef == "" {
   143  		return fiw.WriteLine("ls", c.Path)
   144  	} else {
   145  		return fiw.WriteLine("ls", c.DataRef, c.Path)
   146  	}
   147  }
   148  func init() { parser_registerCmd("ls ", CmdLs{}) }
   149  func (CmdLs) fiCmdRead(fir fiReader) (cmd Cmd, err error) {
   150  	// 'ls' SP <dataref> SP <path> LF
   151  	line, err := fir.ReadLine()
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  	str := trimLinePrefix(line, "ls ")
   156  	sp := -1
   157  	if !strings.HasPrefix(str, "\"") {
   158  		sp = strings.IndexByte(line, ' ')
   159  	}
   160  	c := CmdLs{}
   161  	c.Path = PathUnescape(str[sp+1:])
   162  	if sp >= 0 {
   163  		c.DataRef = str[:sp]
   164  	}
   165  	return c, nil
   166  }