code.gitea.io/gitea@v1.19.3/modules/packages/vagrant/metadata.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package vagrant
     5  
     6  import (
     7  	"archive/tar"
     8  	"compress/gzip"
     9  	"io"
    10  	"strings"
    11  
    12  	"code.gitea.io/gitea/modules/json"
    13  	"code.gitea.io/gitea/modules/validation"
    14  )
    15  
    16  const (
    17  	PropertyProvider = "vagrant.provider"
    18  )
    19  
    20  // Metadata represents the metadata of a Vagrant package
    21  type Metadata struct {
    22  	Author        string `json:"author,omitempty"`
    23  	Description   string `json:"description,omitempty"`
    24  	ProjectURL    string `json:"project_url,omitempty"`
    25  	RepositoryURL string `json:"repository_url,omitempty"`
    26  }
    27  
    28  // ParseMetadataFromBox parses the metadata of a box file
    29  func ParseMetadataFromBox(r io.Reader) (*Metadata, error) {
    30  	gzr, err := gzip.NewReader(r)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	defer gzr.Close()
    35  
    36  	tr := tar.NewReader(gzr)
    37  	for {
    38  		hd, err := tr.Next()
    39  		if err == io.EOF {
    40  			break
    41  		}
    42  		if err != nil {
    43  			return nil, err
    44  		}
    45  
    46  		if hd.Typeflag != tar.TypeReg {
    47  			continue
    48  		}
    49  
    50  		if hd.Name == "info.json" {
    51  			return ParseInfoFile(tr)
    52  		}
    53  	}
    54  
    55  	return &Metadata{}, nil
    56  }
    57  
    58  // ParseInfoFile parses a info.json file to retrieve the metadata of a Vagrant package
    59  func ParseInfoFile(r io.Reader) (*Metadata, error) {
    60  	var values map[string]string
    61  	if err := json.NewDecoder(r).Decode(&values); err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	m := &Metadata{}
    66  
    67  	// There is no defined format for this file, just try the common keys
    68  	for k, v := range values {
    69  		switch strings.ToLower(k) {
    70  		case "description":
    71  			fallthrough
    72  		case "short_description":
    73  			m.Description = v
    74  		case "website":
    75  			fallthrough
    76  		case "homepage":
    77  			fallthrough
    78  		case "url":
    79  			if validation.IsValidURL(v) {
    80  				m.ProjectURL = v
    81  			}
    82  		case "repository":
    83  			fallthrough
    84  		case "source":
    85  			if validation.IsValidURL(v) {
    86  				m.RepositoryURL = v
    87  			}
    88  		case "author":
    89  			fallthrough
    90  		case "authors":
    91  			m.Author = v
    92  		}
    93  	}
    94  
    95  	return m, nil
    96  }