mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-06 03:52:36 +02:00
Fix various version parsing problems (#36553)
1. handle non-release git verions (not semver) 2. fix rubygems version "0" handling (only ">=" can be omitted) 3. lazy compile the regexp to improve performance 4. make test data maintainable, use origin source code instead of compressed binary
This commit is contained in:
1 parent
2ff4f4a909
commit
08b7a30867
8 files changed
+153
-47
No files matched your search
Generated
+1
-1
@@ -697,7 +697,7 @@
|
|||||||
{
|
{
|
||||||
"name": "github.com/hashicorp/go-version",
|
"name": "github.com/hashicorp/go-version",
|
||||||
"path": "github.com/hashicorp/go-version/LICENSE",
|
"path": "github.com/hashicorp/go-version/LICENSE",
|
||||||
"licenseText": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. “Contributor Version”\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor’s Contribution.\n\n1.3. “Contribution”\n\n means Covered Software of a particular Contributor.\n\n1.4. “Covered Software”\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. “Incompatible With Secondary Licenses”\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of version\n 1.1 or earlier of the License, but not also under the terms of a\n Secondary License.\n\n1.6. “Executable Form”\n\n means any form of the work other than Source Code Form.\n\n1.7. “Larger Work”\n\n means a work that combines Covered Software with other material, in a separate\n file or files, that is not Covered Software.\n\n1.8. “License”\n\n means this document.\n\n1.9. “Licensable”\n\n means having the right to grant, to the maximum extent possible, whether at the\n time of the initial grant or subsequently, any and all of the rights conveyed by\n this License.\n\n1.10. “Modifications”\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to, deletion\n from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. “Patent Claims” of a Contributor\n\n means any patent claim(s), including without limitation, method, process,\n and apparatus claims, in any patent Licensable by such Contributor that\n would be infringed, but for the grant of the License, by the making,\n using, selling, offering for sale, having made, import, or transfer of\n either its Contributions or its Contributor Version.\n\n1.12. “Secondary License”\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. “Source Code Form”\n\n means the form of the work preferred for making modifications.\n\n1.14. “You” (or “Your”)\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, “You” includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, “control” means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or as\n part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its Contributions\n or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution become\n effective for each Contribution on the date the Contributor first distributes\n such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under this\n License. No additional rights or licenses will be implied from the distribution\n or licensing of Covered Software under this License. Notwithstanding Section\n 2.1(b) above, no patent license is granted by a Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party’s\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent Claims infringed by Covered Software Line truncated
|
"licenseText": "Copyright IBM Corp. 2014, 2025\n\nMozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n means each individual or legal entity that creates, contributes to the\n creation of, or owns Covered Software.\n\n1.2. “Contributor Version”\n\n means the combination of the Contributions of others (if any) used by a\n Contributor and that particular Contributor’s Contribution.\n\n1.3. “Contribution”\n\n means Covered Software of a particular Contributor.\n\n1.4. “Covered Software”\n\n means Source Code Form to which the initial Contributor has attached the\n notice in Exhibit A, the Executable Form of such Source Code Form, and\n Modifications of such Source Code Form, in each case including portions\n thereof.\n\n1.5. “Incompatible With Secondary Licenses”\n means\n\n a. that the initial Contributor has attached the notice described in\n Exhibit B to the Covered Software; or\n\n b. that the Covered Software was made available under the terms of version\n 1.1 or earlier of the License, but not also under the terms of a\n Secondary License.\n\n1.6. “Executable Form”\n\n means any form of the work other than Source Code Form.\n\n1.7. “Larger Work”\n\n means a work that combines Covered Software with other material, in a separate\n file or files, that is not Covered Software.\n\n1.8. “License”\n\n means this document.\n\n1.9. “Licensable”\n\n means having the right to grant, to the maximum extent possible, whether at the\n time of the initial grant or subsequently, any and all of the rights conveyed by\n this License.\n\n1.10. “Modifications”\n\n means any of the following:\n\n a. any file in Source Code Form that results from an addition to, deletion\n from, or modification of the contents of Covered Software; or\n\n b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. “Patent Claims” of a Contributor\n\n means any patent claim(s), including without limitation, method, process,\n and apparatus claims, in any patent Licensable by such Contributor that\n would be infringed, but for the grant of the License, by the making,\n using, selling, offering for sale, having made, import, or transfer of\n either its Contributions or its Contributor Version.\n\n1.12. “Secondary License”\n\n means either the GNU General Public License, Version 2.0, the GNU Lesser\n General Public License, Version 2.1, the GNU Affero General Public\n License, Version 3.0, or any later versions of those licenses.\n\n1.13. “Source Code Form”\n\n means the form of the work preferred for making modifications.\n\n1.14. “You” (or “Your”)\n\n means an individual or a legal entity exercising rights under this\n License. For legal entities, “You” includes any entity that controls, is\n controlled by, or is under common control with You. For purposes of this\n definition, “control” means (a) the power, direct or indirect, to cause\n the direction or management of such entity, whether by contract or\n otherwise, or (b) ownership of more than fifty percent (50%) of the\n outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n Each Contributor hereby grants You a world-wide, royalty-free,\n non-exclusive license:\n\n a. under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or as\n part of a Larger Work; and\n\n b. under Patent Claims of such Contributor to make, use, sell, offer for\n sale, have made, import, and otherwise transfer either its Contributions\n or its Contributor Version.\n\n2.2. Effective Date\n\n The licenses granted in Section 2.1 with respect to any Contribution become\n effective for each Contribution on the date the Contributor first distributes\n such Contribution.\n\n2.3. Limitations on Grant Scope\n\n The licenses granted in this Section 2 are the only rights granted under this\n License. No additional rights or licenses will be implied from the distribution\n or licensing of Covered Software under this License. Notwithstanding Section\n 2.1(b) above, no patent license is granted by a Contributor:\n\n a. for any code that a Contributor has removed from Covered Software; or\n\n b. for infringements caused by: (i) Your and any other third party’s\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n c. under Patent ClaLine truncated
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "github.com/hashicorp/golang-lru/v2",
|
"name": "github.com/hashicorp/golang-lru/v2",
|
||||||
|
|||||||
@@ -296,8 +296,6 @@ ignore (
|
|||||||
|
|
||||||
replace github.com/jaytaylor/html2text => github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347
|
replace github.com/jaytaylor/html2text => github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347
|
||||||
|
|
||||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
|
||||||
|
|
||||||
replace github.com/nektos/act => gitea.com/gitea/act v0.261.7-0.20251003180512-ac6e4b751763
|
replace github.com/nektos/act => gitea.com/gitea/act v0.261.7-0.20251003180512-ac6e4b751763
|
||||||
|
|
||||||
replace git.sr.ht/~mariusor/go-xsd-duration => gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078
|
replace git.sr.ht/~mariusor/go-xsd-duration => gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
|||||||
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
|
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
|
||||||
github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920 h1:mWAVGlovzUfREJBhm0GwJnDNu21yRrL9QH9NIzAU3rg=
|
github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920 h1:mWAVGlovzUfREJBhm0GwJnDNu21yRrL9QH9NIzAU3rg=
|
||||||
github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920/go.mod h1:zWxcT7BIWOe05xVJL0VMvO/PJ6RpoCux10heb77H6Q8=
|
github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920/go.mod h1:zWxcT7BIWOe05xVJL0VMvO/PJ6RpoCux10heb77H6Q8=
|
||||||
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
|
||||||
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
|
||||||
@@ -474,6 +472,8 @@ github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVU
|
|||||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
||||||
|
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||||
|
|||||||
+9
-4
@@ -88,12 +88,17 @@ func parseGitVersionLine(s string) (*version.Version, error) {
|
|||||||
return nil, fmt.Errorf("invalid git version: %q", s)
|
return nil, fmt.Errorf("invalid git version: %q", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// version string is like: "git version 2.29.3" or "git version 2.29.3.windows.1"
|
// version output is like: "git version {versionString}"
|
||||||
|
// versionString can be:
|
||||||
|
// * "2.5.3"
|
||||||
|
// * "2.29.3.windows.1"
|
||||||
|
// * "2.28.0.618.gf4bc123cb7": https://github.com/go-gitea/gitea/issues/12731
|
||||||
versionString := fields[2]
|
versionString := fields[2]
|
||||||
if pos := strings.Index(versionString, "windows"); pos >= 1 {
|
versionFields := strings.Split(versionString, ".")
|
||||||
versionString = versionString[:pos-1]
|
if len(versionFields) > 3 {
|
||||||
|
versionFields = versionFields[:3]
|
||||||
}
|
}
|
||||||
return version.NewVersion(versionString)
|
return version.NewVersion(strings.Join(versionFields, "."))
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkGitVersionCompatibility(gitVer *version.Version) error {
|
func checkGitVersionCompatibility(gitVer *version.Version) error {
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ func TestParseGitVersion(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "2.29.3", v.String())
|
assert.Equal(t, "2.29.3", v.String())
|
||||||
|
|
||||||
|
v, err = parseGitVersionLine("git version 2.28.0.618.gf4bc123cb7")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "2.28.0", v.String())
|
||||||
|
|
||||||
_, err = parseGitVersionLine("git version")
|
_, err = parseGitVersionLine("git version")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/modules/validation"
|
"code.gitea.io/gitea/modules/validation"
|
||||||
@@ -25,7 +26,9 @@ var (
|
|||||||
ErrInvalidVersion = util.NewInvalidArgumentErrorf("package version is invalid")
|
ErrInvalidVersion = util.NewInvalidArgumentErrorf("package version is invalid")
|
||||||
)
|
)
|
||||||
|
|
||||||
var versionMatcher = regexp.MustCompile(`\A[0-9]+(?:\.[0-9a-zA-Z]+)*(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?\z`)
|
var versionMatcher = sync.OnceValue(func() *regexp.Regexp {
|
||||||
|
return regexp.MustCompile(`\A[0-9]+(?:\.[0-9a-zA-Z]+)*(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?\z`)
|
||||||
|
})
|
||||||
|
|
||||||
// Package represents a RubyGems package
|
// Package represents a RubyGems package
|
||||||
type Package struct {
|
type Package struct {
|
||||||
@@ -128,7 +131,7 @@ func (r requirement) AsVersionRequirement() []VersionRequirement {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
version, ok := versionInt.(string)
|
version, ok := versionInt.(string)
|
||||||
if !ok || version == "0" {
|
if !ok || (version == "0" && restriction == ">=") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +179,7 @@ func parseMetadataFile(r io.Reader) (*Package, error) {
|
|||||||
return nil, ErrInvalidName
|
return nil, ErrInvalidName
|
||||||
}
|
}
|
||||||
|
|
||||||
if !versionMatcher.MatchString(spec.Version.Version) {
|
if !versionMatcher().MatchString(spec.Version.Version) {
|
||||||
return nil, ErrInvalidVersion
|
return nil, ErrInvalidVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,42 +4,30 @@
|
|||||||
package rubygems
|
package rubygems
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"io"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/test"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParsePackageMetaData(t *testing.T) {
|
func TestParsePackageMetaData(t *testing.T) {
|
||||||
createArchive := func(filename string, content []byte) io.Reader {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
tw := tar.NewWriter(&buf)
|
|
||||||
hdr := &tar.Header{
|
|
||||||
Name: filename,
|
|
||||||
Mode: 0o600,
|
|
||||||
Size: int64(len(content)),
|
|
||||||
}
|
|
||||||
tw.WriteHeader(hdr)
|
|
||||||
tw.Write(content)
|
|
||||||
tw.Close()
|
|
||||||
return &buf
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("MissingMetadataFile", func(t *testing.T) {
|
t.Run("MissingMetadataFile", func(t *testing.T) {
|
||||||
data := createArchive("dummy.txt", []byte{0})
|
data := test.WriteTarArchive(map[string]string{"dummy.txt": ""})
|
||||||
|
|
||||||
rp, err := ParsePackageMetaData(data)
|
rp, err := ParsePackageMetaData(data)
|
||||||
assert.ErrorIs(t, err, ErrMissingMetadataFile)
|
assert.ErrorIs(t, err, ErrMissingMetadataFile)
|
||||||
assert.Nil(t, rp)
|
assert.Nil(t, rp)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Valid", func(t *testing.T) {
|
t.Run("Valid", func(t *testing.T) {
|
||||||
content, _ := base64.StdEncoding.DecodeString("H4sICHC/I2EEAG1ldGFkYXRhAAEeAOH/bmFtZTogZwp2ZXJzaW9uOgogIHZlcnNpb246IDEKWw35Tx4AAAA=")
|
metadataContent := test.CompressGzip(`
|
||||||
data := createArchive("metadata.gz", content)
|
name: g
|
||||||
|
version:
|
||||||
|
version: 1
|
||||||
|
`)
|
||||||
|
data := test.WriteTarArchive(map[string]string{
|
||||||
|
"metadata.gz": metadataContent.String(),
|
||||||
|
})
|
||||||
rp, err := ParsePackageMetaData(data)
|
rp, err := ParsePackageMetaData(data)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, rp)
|
assert.NotNil(t, rp)
|
||||||
@@ -47,17 +35,86 @@ func TestParsePackageMetaData(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseMetadataFile(t *testing.T) {
|
func TestParseMetadataFile(t *testing.T) {
|
||||||
content, _ := base64.StdEncoding.DecodeString(`H4sIAMe7I2ECA9VVTW/UMBC9+1eYXvaUbJpSQBZUHJAqDlwK4kCFIseZzZrGH9iTqisEv52Js9nd
|
content := test.CompressGzip(`--- !ruby/object:Gem::Specification
|
||||||
0KqggiqRXWnX45n3ZuZ5nCzL+JPQ15ulq7+AQnEORoj3HpReaSVRO8usNCB4qxEku4YQySbuCPo4
|
name: gitea
|
||||||
bjHOd07HeZGfMt9JXLlgBB9imOxx7UIULOPnCZMMLsDXXgeiYbW2jQ6C0y9TELBSa6kJ6/IzaySS
|
version: !ruby/object:Gem::Version
|
||||||
R1mUx1nxIitPeFGI9M2L6eGfWAMebANWaUgktzN9M3lsKNmxutBb1AYyCibbNhsDFu+q9GK/Tc4z
|
version: 1.0.5
|
||||||
d2IcLBl9js5eHaXFsLyvXeNz0LQyL/YoLx8EsiCMBZlx46k6sS2PDD5AgA5kJPNKdhH2elWzOv7n
|
platform: ruby
|
||||||
uv9Q9Aau/6ngP84elvNpXh5oRVlB5/yW7BH0+qu0G4gqaI/JdEHBFBS5l+pKtsARIjIwUnfj8Le0
|
authors:
|
||||||
+TrdJLl2DG5A9SjrjgZ1mG+4QbAD+G4ZZBUap6qVnnzGf6Rwp+vliBRqtnYGPBEKvkb0USyXE8mS
|
- Gitea
|
||||||
dVoR6hj07u0HZgAl3SRS8G/fmXcRK20jyq6rDMSYQFgidamqkXbbuspLXE/0k7GphtKqe67GuRC/
|
autorequire:
|
||||||
yjAbmt9LsOMp8xMamFkSQ38fP5EFjdz8LA4do2C69VvqWXAJgrPbKZb58/xZXrKoW6ttW13Bhvzi
|
bindir: bin
|
||||||
4ftn7/yUxd4YGcglvTmmY8aGY3ZwRn4CqcWcidUGAAA=`)
|
cert_chain: []
|
||||||
rp, err := parseMetadataFile(bytes.NewReader(content))
|
date: 2021-08-23 00:00:00.000000000 Z
|
||||||
|
dependencies:
|
||||||
|
- !ruby/object:Gem::Dependency
|
||||||
|
name: runtime-dep
|
||||||
|
requirement: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: 1.2.0
|
||||||
|
- - "<"
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: '2.0'
|
||||||
|
type: :runtime
|
||||||
|
prerelease: false
|
||||||
|
version_requirements: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: 1.2.0
|
||||||
|
- - "<"
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: '2.0'
|
||||||
|
- !ruby/object:Gem::Dependency
|
||||||
|
name: dev-dep
|
||||||
|
requirement: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - "~>"
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: '0'
|
||||||
|
type: :development
|
||||||
|
prerelease: false
|
||||||
|
version_requirements: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - "~>"
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: '5.2'
|
||||||
|
description: RubyGems package test
|
||||||
|
email: rubygems@gitea.io
|
||||||
|
executables: []
|
||||||
|
extensions: []
|
||||||
|
extra_rdoc_files: []
|
||||||
|
files:
|
||||||
|
- lib/gitea.rb
|
||||||
|
homepage: https://gitea.io/
|
||||||
|
licenses:
|
||||||
|
- MIT
|
||||||
|
metadata: {}
|
||||||
|
post_install_message:
|
||||||
|
rdoc_options: []
|
||||||
|
require_paths:
|
||||||
|
- lib
|
||||||
|
required_ruby_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: 2.3.0
|
||||||
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: '0'
|
||||||
|
requirements: []
|
||||||
|
rubyforge_project:
|
||||||
|
rubygems_version: 2.7.6.2
|
||||||
|
signing_key:
|
||||||
|
specification_version: 4
|
||||||
|
summary: Gitea package
|
||||||
|
test_files: []
|
||||||
|
`)
|
||||||
|
rp, err := parseMetadataFile(content)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, rp)
|
assert.NotNil(t, rp)
|
||||||
|
|
||||||
@@ -84,5 +141,5 @@ yjAbmt9LsOMp8xMamFkSQ38fP5EFjdz8LA4do2C69VvqWXAJgrPbKZb58/xZXrKoW6ttW13Bhvzi
|
|||||||
assert.Equal(t, "dev-dep", rp.Metadata.DevelopmentDependencies[0].Name)
|
assert.Equal(t, "dev-dep", rp.Metadata.DevelopmentDependencies[0].Name)
|
||||||
assert.Len(t, rp.Metadata.DevelopmentDependencies[0].Version, 1)
|
assert.Len(t, rp.Metadata.DevelopmentDependencies[0].Version, 1)
|
||||||
assert.Equal(t, "~>", rp.Metadata.DevelopmentDependencies[0].Version[0].Restriction)
|
assert.Equal(t, "~>", rp.Metadata.DevelopmentDependencies[0].Version[0].Restriction)
|
||||||
assert.Equal(t, "5.2", rp.Metadata.DevelopmentDependencies[0].Version[0].Version)
|
assert.Equal(t, "0", rp.Metadata.DevelopmentDependencies[0].Version[0].Version)
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -12,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RedirectURL returns the redirect URL of a http response.
|
// RedirectURL returns the redirect URL of a http response.
|
||||||
@@ -82,3 +84,40 @@ func ReadAllTarGzContent(r io.Reader) (map[string]string, error) {
|
|||||||
}
|
}
|
||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WriteTarArchive(files map[string]string) *bytes.Buffer {
|
||||||
|
return WriteTarCompression(func(w io.Writer) io.WriteCloser { return util.NopCloser{Writer: w} }, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteTarCompression[F func(io.Writer) io.WriteCloser | func(io.Writer) (io.WriteCloser, error)](compression F, files map[string]string) *bytes.Buffer {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
var cw io.WriteCloser
|
||||||
|
switch compressFunc := any(compression).(type) {
|
||||||
|
case func(io.Writer) io.WriteCloser:
|
||||||
|
cw = compressFunc(buf)
|
||||||
|
case func(io.Writer) (io.WriteCloser, error):
|
||||||
|
cw, _ = compressFunc(buf)
|
||||||
|
}
|
||||||
|
tw := tar.NewWriter(cw)
|
||||||
|
|
||||||
|
for name, content := range files {
|
||||||
|
hdr := &tar.Header{
|
||||||
|
Name: name,
|
||||||
|
Mode: 0o600,
|
||||||
|
Size: int64(len(content)),
|
||||||
|
}
|
||||||
|
_ = tw.WriteHeader(hdr)
|
||||||
|
_, _ = tw.Write([]byte(content))
|
||||||
|
}
|
||||||
|
_ = tw.Close()
|
||||||
|
_ = cw.Close()
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func CompressGzip(content string) *bytes.Buffer {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
cw := gzip.NewWriter(buf)
|
||||||
|
_, _ = cw.Write([]byte(content))
|
||||||
|
_ = cw.Close()
|
||||||
|
return buf
|
||||||
|
}
|
||||||
Reference in new issue
Block a user