github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/base/dsfs/package.go (about)

     1  package dsfs
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/qri-io/qfs"
     8  	"github.com/qri-io/qfs/muxfs"
     9  )
    10  
    11  const (
    12  	// transformScriptFilename is the name transform scripts will be written to
    13  	transformScriptFilename = "transform_script"
    14  	// vizsScriptFilename is the name transform scripts will be written to
    15  	vizScriptFilename = "viz_script"
    16  	// readmeScriptFilename is the name of the readme file that will be written to
    17  	readmeScriptFilename = "readme.json"
    18  )
    19  
    20  // PackageFile specifies the different types of files that are
    21  // stored in a package
    22  type PackageFile int
    23  
    24  const (
    25  	// PackageFileUnknown is the default package file, which
    26  	// should be erroneous, as there is no sensible default
    27  	// for PackageFile
    28  	PackageFileUnknown PackageFile = iota
    29  	// PackageFileDataset is the main dataset.json file
    30  	// that contains all dataset metadata, and is the only
    31  	// required file to constitute a dataset
    32  	PackageFileDataset
    33  	// PackageFileStructure isolates this dataset's structure
    34  	// in it's own file
    35  	PackageFileStructure
    36  	// PackageFileAbstract is the abstract verion of
    37  	// structure
    38  	PackageFileAbstract
    39  	// PackageFileResources lists the resource datasets
    40  	// that went into creating a dataset
    41  	// TODO - I think this can be removed now that Transform exists
    42  	PackageFileResources
    43  	// PackageFileCommit isolates the user-entered
    44  	// documentation of the changes to this dataset's history
    45  	PackageFileCommit
    46  	// PackageFileTransform isloates the concrete transform that
    47  	// generated this dataset
    48  	PackageFileTransform
    49  	// PackageFileAbstractTransform is the abstract version of
    50  	// the operation performed to create this dataset
    51  	PackageFileAbstractTransform
    52  	// PackageFileMeta encapsulates human-readable metadata
    53  	PackageFileMeta
    54  	// PackageFileViz isolates the data related to representing a dataset as a
    55  	// visualization
    56  	PackageFileViz
    57  	// PackageFileVizScript is the viz template
    58  	PackageFileVizScript
    59  	// PackageFileRenderedViz is the rendered visualization of the dataset
    60  	PackageFileRenderedViz
    61  	// PackageFileReadme connects readme data to the dataset package
    62  	PackageFileReadme
    63  	// PackageFileReadmeScript is the raw readme of the dataset
    64  	PackageFileReadmeScript
    65  	// PackageFileRenderedReadme is the rendered readme of the dataset
    66  	PackageFileRenderedReadme
    67  	// PackageFileStats isolates the statistical metadata component
    68  	PackageFileStats
    69  )
    70  
    71  // filenames maps PackageFile to their filename counterparts
    72  var filenames = map[PackageFile]string{
    73  	PackageFileUnknown:           "",
    74  	PackageFileDataset:           "dataset.json",
    75  	PackageFileStructure:         "structure.json",
    76  	PackageFileAbstract:          "abstract.json",
    77  	PackageFileAbstractTransform: "abstract_transform.json",
    78  	PackageFileResources:         "resources",
    79  	PackageFileCommit:            "commit.json",
    80  	PackageFileTransform:         "transform.json",
    81  	PackageFileMeta:              "meta.json",
    82  	PackageFileViz:               "viz.json",
    83  	PackageFileVizScript:         "viz_script",
    84  	PackageFileRenderedViz:       "index.html",
    85  	PackageFileReadme:            "readme.json",
    86  	PackageFileReadmeScript:      "readme.md",
    87  	PackageFileRenderedReadme:    "readme.html",
    88  	PackageFileStats:             "stats.json",
    89  }
    90  
    91  // String implements the io.Stringer interface for PackageFile
    92  func (p PackageFile) String() string {
    93  	return filenames[p]
    94  }
    95  
    96  // Filename gives the canonical filename for a PackageFile
    97  func (p PackageFile) Filename() string {
    98  	return fmt.Sprintf("/%s", filenames[p])
    99  }
   100  
   101  // GetHashBase strips paths to return just the hash
   102  func GetHashBase(in string) string {
   103  	in = strings.TrimLeft(in, "/")
   104  	for _, fsType := range muxfs.KnownFSTypes() {
   105  		in = strings.TrimPrefix(in, fsType)
   106  	}
   107  	in = strings.TrimLeft(in, "/")
   108  	return strings.Split(in, "/")[0]
   109  }
   110  
   111  // PackageFilepath returns the path to a package file for a given base path
   112  // It relies relies on package storage conventions and qfs.Filesystem path prefixes
   113  // If you supply a path that does not match the filestore's naming conventions will
   114  // return an invalid path
   115  func PackageFilepath(fs qfs.Filesystem, path string, pf PackageFile) string {
   116  	prefix := fs.Type()
   117  	if prefix == muxfs.FilestoreType {
   118  		// TODO(b5) - for situations where a muxfs is passed, we rely on path being populated
   119  		// with the desired filesystem resolver intact. This should be hardened
   120  		return strings.Join([]string{path, pf.String()}, "/")
   121  	}
   122  
   123  	if prefix == "" {
   124  		return path
   125  	}
   126  	// Keep forward slashes in the path by using strings.Join instead of filepath.Join. This
   127  	// will make IPFS happy on Windows, since it always wants "/" and not "\". The blank
   128  	// path component in the front of this join ensures that the path begins with a "/" character.
   129  	return strings.Join([]string{"", prefix, GetHashBase(path), pf.String()}, "/")
   130  }