diff --git a/go.mod b/go.mod index c12aba65870..f83524afea8 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/jedib0t/go-pretty/v6 v6.4.9 github.com/joho/godotenv v1.5.1 github.com/manifoldco/promptui v0.9.0 + github.com/maruel/natural v1.1.1 github.com/mattn/go-isatty v0.0.20 github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index 8f7235d2150..58a7462960a 100644 --- a/go.sum +++ b/go.sum @@ -115,6 +115,8 @@ github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= diff --git a/pkg/ddevapp/apptypes.go b/pkg/ddevapp/apptypes.go index ec2e9d50eb4..cbbf065e83e 100644 --- a/pkg/ddevapp/apptypes.go +++ b/pkg/ddevapp/apptypes.go @@ -10,6 +10,7 @@ import ( "github.com/ddev/ddev/pkg/nodeps" "github.com/ddev/ddev/pkg/util" + "github.com/maruel/natural" "github.com/pkg/errors" ) @@ -485,7 +486,7 @@ func GetValidAppTypes() []string { keys := make([]string, 0, len(appTypeMatrix)) for k := range appTypeMatrix { keys = append(keys, k) - sort.Strings(keys) + sort.Sort(natural.StringSlice(keys)) } return keys } diff --git a/pkg/ddevapp/config.go b/pkg/ddevapp/config.go index db102282f10..89f7f4af460 100644 --- a/pkg/ddevapp/config.go +++ b/pkg/ddevapp/config.go @@ -531,10 +531,6 @@ func (app *DdevApp) ValidateConfig() error { } } - // if app.Database.Type == nodeps.Postgres && (nodeps.ArrayContainsString([]string{"wordpress", "magento", "magento2"}, app.Type)) { - // return fmt.Errorf("the %s project has a project type %s that does not support PostgreSQL database", app.Name, app.Type) - // } - return nil } diff --git a/pkg/nodeps/values.go b/pkg/nodeps/values.go index 071b20f36a5..a8b983c1d63 100644 --- a/pkg/nodeps/values.go +++ b/pkg/nodeps/values.go @@ -1,6 +1,7 @@ package nodeps import ( + "github.com/maruel/natural" "sort" "github.com/ddev/ddev/pkg/config/types" @@ -136,7 +137,7 @@ func GetValidPHPVersions() []string { for p := range ValidPHPVersions { s = append(s, p) } - sort.Strings(s) + sort.Sort(natural.StringSlice(s)) return s } @@ -197,7 +198,7 @@ func GetValidMariaDBVersions() []string { for p := range ValidMariaDBVersions { s = append(s, p) } - sort.Strings(s) + sort.Sort(natural.StringSlice(s)) return s } @@ -218,7 +219,7 @@ func GetValidMySQLVersions() []string { for p := range ValidMySQLVersions { s = append(s, p) } - sort.Strings(s) + sort.Sort(natural.StringSlice(s)) return s } @@ -229,7 +230,7 @@ func GetValidPostgresVersions() []string { for p := range ValidPostgresVersions { s = append(s, p) } - sort.Strings(s) + sort.Sort(natural.StringSlice(s)) return s } diff --git a/vendor/github.com/maruel/natural/LICENSE b/vendor/github.com/maruel/natural/LICENSE new file mode 100644 index 00000000000..8e539f6924c --- /dev/null +++ b/vendor/github.com/maruel/natural/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Marc-Antoine Ruel + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/maruel/natural/README.md b/vendor/github.com/maruel/natural/README.md new file mode 100644 index 00000000000..7d1a18a264e --- /dev/null +++ b/vendor/github.com/maruel/natural/README.md @@ -0,0 +1,50 @@ +# natural + +Yet another natural sort, with 100% test coverage and a benchmark. It **does not +allocate memory**, doesn't depend on package `sort` and hence doesn't depend on +`reflect`. It is optimized for speed. + +[![Go +Reference](https://pkg.go.dev/badge/github.com/maruel/natural.svg)](https://pkg.go.dev/github.com/maruel/natural) +[![codecov](https://codecov.io/gh/maruel/natural/branch/main/graph/badge.svg?token=iQg8Y62BBg)](https://codecov.io/gh/maruel/natural) + + +## Benchmarks + +On Go 1.18.3. + +``` +$ go test -bench=. -cpu 1 +goos: linux +goarch: amd64 +pkg: github.com/maruel/natural +cpu: Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz +BenchmarkLessDigitsTwoGroupsNative 331287298 3.597 ns/op 0 B/op 0 allocs/op +BenchmarkLessDigitsTwoGroups 32479050 36.55 ns/op 0 B/op 0 allocs/op +BenchmarkLessStringOnly 157775884 7.603 ns/op 0 B/op 0 allocs/op +BenchmarkLessDigitsOnly 69210796 17.52 ns/op 0 B/op 0 allocs/op +BenchmarkLess10Blocks 6331066 190.8 ns/op 0 B/op 0 allocs/op +``` + +On a Raspberry Pi 3: + +``` +$ go test -bench=. -cpu 1 +goos: linux +goarch: arm +pkg: github.com/maruel/natural +BenchmarkLessDigitsTwoGroupsNative 14181789 86.57 ns/op 0 B/op 0 allocs/op +BenchmarkLessDigitsTwoGroups 1600195 748.9 ns/op 0 B/op 0 allocs/op +BenchmarkLessStringOnly 8286034 142.3 ns/op 0 B/op 0 allocs/op +BenchmarkLessDigitsOnly 3653055 331.4 ns/op 0 B/op 0 allocs/op +BenchmarkLess10Blocks 310687 3838 ns/op 0 B/op 0 allocs/op +``` + +Coverage: + +``` +$ go test -cover +PASS +coverage: 100.0% of statements +ok github.com/maruel/natural 0.012s +``` diff --git a/vendor/github.com/maruel/natural/natsort.go b/vendor/github.com/maruel/natural/natsort.go new file mode 100644 index 00000000000..df3ee0cbab8 --- /dev/null +++ b/vendor/github.com/maruel/natural/natsort.go @@ -0,0 +1,94 @@ +// Copyright 2018 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +// Package natural defines a natural "less" to compare two strings while +// interpreting natural numbers. +// +// This is occasionally nicknamed 'natsort'. +// +// It does so with no memory allocation. +package natural + +import ( + "strconv" +) + +// Less does a 'natural' comparison on the two strings. +// +// It treats digits as decimal numbers, so that Less("10", "2") return false. +// +// This function does no memory allocation. +func Less(a, b string) bool { + for { + if p := commonPrefix(a, b); p != 0 { + a = a[p:] + b = b[p:] + } + if len(a) == 0 { + return len(b) != 0 + } + if ia := digits(a); ia > 0 { + if ib := digits(b); ib > 0 { + // Both sides have digits. + an, aerr := strconv.ParseUint(a[:ia], 10, 64) + bn, berr := strconv.ParseUint(b[:ib], 10, 64) + if aerr == nil && berr == nil { + if an != bn { + return an < bn + } + // Semantically the same digits, e.g. "00" == "0", "01" == "1". In + // this case, only continue processing if there's trailing data on + // both sides, otherwise do lexical comparison. + if ia != len(a) && ib != len(b) { + a = a[ia:] + b = b[ib:] + continue + } + } + } + } + return a < b + } +} + +// StringSlice attaches the methods of Interface to []string, sorting in +// increasing order using natural order. +type StringSlice []string + +func (p StringSlice) Len() int { return len(p) } +func (p StringSlice) Less(i, j int) bool { return Less(p[i], p[j]) } +func (p StringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// + +// commonPrefix returns the common prefix except for digits. +func commonPrefix(a, b string) int { + m := len(a) + if n := len(b); n < m { + m = n + } + if m == 0 { + return 0 + } + _ = a[m-1] + _ = b[m-1] + for i := 0; i < m; i++ { + ca := a[i] + cb := b[i] + if (ca >= '0' && ca <= '9') || (cb >= '0' && cb <= '9') || ca != cb { + return i + } + } + return m +} + +func digits(s string) int { + for i := 0; i < len(s); i++ { + c := s[i] + if c < '0' || c > '9' { + return i + } + } + return len(s) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 2a27221923a..ac92693d7f9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -178,6 +178,9 @@ github.com/magefile/mage/sh github.com/manifoldco/promptui github.com/manifoldco/promptui/list github.com/manifoldco/promptui/screenbuf +# github.com/maruel/natural v1.1.1 +## explicit; go 1.21 +github.com/maruel/natural # github.com/mattn/go-colorable v0.1.13 ## explicit; go 1.15 # github.com/mattn/go-isatty v0.0.20