github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/extractor/file/file.go (about)

     1  /*
     2   * Copyright (c) 2018-2020 vChain, Inc. All Rights Reserved.
     3   * This software is released under GPL3.
     4   * The full license information can be found under:
     5   * https://www.gnu.org/licenses/gpl-3.0.en.html
     6   *
     7   */
     8  
     9  package file
    10  
    11  import (
    12  	"crypto/sha256"
    13  	"encoding/hex"
    14  	"io"
    15  	"os"
    16  	"strings"
    17  
    18  	"github.com/vchain-us/vcn/pkg/api"
    19  	"github.com/vchain-us/vcn/pkg/extractor"
    20  	"github.com/vchain-us/vcn/pkg/uri"
    21  )
    22  
    23  // Scheme for file
    24  const Scheme = "file"
    25  
    26  // Artifact returns a file *api.Artifact from a given u
    27  func Artifact(u *uri.URI, options ...extractor.Option) ([]*api.Artifact, error) {
    28  
    29  	if u.Scheme != Scheme {
    30  		return nil, nil
    31  	}
    32  
    33  	path := strings.TrimPrefix(u.Opaque, "//")
    34  
    35  	f, err := os.Open(path)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	defer f.Close()
    40  
    41  	// Metadata container
    42  	m := api.Metadata{}
    43  
    44  	// Hash
    45  	h := sha256.New()
    46  	if _, err := io.Copy(h, f); err != nil {
    47  		return nil, err
    48  	}
    49  	checksum := h.Sum(nil)
    50  
    51  	// Name and Size
    52  	stat, err := f.Stat()
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	// ContentType
    58  	ct, err := contentType(f)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	// Infer version from filename
    64  	if version := inferVer(stat.Name()); version != "" {
    65  		m["version"] = version
    66  	}
    67  
    68  	// Sniff executable info, if any
    69  	if ok, data, _ := xInfo(f, &ct); ok {
    70  		m.SetValues(data)
    71  	}
    72  
    73  	return []*api.Artifact{{
    74  		Kind:        Scheme,
    75  		Name:        stat.Name(),
    76  		Hash:        hex.EncodeToString(checksum),
    77  		Size:        uint64(stat.Size()),
    78  		ContentType: ct,
    79  		Metadata:    m,
    80  	}}, nil
    81  }