Улучшения обработки зависимостей и фильтрации установленных пакетов
- Добавлена поддержка версионных ограничений при установке пакетов - Улучшена логика фильтрации уже установленных пакетов - Добавлен метод GetInstalledVersion для всех менеджеров пакетов - Активированы тесты для систем archlinux, alpine, opensuse-leap - Улучшена обработка переменных в скриптах Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -171,7 +172,25 @@ func (s *ScriptFile) createPackageFromMeta(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metaDecoder := decoder.New(&distro.OSRelease{}, metaRunner)
|
||||
// DEBUG: Выводим что в metaRunner.Vars и dec.Runner.Vars для deps_debian
|
||||
if depsDebianMeta, ok := metaRunner.Vars["deps_debian"]; ok {
|
||||
slog.Info("DEBUG createPackageFromMeta: metaRunner.Vars[deps_debian]", "value", depsDebianMeta.String(), "list", depsDebianMeta.List)
|
||||
} else {
|
||||
slog.Info("DEBUG createPackageFromMeta: metaRunner.Vars[deps_debian] NOT FOUND")
|
||||
}
|
||||
if depsDebianParent, ok := dec.Runner.Vars["deps_debian"]; ok {
|
||||
slog.Info("DEBUG createPackageFromMeta: parent Vars[deps_debian]", "value", depsDebianParent.String(), "list", depsDebianParent.List)
|
||||
}
|
||||
|
||||
// Сливаем переменные родительского runner'а с переменными мета-функции.
|
||||
// Переменные мета-функции имеют приоритет (для случаев переопределения).
|
||||
for name, val := range dec.Runner.Vars {
|
||||
if _, exists := metaRunner.Vars[name]; !exists {
|
||||
metaRunner.Vars[name] = val
|
||||
}
|
||||
}
|
||||
|
||||
metaDecoder := decoder.New(dec.Info(), metaRunner)
|
||||
|
||||
var vars Package
|
||||
if err := metaDecoder.DecodeVars(&vars); err != nil {
|
||||
|
||||
137
pkg/depver/depver.go
Normal file
137
pkg/depver/depver.go
Normal file
@@ -0,0 +1,137 @@
|
||||
// ALR - Any Linux Repository
|
||||
// Copyright (C) 2025 The ALR Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package depver provides parsing and comparison of versioned dependencies
|
||||
// in PKGBUILD-style format (e.g., "gcc>=5.0", "openssl>=1.1.0").
|
||||
package depver
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gitea.plemya-x.ru/xpamych/vercmp"
|
||||
)
|
||||
|
||||
// Operator represents a version comparison operator.
|
||||
type Operator string
|
||||
|
||||
const (
|
||||
OpNone Operator = "" // No version constraint
|
||||
OpEq Operator = "=" // Equal to
|
||||
OpGt Operator = ">" // Greater than
|
||||
OpGe Operator = ">=" // Greater than or equal to
|
||||
OpLt Operator = "<" // Less than
|
||||
OpLe Operator = "<=" // Less than or equal to
|
||||
)
|
||||
|
||||
// Dependency represents a package dependency with optional version constraint.
|
||||
type Dependency struct {
|
||||
Name string // Package name (e.g., "gcc")
|
||||
Operator Operator // Comparison operator (e.g., OpGe for ">=")
|
||||
Version string // Version string (e.g., "5.0")
|
||||
}
|
||||
|
||||
// operators lists all supported operators in order of decreasing length
|
||||
// (to ensure ">=" is matched before ">").
|
||||
var operators = []Operator{OpGe, OpLe, OpGt, OpLt, OpEq}
|
||||
|
||||
// Parse parses a dependency string in PKGBUILD format.
|
||||
// Examples:
|
||||
// - "gcc>=5.0" -> Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"}
|
||||
// - "openssl" -> Dependency{Name: "openssl", Operator: OpNone, Version: ""}
|
||||
// - "cmake>=3.10" -> Dependency{Name: "cmake", Operator: OpGe, Version: "3.10"}
|
||||
func Parse(dep string) Dependency {
|
||||
dep = strings.TrimSpace(dep)
|
||||
if dep == "" {
|
||||
return Dependency{}
|
||||
}
|
||||
|
||||
// Try each operator (longer ones first)
|
||||
for _, op := range operators {
|
||||
if idx := strings.Index(dep, string(op)); idx > 0 {
|
||||
return Dependency{
|
||||
Name: strings.TrimSpace(dep[:idx]),
|
||||
Operator: op,
|
||||
Version: strings.TrimSpace(dep[idx+len(op):]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No operator found - just a package name
|
||||
return Dependency{
|
||||
Name: dep,
|
||||
Operator: OpNone,
|
||||
Version: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ParseMultiple parses multiple dependency strings.
|
||||
func ParseMultiple(deps []string) []Dependency {
|
||||
result := make([]Dependency, 0, len(deps))
|
||||
for _, dep := range deps {
|
||||
if dep != "" {
|
||||
result = append(result, Parse(dep))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// String returns the dependency in PKGBUILD format.
|
||||
func (d Dependency) String() string {
|
||||
if d.Operator == OpNone || d.Version == "" {
|
||||
return d.Name
|
||||
}
|
||||
return d.Name + string(d.Operator) + d.Version
|
||||
}
|
||||
|
||||
// Satisfies checks if the given version satisfies the dependency constraint.
|
||||
// Returns true if:
|
||||
// - The dependency has no version constraint (OpNone)
|
||||
// - The installed version satisfies the operator/version requirement
|
||||
func (d Dependency) Satisfies(installedVersion string) bool {
|
||||
if d.Operator == OpNone || d.Version == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
if installedVersion == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// vercmp.Compare returns:
|
||||
// -1 if installedVersion < d.Version
|
||||
// 0 if installedVersion == d.Version
|
||||
// 1 if installedVersion > d.Version
|
||||
cmp := vercmp.Compare(installedVersion, d.Version)
|
||||
|
||||
switch d.Operator {
|
||||
case OpEq:
|
||||
return cmp == 0
|
||||
case OpGt:
|
||||
return cmp > 0
|
||||
case OpGe:
|
||||
return cmp >= 0
|
||||
case OpLt:
|
||||
return cmp < 0
|
||||
case OpLe:
|
||||
return cmp <= 0
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// HasVersionConstraint returns true if the dependency has a version constraint.
|
||||
func (d Dependency) HasVersionConstraint() bool {
|
||||
return d.Operator != OpNone && d.Version != ""
|
||||
}
|
||||
347
pkg/depver/depver_test.go
Normal file
347
pkg/depver/depver_test.go
Normal file
@@ -0,0 +1,347 @@
|
||||
// ALR - Any Linux Repository
|
||||
// Copyright (C) 2025 The ALR Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package depver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected Dependency
|
||||
}{
|
||||
{
|
||||
name: "simple package name",
|
||||
input: "gcc",
|
||||
expected: Dependency{
|
||||
Name: "gcc",
|
||||
Operator: OpNone,
|
||||
Version: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "greater or equal",
|
||||
input: "gcc>=5.0",
|
||||
expected: Dependency{
|
||||
Name: "gcc",
|
||||
Operator: OpGe,
|
||||
Version: "5.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "less or equal",
|
||||
input: "openssl<=1.1.0",
|
||||
expected: Dependency{
|
||||
Name: "openssl",
|
||||
Operator: OpLe,
|
||||
Version: "1.1.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "greater than",
|
||||
input: "cmake>3.10",
|
||||
expected: Dependency{
|
||||
Name: "cmake",
|
||||
Operator: OpGt,
|
||||
Version: "3.10",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "less than",
|
||||
input: "python<4.0",
|
||||
expected: Dependency{
|
||||
Name: "python",
|
||||
Operator: OpLt,
|
||||
Version: "4.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "equal",
|
||||
input: "nodejs=18.0.0",
|
||||
expected: Dependency{
|
||||
Name: "nodejs",
|
||||
Operator: OpEq,
|
||||
Version: "18.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with spaces around",
|
||||
input: " gcc>=5.0 ",
|
||||
expected: Dependency{
|
||||
Name: "gcc",
|
||||
Operator: OpGe,
|
||||
Version: "5.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "complex version",
|
||||
input: "glibc>=2.17-326",
|
||||
expected: Dependency{
|
||||
Name: "glibc",
|
||||
Operator: OpGe,
|
||||
Version: "2.17-326",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty string",
|
||||
input: "",
|
||||
expected: Dependency{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := Parse(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMultiple(t *testing.T) {
|
||||
input := []string{"gcc>=5.0", "openssl", "cmake>=3.10", ""}
|
||||
expected := []Dependency{
|
||||
{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
{Name: "openssl", Operator: OpNone, Version: ""},
|
||||
{Name: "cmake", Operator: OpGe, Version: "3.10"},
|
||||
}
|
||||
|
||||
result := ParseMultiple(input)
|
||||
assert.Equal(t, expected, result)
|
||||
}
|
||||
|
||||
func TestDependency_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dep Dependency
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "no version",
|
||||
dep: Dependency{Name: "gcc", Operator: OpNone, Version: ""},
|
||||
expected: "gcc",
|
||||
},
|
||||
{
|
||||
name: "with version",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
expected: "gcc>=5.0",
|
||||
},
|
||||
{
|
||||
name: "equal operator",
|
||||
dep: Dependency{Name: "python", Operator: OpEq, Version: "3.11"},
|
||||
expected: "python=3.11",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := tt.dep.String()
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDependency_Satisfies(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dep Dependency
|
||||
installedVersion string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "no constraint - always satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpNone, Version: ""},
|
||||
installedVersion: "5.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "ge - satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
installedVersion: "5.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "ge - greater version satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
installedVersion: "6.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "ge - not satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
installedVersion: "4.9",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "gt - satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGt, Version: "5.0"},
|
||||
installedVersion: "5.1",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "gt - equal not satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGt, Version: "5.0"},
|
||||
installedVersion: "5.0",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "le - satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpLe, Version: "5.0"},
|
||||
installedVersion: "5.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "le - lesser satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpLe, Version: "5.0"},
|
||||
installedVersion: "4.9",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "le - not satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpLe, Version: "5.0"},
|
||||
installedVersion: "5.1",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "lt - satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpLt, Version: "5.0"},
|
||||
installedVersion: "4.9",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "lt - equal not satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpLt, Version: "5.0"},
|
||||
installedVersion: "5.0",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "eq - satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpEq, Version: "5.0"},
|
||||
installedVersion: "5.0",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "eq - not satisfied",
|
||||
dep: Dependency{Name: "gcc", Operator: OpEq, Version: "5.0"},
|
||||
installedVersion: "5.1",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "empty installed version",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
installedVersion: "",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := tt.dep.Satisfies(tt.installedVersion)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDependency_ForManager(t *testing.T) {
|
||||
dep := Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"}
|
||||
|
||||
tests := []struct {
|
||||
manager string
|
||||
expected string
|
||||
}{
|
||||
{"pacman", "gcc>=5.0"},
|
||||
{"apt", "gcc"},
|
||||
{"dnf", "gcc >= 5.0"},
|
||||
{"yum", "gcc >= 5.0"},
|
||||
{"apk", "gcc>=5.0"},
|
||||
{"zypper", "gcc >= 5.0"},
|
||||
{"apt-rpm", "gcc >= 5.0"},
|
||||
{"unknown", "gcc>=5.0"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.manager, func(t *testing.T) {
|
||||
result := dep.ForManager(tt.manager)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
|
||||
// Test without version constraint
|
||||
depNoVersion := Dependency{Name: "gcc", Operator: OpNone, Version: ""}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.manager+"_no_version", func(t *testing.T) {
|
||||
result := depNoVersion.ForManager(tt.manager)
|
||||
assert.Equal(t, "gcc", result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDependency_ForNfpm(t *testing.T) {
|
||||
dep := Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"}
|
||||
|
||||
tests := []struct {
|
||||
format string
|
||||
expected string
|
||||
}{
|
||||
{"deb", "gcc (>= 5.0)"},
|
||||
{"rpm", "gcc >= 5.0"},
|
||||
{"apk", "gcc>=5.0"},
|
||||
{"archlinux", "gcc>=5.0"},
|
||||
{"unknown", "gcc>=5.0"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.format, func(t *testing.T) {
|
||||
result := dep.ForNfpm(tt.format)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasVersionConstraint(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dep Dependency
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "has constraint",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: "5.0"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "no operator",
|
||||
dep: Dependency{Name: "gcc", Operator: OpNone, Version: ""},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "operator but no version",
|
||||
dep: Dependency{Name: "gcc", Operator: OpGe, Version: ""},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := tt.dep.HasVersionConstraint()
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
132
pkg/depver/format.go
Normal file
132
pkg/depver/format.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// ALR - Any Linux Repository
|
||||
// Copyright (C) 2025 The ALR Authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package depver
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ForManager formats the dependency for a specific package manager.
|
||||
// Different package managers have different syntax for version constraints:
|
||||
//
|
||||
// pacman (Arch): "gcc>=5.0" (no changes)
|
||||
// apt (Debian): "gcc" (version ignored for install command)
|
||||
// dnf/yum (Fedora): "gcc >= 5.0" (with spaces)
|
||||
// apk (Alpine): "gcc>=5.0" (no changes)
|
||||
// zypper (openSUSE): "gcc >= 5.0" (with spaces)
|
||||
// apt-rpm (ALT): "gcc >= 5.0" (with spaces)
|
||||
func (d Dependency) ForManager(managerName string) string {
|
||||
if d.Name == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// No version constraint - just return the name
|
||||
if d.Operator == OpNone || d.Version == "" {
|
||||
return d.Name
|
||||
}
|
||||
|
||||
switch managerName {
|
||||
case "apt":
|
||||
// APT doesn't support version constraints in 'apt install' command
|
||||
// Versions are checked after installation
|
||||
return d.Name
|
||||
|
||||
case "pacman":
|
||||
// Pacman uses PKGBUILD-style: package>=version (no spaces)
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "apk":
|
||||
// Alpine APK uses similar syntax to pacman
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "dnf", "yum":
|
||||
// DNF/YUM use RPM-style: "package >= version" (with spaces)
|
||||
return fmt.Sprintf("%s %s %s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "zypper":
|
||||
// Zypper uses RPM-style with spaces
|
||||
return fmt.Sprintf("%s %s %s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "apt-rpm":
|
||||
// ALT Linux apt-rpm uses RPM-style
|
||||
return fmt.Sprintf("%s %s %s", d.Name, d.Operator, d.Version)
|
||||
|
||||
default:
|
||||
// Default: PKGBUILD-style (no spaces)
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
}
|
||||
}
|
||||
|
||||
// ForManagerMultiple formats multiple dependencies for a specific package manager.
|
||||
func ForManagerMultiple(deps []Dependency, managerName string) []string {
|
||||
result := make([]string, 0, len(deps))
|
||||
for _, dep := range deps {
|
||||
if formatted := dep.ForManager(managerName); formatted != "" {
|
||||
result = append(result, formatted)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ForNfpm formats the dependency for nfpm package building.
|
||||
// Different package formats have different dependency syntax:
|
||||
//
|
||||
// deb: "package (>= version)"
|
||||
// rpm: "package >= version"
|
||||
// apk: "package>=version"
|
||||
// archlinux: "package>=version"
|
||||
func (d Dependency) ForNfpm(pkgFormat string) string {
|
||||
if d.Name == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// No version constraint - just return the name
|
||||
if d.Operator == OpNone || d.Version == "" {
|
||||
return d.Name
|
||||
}
|
||||
|
||||
switch pkgFormat {
|
||||
case "deb":
|
||||
// Debian uses: package (>= version)
|
||||
return fmt.Sprintf("%s (%s %s)", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "rpm":
|
||||
// RPM uses: package >= version
|
||||
return fmt.Sprintf("%s %s %s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "apk":
|
||||
// Alpine uses: package>=version
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
|
||||
case "archlinux":
|
||||
// Arch uses: package>=version
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
|
||||
default:
|
||||
// Default: no spaces
|
||||
return fmt.Sprintf("%s%s%s", d.Name, d.Operator, d.Version)
|
||||
}
|
||||
}
|
||||
|
||||
// ForNfpmMultiple formats multiple dependencies for nfpm.
|
||||
func ForNfpmMultiple(deps []Dependency, pkgFormat string) []string {
|
||||
result := make([]string, 0, len(deps))
|
||||
for _, dep := range deps {
|
||||
if formatted := dep.ForNfpm(pkgFormat); formatted != "" {
|
||||
result = append(result, formatted)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user