mirror of
				https://gitcode.com/gitea/gitea.git
				synced 2025-11-01 01:36:12 +08:00 
			
		
		
		
	 1d332342db
			
		
	
	1d332342db
	
	
	
		
			
			* Added package store settings. * Added models. * Added generic package registry. * Added tests. * Added NuGet package registry. * Moved service index to api file. * Added NPM package registry. * Added Maven package registry. * Added PyPI package registry. * Summary is deprecated. * Changed npm name. * Sanitize project url. * Allow only scoped packages. * Added user interface. * Changed method name. * Added missing migration file. * Set page info. * Added documentation. * Added documentation links. * Fixed wrong error message. * Lint template files. * Fixed merge errors. * Fixed unit test storage path. * Switch to json module. * Added suggestions. * Added package webhook. * Add package api. * Fixed swagger file. * Fixed enum and comments. * Fixed NuGet pagination. * Print test names. * Added api tests. * Fixed access level. * Fix User unmarshal. * Added RubyGems package registry. * Fix lint. * Implemented io.Writer. * Added support for sha256/sha512 checksum files. * Improved maven-metadata.xml support. * Added support for symbol package uploads. * Added tests. * Added overview docs. * Added npm dependencies and keywords. * Added no-packages information. * Display file size. * Display asset count. * Fixed filter alignment. * Added package icons. * Formatted instructions. * Allow anonymous package downloads. * Fixed comments. * Fixed postgres test. * Moved file. * Moved models to models/packages. * Use correct error response format per client. * Use simpler search form. * Fixed IsProd. * Restructured data model. * Prevent empty filename. * Fix swagger. * Implemented user/org registry. * Implemented UI. * Use GetUserByIDCtx. * Use table for dependencies. * make svg * Added support for unscoped npm packages. * Add support for npm dist tags. * Added tests for npm tags. * Unlink packages if repository gets deleted. * Prevent user/org delete if a packages exist. * Use package unlink in repository service. * Added support for composer packages. * Restructured package docs. * Added missing tests. * Fixed generic content page. * Fixed docs. * Fixed swagger. * Added missing type. * Fixed ambiguous column. * Organize content store by sha256 hash. * Added admin package management. * Added support for sorting. * Add support for multiple identical versions/files. * Added missing repository unlink. * Added file properties. * make fmt * lint * Added Conan package registry. * Updated docs. * Unify package names. * Added swagger enum. * Use longer TEXT column type. * Removed version composite key. * Merged package and container registry. * Removed index. * Use dedicated package router. * Moved files to new location. * Updated docs. * Fixed JOIN order. * Fixed GROUP BY statement. * Fixed GROUP BY #2. * Added symbol server support. * Added more tests. * Set NOT NULL. * Added setting to disable package registries. * Moved auth into service. * refactor * Use ctx everywhere. * Added package cleanup task. * Changed packages path. * Added container registry. * Refactoring * Updated comparison. * Fix swagger. * Fixed table order. * Use token auth for npm routes. * Enabled ReverseProxy auth. * Added packages link for orgs. * Fixed anonymous org access. * Enable copy button for setup instructions. * Merge error * Added suggestions. * Fixed merge. * Handle "generic". * Added link for TODO. * Added suggestions. * Changed temporary buffer filename. * Added suggestions. * Apply suggestions from code review Co-authored-by: Thomas Boerger <thomas@webhippie.de> * Update docs/content/doc/packages/nuget.en-us.md Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Thomas Boerger <thomas@webhippie.de>
		
			
				
	
	
		
			188 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2021 The Gitea Authors. All rights reserved.
 | |
| // Use of this source code is governed by a MIT-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package nuget
 | |
| 
 | |
| import (
 | |
| 	"archive/zip"
 | |
| 	"encoding/xml"
 | |
| 	"errors"
 | |
| 	"io"
 | |
| 	"path/filepath"
 | |
| 	"regexp"
 | |
| 	"strings"
 | |
| 
 | |
| 	"code.gitea.io/gitea/modules/validation"
 | |
| 
 | |
| 	"github.com/hashicorp/go-version"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// ErrMissingNuspecFile indicates a missing Nuspec file
 | |
| 	ErrMissingNuspecFile = errors.New("Nuspec file is missing")
 | |
| 	// ErrNuspecFileTooLarge indicates a Nuspec file which is too large
 | |
| 	ErrNuspecFileTooLarge = errors.New("Nuspec file is too large")
 | |
| 	// ErrNuspecInvalidID indicates an invalid id in the Nuspec file
 | |
| 	ErrNuspecInvalidID = errors.New("Nuspec file contains an invalid id")
 | |
| 	// ErrNuspecInvalidVersion indicates an invalid version in the Nuspec file
 | |
| 	ErrNuspecInvalidVersion = errors.New("Nuspec file contains an invalid version")
 | |
| )
 | |
| 
 | |
| // PackageType specifies the package type the metadata describes
 | |
| type PackageType int
 | |
| 
 | |
| const (
 | |
| 	// DependencyPackage represents a package (*.nupkg)
 | |
| 	DependencyPackage PackageType = iota + 1
 | |
| 	// SymbolsPackage represents a symbol package (*.snupkg)
 | |
| 	SymbolsPackage
 | |
| 
 | |
| 	PropertySymbolID = "nuget.symbol.id"
 | |
| )
 | |
| 
 | |
| var idmatch = regexp.MustCompile(`\A\w+(?:[.-]\w+)*\z`)
 | |
| 
 | |
| const maxNuspecFileSize = 3 * 1024 * 1024
 | |
| 
 | |
| // Package represents a Nuget package
 | |
| type Package struct {
 | |
| 	PackageType PackageType
 | |
| 	ID          string
 | |
| 	Version     string
 | |
| 	Metadata    *Metadata
 | |
| }
 | |
| 
 | |
| // Metadata represents the metadata of a Nuget package
 | |
| type Metadata struct {
 | |
| 	Description   string                  `json:"description,omitempty"`
 | |
| 	ReleaseNotes  string                  `json:"release_notes,omitempty"`
 | |
| 	Authors       string                  `json:"authors,omitempty"`
 | |
| 	ProjectURL    string                  `json:"project_url,omitempty"`
 | |
| 	RepositoryURL string                  `json:"repository_url,omitempty"`
 | |
| 	Dependencies  map[string][]Dependency `json:"dependencies,omitempty"`
 | |
| }
 | |
| 
 | |
| // Dependency represents a dependency of a Nuget package
 | |
| type Dependency struct {
 | |
| 	ID      string `json:"id"`
 | |
| 	Version string `json:"version"`
 | |
| }
 | |
| 
 | |
| type nuspecPackage struct {
 | |
| 	Metadata struct {
 | |
| 		ID                       string `xml:"id"`
 | |
| 		Version                  string `xml:"version"`
 | |
| 		Authors                  string `xml:"authors"`
 | |
| 		RequireLicenseAcceptance bool   `xml:"requireLicenseAcceptance"`
 | |
| 		ProjectURL               string `xml:"projectUrl"`
 | |
| 		Description              string `xml:"description"`
 | |
| 		ReleaseNotes             string `xml:"releaseNotes"`
 | |
| 		PackageTypes             struct {
 | |
| 			PackageType []struct {
 | |
| 				Name string `xml:"name,attr"`
 | |
| 			} `xml:"packageType"`
 | |
| 		} `xml:"packageTypes"`
 | |
| 		Repository struct {
 | |
| 			URL string `xml:"url,attr"`
 | |
| 		} `xml:"repository"`
 | |
| 		Dependencies struct {
 | |
| 			Group []struct {
 | |
| 				TargetFramework string `xml:"targetFramework,attr"`
 | |
| 				Dependency      []struct {
 | |
| 					ID      string `xml:"id,attr"`
 | |
| 					Version string `xml:"version,attr"`
 | |
| 					Exclude string `xml:"exclude,attr"`
 | |
| 				} `xml:"dependency"`
 | |
| 			} `xml:"group"`
 | |
| 		} `xml:"dependencies"`
 | |
| 	} `xml:"metadata"`
 | |
| }
 | |
| 
 | |
| // ParsePackageMetaData parses the metadata of a Nuget package file
 | |
| func ParsePackageMetaData(r io.ReaderAt, size int64) (*Package, error) {
 | |
| 	archive, err := zip.NewReader(r, size)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	for _, file := range archive.File {
 | |
| 		if filepath.Dir(file.Name) != "." {
 | |
| 			continue
 | |
| 		}
 | |
| 		if strings.HasSuffix(strings.ToLower(file.Name), ".nuspec") {
 | |
| 			if file.UncompressedSize64 > maxNuspecFileSize {
 | |
| 				return nil, ErrNuspecFileTooLarge
 | |
| 			}
 | |
| 			f, err := archive.Open(file.Name)
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			defer f.Close()
 | |
| 
 | |
| 			return ParseNuspecMetaData(f)
 | |
| 		}
 | |
| 	}
 | |
| 	return nil, ErrMissingNuspecFile
 | |
| }
 | |
| 
 | |
| // ParseNuspecMetaData parses a Nuspec file to retrieve the metadata of a Nuget package
 | |
| func ParseNuspecMetaData(r io.Reader) (*Package, error) {
 | |
| 	var p nuspecPackage
 | |
| 	if err := xml.NewDecoder(r).Decode(&p); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if !idmatch.MatchString(p.Metadata.ID) {
 | |
| 		return nil, ErrNuspecInvalidID
 | |
| 	}
 | |
| 
 | |
| 	v, err := version.NewSemver(p.Metadata.Version)
 | |
| 	if err != nil {
 | |
| 		return nil, ErrNuspecInvalidVersion
 | |
| 	}
 | |
| 
 | |
| 	if !validation.IsValidURL(p.Metadata.ProjectURL) {
 | |
| 		p.Metadata.ProjectURL = ""
 | |
| 	}
 | |
| 
 | |
| 	packageType := DependencyPackage
 | |
| 	for _, pt := range p.Metadata.PackageTypes.PackageType {
 | |
| 		if pt.Name == "SymbolsPackage" {
 | |
| 			packageType = SymbolsPackage
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	m := &Metadata{
 | |
| 		Description:   p.Metadata.Description,
 | |
| 		ReleaseNotes:  p.Metadata.ReleaseNotes,
 | |
| 		Authors:       p.Metadata.Authors,
 | |
| 		ProjectURL:    p.Metadata.ProjectURL,
 | |
| 		RepositoryURL: p.Metadata.Repository.URL,
 | |
| 		Dependencies:  make(map[string][]Dependency),
 | |
| 	}
 | |
| 
 | |
| 	for _, group := range p.Metadata.Dependencies.Group {
 | |
| 		deps := make([]Dependency, 0, len(group.Dependency))
 | |
| 		for _, dep := range group.Dependency {
 | |
| 			if dep.ID == "" || dep.Version == "" {
 | |
| 				continue
 | |
| 			}
 | |
| 			deps = append(deps, Dependency{
 | |
| 				ID:      dep.ID,
 | |
| 				Version: dep.Version,
 | |
| 			})
 | |
| 		}
 | |
| 		if len(deps) > 0 {
 | |
| 			m.Dependencies[group.TargetFramework] = deps
 | |
| 		}
 | |
| 	}
 | |
| 	return &Package{
 | |
| 		PackageType: packageType,
 | |
| 		ID:          p.Metadata.ID,
 | |
| 		Version:     v.String(),
 | |
| 		Metadata:    m,
 | |
| 	}, nil
 | |
| }
 |