forked from Plemya-x/ALR
Compare commits
No commits in common. "chore/add-linters" and "master" have entirely different histories.
chore/add-
...
master
@ -1,26 +0,0 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
|
||||
linters-settings:
|
||||
goimports:
|
||||
local-prefixes: "plemya-x.ru/alr"
|
||||
gofmt:
|
||||
simplify: true
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gocritic
|
||||
- govet
|
||||
- staticcheck
|
||||
- unused
|
||||
- errcheck
|
||||
- typecheck
|
||||
# - forbidigo
|
||||
|
||||
issues:
|
||||
fix: true
|
6
Makefile
6
Makefile
@ -11,8 +11,6 @@ ZSH_COMPLETION := $(COMPLETIONS_DIR)/zsh
|
||||
INSTALLED_BASH_COMPLETION := $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$(NAME)
|
||||
INSTALLED_ZSH_COMPLETION := $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_$(NAME)
|
||||
|
||||
GOLANGCI_LINT := go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2
|
||||
|
||||
.PHONY: build install clean clear uninstall check-no-root
|
||||
|
||||
build: check-no-root $(BIN)
|
||||
@ -27,10 +25,6 @@ check-no-root:
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# TODO: remove --tests=false
|
||||
fmt:
|
||||
$(GOLANGCI_LINT) run --fix --tests=false
|
||||
|
||||
install: \
|
||||
$(INSTALED_BIN) \
|
||||
$(INSTALLED_BASH_COMPLETION) \
|
||||
|
1
build.go
1
build.go
@ -23,7 +23,6 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/osutils"
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
|
1
fix.go
1
fix.go
@ -22,7 +22,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
|
1
gen.go
1
gen.go
@ -4,7 +4,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"plemya-x.ru/alr/pkg/gen"
|
||||
)
|
||||
|
||||
|
@ -6,13 +6,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
|
||||
"plemya-x.ru/alr/internal/cpu"
|
||||
"plemya-x.ru/alr/internal/shutils/helpers"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
var helperCmd = &cli.Command{
|
||||
|
3
info.go
3
info.go
@ -23,14 +23,13 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"plemya-x.ru/alr/internal/cliutils"
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/overrides"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"plemya-x.ru/alr/pkg/repos"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var infoCmd = &cli.Command{
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/cliutils"
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/internal/pager"
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
)
|
||||
|
@ -24,9 +24,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -25,7 +25,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
)
|
||||
|
||||
|
@ -28,11 +28,10 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"golang.org/x/exp/slices"
|
||||
"modernc.org/sqlite"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"golang.org/x/exp/slices"
|
||||
"modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// CurrentVersion is the current version of the database.
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
|
||||
// Пакет dl содержит абстракции для загрузки файлов и каталогов
|
||||
// из различных источников.
|
||||
@ -39,7 +39,6 @@ import (
|
||||
"golang.org/x/crypto/blake2b"
|
||||
"golang.org/x/crypto/blake2s"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"plemya-x.ru/alr/internal/dlcache"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
)
|
||||
@ -300,6 +299,8 @@ func linkDir(src, dest string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
rel, err := filepath.Rel(src, path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -33,7 +33,6 @@ import (
|
||||
|
||||
"github.com/mholt/archiver/v4"
|
||||
"github.com/schollz/progressbar/v3"
|
||||
|
||||
"plemya-x.ru/alr/internal/shutils/handlers"
|
||||
)
|
||||
|
||||
|
@ -22,12 +22,11 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"plemya-x.ru/alr/internal/cpu"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type Opts struct {
|
||||
|
@ -25,13 +25,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"plemya-x.ru/alr/internal/overrides"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
"golang.org/x/exp/slices"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
|
||||
"plemya-x.ru/alr/internal/overrides"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
)
|
||||
|
||||
var ErrNotPointerToStruct = errors.New("val must be a pointer to a struct")
|
||||
|
@ -10,9 +10,9 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"plemya-x.ru/fakeroot"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"plemya-x.ru/fakeroot"
|
||||
)
|
||||
|
||||
// FakerootExecHandler was extracted from github.com/mvdan/sh/interp/handler.go
|
||||
|
@ -31,9 +31,8 @@ import (
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"golang.org/x/exp/slices"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
|
||||
"plemya-x.ru/alr/internal/shutils/handlers"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,10 +24,9 @@ import (
|
||||
"sync"
|
||||
|
||||
"go.elara.ws/logger"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"go.elara.ws/translate"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
)
|
||||
|
||||
//go:embed files
|
||||
|
3
list.go
3
list.go
@ -22,13 +22,12 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"plemya-x.ru/alr/pkg/manager"
|
||||
"plemya-x.ru/alr/pkg/repos"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var listCmd = &cli.Command{
|
||||
|
1
main.go
1
main.go
@ -28,7 +28,6 @@ import (
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.elara.ws/logger"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/internal/translations"
|
||||
|
@ -52,7 +52,6 @@ import (
|
||||
|
||||
"github.com/goreleaser/nfpm/v2"
|
||||
"github.com/goreleaser/nfpm/v2/files"
|
||||
|
||||
"plemya-x.ru/alr/internal/cliutils"
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/cpu"
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goreleaser/nfpm/v2"
|
||||
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
)
|
||||
|
@ -46,15 +46,15 @@ func InstallPkgs(ctx context.Context, alrPkgs []db.Package, nativePkgs []string,
|
||||
|
||||
if len(nativePkgs) > 0 {
|
||||
err := opts.Manager.Install(nil, nativePkgs...)
|
||||
// Если есть нативные пакеты, выполняем их установку
|
||||
// Если есть нативные пакеты, выполняем их установку
|
||||
if err != nil {
|
||||
log.Fatal("Error installing native packages").Err(err).Send()
|
||||
// Логируем и завершаем выполнение при ошибке
|
||||
// Логируем и завершаем выполнение при ошибке
|
||||
}
|
||||
}
|
||||
|
||||
InstallScripts(ctx, GetScriptPaths(ctx, alrPkgs), opts)
|
||||
// Устанавливаем скрипты сборки через функцию InstallScripts
|
||||
// Устанавливаем скрипты сборки через функцию InstallScripts
|
||||
}
|
||||
|
||||
// GetScriptPaths возвращает срез путей к скриптам, соответствующий
|
||||
@ -62,7 +62,7 @@ func InstallPkgs(ctx context.Context, alrPkgs []db.Package, nativePkgs []string,
|
||||
func GetScriptPaths(ctx context.Context, pkgs []db.Package) []string {
|
||||
var scripts []string
|
||||
for _, pkg := range pkgs {
|
||||
// Для каждого пакета создаем путь к скрипту сборки
|
||||
// Для каждого пакета создаем путь к скрипту сборки
|
||||
scriptPath := filepath.Join(config.GetPaths(ctx).RepoDir, pkg.Repository, pkg.Name, "alr.sh")
|
||||
scripts = append(scripts, scriptPath)
|
||||
}
|
||||
@ -75,17 +75,17 @@ func InstallScripts(ctx context.Context, scripts []string, opts types.BuildOpts)
|
||||
for _, script := range scripts {
|
||||
opts.Script = script // Устанавливаем текущий скрипт в опции
|
||||
builtPkgs, _, err := BuildPackage(ctx, opts)
|
||||
// Выполняем сборку пакета
|
||||
// Выполняем сборку пакета
|
||||
if err != nil {
|
||||
log.Fatal("Error building package").Err(err).Send()
|
||||
// Логируем и завершаем выполнение при ошибке сборки
|
||||
// Логируем и завершаем выполнение при ошибке сборки
|
||||
}
|
||||
|
||||
err = opts.Manager.InstallLocal(nil, builtPkgs...)
|
||||
// Устанавливаем локально собранные пакеты
|
||||
// Устанавливаем локально собранные пакеты
|
||||
if err != nil {
|
||||
log.Fatal("Error installing package").Err(err).Send()
|
||||
// Логируем и завершаем выполнение при ошибке установки
|
||||
// Логируем и завершаем выполнение при ошибке установки
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,10 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"plemya-x.ru/alr/internal/shutils/handlers"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
|
||||
"plemya-x.ru/alr/internal/shutils/handlers"
|
||||
)
|
||||
|
||||
// OSRelease contains information from an os-release file
|
||||
|
@ -1,20 +1,20 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"text/template"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// Определяем переменную funcs типа template.FuncMap, которая будет использоваться для
|
||||
// предоставления пользовательских функций в шаблонах
|
||||
var funcs = template.FuncMap{
|
||||
// Функция "tolower" использует strings.ToLower
|
||||
// для преобразования строки в нижний регистр
|
||||
"tolower": strings.ToLower,
|
||||
// Функция "tolower" использует strings.ToLower
|
||||
// для преобразования строки в нижний регистр
|
||||
"tolower": strings.ToLower,
|
||||
|
||||
// Функция "firstchar" — это лямбда-функция, которая берет строку
|
||||
// и возвращает её первый символ
|
||||
"firstchar": func(s string) string {
|
||||
return s[:1]
|
||||
},
|
||||
// Функция "firstchar" — это лямбда-функция, которая берет строку
|
||||
// и возвращает её первый символ
|
||||
"firstchar": func(s string) string {
|
||||
return s[:1]
|
||||
},
|
||||
}
|
||||
|
121
pkg/gen/pip.go
121
pkg/gen/pip.go
@ -1,99 +1,98 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
_ "embed" // Пакет для встраивания содержимого файлов в бинарники Go, использовав откладку //go:embed
|
||||
"encoding/json" // Пакет для работы с JSON: декодирование и кодирование
|
||||
"errors" // Пакет для создания и обработки ошибок
|
||||
"fmt" // Пакет для форматированного ввода и вывода
|
||||
"io" // Пакет для интерфейсов ввода и вывода
|
||||
"net/http" // Пакет для HTTP-клиентов и серверов
|
||||
"text/template" // Пакет для обработки текстовых шаблонов
|
||||
_ "embed" // Пакет для встраивания содержимого файлов в бинарники Go, использовав откладку //go:embed
|
||||
"encoding/json" // Пакет для работы с JSON: декодирование и кодирование
|
||||
"errors" // Пакет для создания и обработки ошибок
|
||||
"fmt" // Пакет для форматированного ввода и вывода
|
||||
"io" // Пакет для интерфейсов ввода и вывода
|
||||
"net/http" // Пакет для HTTP-клиентов и серверов
|
||||
"text/template" // Пакет для обработки текстовых шаблонов
|
||||
)
|
||||
|
||||
// Используем директиву //go:embed для встраивания содержимого файла шаблона в строку pipTmpl
|
||||
// Встраивание файла tmpls/pip.tmpl.sh
|
||||
//
|
||||
//go:embed tmpls/pip.tmpl.sh
|
||||
var pipTmpl string
|
||||
|
||||
// PipOptions содержит параметры, которые будут переданы в шаблон
|
||||
type PipOptions struct {
|
||||
Name string // Имя пакета
|
||||
Version string // Версия пакета
|
||||
Description string // Описание пакета
|
||||
Name string // Имя пакета
|
||||
Version string // Версия пакета
|
||||
Description string // Описание пакета
|
||||
}
|
||||
|
||||
// pypiAPIResponse представляет структуру ответа от API PyPI
|
||||
type pypiAPIResponse struct {
|
||||
Info pypiInfo `json:"info"` // Информация о пакете
|
||||
URLs []pypiURL `json:"urls"` // Список URL-адресов для загрузки пакета
|
||||
Info pypiInfo `json:"info"` // Информация о пакете
|
||||
URLs []pypiURL `json:"urls"` // Список URL-адресов для загрузки пакета
|
||||
}
|
||||
|
||||
// Метод SourceURL ищет и возвращает URL исходного distribution для пакета, если он существует
|
||||
func (res pypiAPIResponse) SourceURL() (pypiURL, error) {
|
||||
for _, url := range res.URLs {
|
||||
if url.PackageType == "sdist" {
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
return pypiURL{}, errors.New("package doesn't have a source distribution")
|
||||
for _, url := range res.URLs {
|
||||
if url.PackageType == "sdist" {
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
return pypiURL{}, errors.New("package doesn't have a source distribution")
|
||||
}
|
||||
|
||||
// pypiInfo содержит основную информацию о пакете, такую как имя, версия и пр.
|
||||
type pypiInfo struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Summary string `json:"summary"`
|
||||
Homepage string `json:"home_page"`
|
||||
License string `json:"license"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Summary string `json:"summary"`
|
||||
Homepage string `json:"home_page"`
|
||||
License string `json:"license"`
|
||||
}
|
||||
|
||||
// pypiURL представляет информацию об одном из доступных для загрузки URL
|
||||
type pypiURL struct {
|
||||
Digests map[string]string `json:"digests"` // Контрольные суммы для файлов
|
||||
Filename string `json:"filename"` // Имя файла
|
||||
PackageType string `json:"packagetype"` // Тип пакета (например sdist)
|
||||
Digests map[string]string `json:"digests"` // Контрольные суммы для файлов
|
||||
Filename string `json:"filename"` // Имя файла
|
||||
PackageType string `json:"packagetype"` // Тип пакета (например sdist)
|
||||
}
|
||||
|
||||
// Функция Pip загружает информацию о пакете из PyPI и использует шаблон для вывода информации
|
||||
func Pip(w io.Writer, opts PipOptions) error {
|
||||
// Создаем новый шаблон с добавлением функций из FuncMap
|
||||
tmpl, err := template.New("pip").
|
||||
Funcs(funcs).
|
||||
Parse(pipTmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Создаем новый шаблон с добавлением функций из FuncMap
|
||||
tmpl, err := template.New("pip").
|
||||
Funcs(funcs).
|
||||
Parse(pipTmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Формируем URL для запроса к PyPI на основании имени и версии пакета
|
||||
url := fmt.Sprintf(
|
||||
"https://pypi.org/pypi/%s/%s/json",
|
||||
opts.Name,
|
||||
opts.Version,
|
||||
)
|
||||
// Формируем URL для запроса к PyPI на основании имени и версии пакета
|
||||
url := fmt.Sprintf(
|
||||
"https://pypi.org/pypi/%s/%s/json",
|
||||
opts.Name,
|
||||
opts.Version,
|
||||
)
|
||||
|
||||
// Выполняем HTTP GET запрос к PyPI
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close() // Закрываем тело ответа после завершения работы
|
||||
if res.StatusCode != 200 {
|
||||
return fmt.Errorf("pypi: %s", res.Status)
|
||||
}
|
||||
// Выполняем HTTP GET запрос к PyPI
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close() // Закрываем тело ответа после завершения работы
|
||||
if res.StatusCode != 200 {
|
||||
return fmt.Errorf("pypi: %s", res.Status)
|
||||
}
|
||||
|
||||
// Раскодируем ответ JSON от PyPI в структуру pypiAPIResponse
|
||||
var resp pypiAPIResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Раскодируем ответ JSON от PyPI в структуру pypiAPIResponse
|
||||
var resp pypiAPIResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Если в opts указано описание, используем его вместо описания из PyPI
|
||||
if opts.Description != "" {
|
||||
resp.Info.Summary = opts.Description
|
||||
}
|
||||
// Если в opts указано описание, используем его вместо описания из PyPI
|
||||
if opts.Description != "" {
|
||||
resp.Info.Summary = opts.Description
|
||||
}
|
||||
|
||||
// Выполняем шаблон с использованием данных из resp и записываем результат в w
|
||||
return tmpl.Execute(w, resp)
|
||||
// Выполняем шаблон с использованием данных из resp и записываем результат в w
|
||||
return tmpl.Execute(w, resp)
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ func (a *APTRpm) UpgradeAll(opts *Opts) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (y *APTRpm) ListInstalled(opts *Opts) (map[string]string, error) {
|
||||
out := map[string]string{}
|
||||
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME}\u200b%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\n")
|
||||
|
@ -19,154 +19,154 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DNF представляет менеджер пакетов DNF
|
||||
type DNF struct {
|
||||
rootCmd string // rootCmd хранит команду, используемую для выполнения команд с правами root
|
||||
rootCmd string // rootCmd хранит команду, используемую для выполнения команд с правами root
|
||||
}
|
||||
|
||||
// Exists проверяет, доступен ли DNF в системе, возвращает true если да
|
||||
func (*DNF) Exists() bool {
|
||||
_, err := exec.LookPath("dnf")
|
||||
return err == nil
|
||||
_, err := exec.LookPath("dnf")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Name возвращает имя менеджера пакетов, в данном случае "dnf"
|
||||
func (*DNF) Name() string {
|
||||
return "dnf"
|
||||
return "dnf"
|
||||
}
|
||||
|
||||
// Format возвращает формат пакетов "rpm", используемый DNF
|
||||
func (*DNF) Format() string {
|
||||
return "rpm"
|
||||
return "rpm"
|
||||
}
|
||||
|
||||
// SetRootCmd устанавливает команду, используемую для выполнения операций с правами root
|
||||
func (d *DNF) SetRootCmd(s string) {
|
||||
d.rootCmd = s
|
||||
d.rootCmd = s
|
||||
}
|
||||
|
||||
// Sync выполняет upgrade всех установленных пакетов, обновляя их до более новых версий
|
||||
func (d *DNF) Sync(opts *Opts) error {
|
||||
opts = ensureOpts(opts) // Гарантирует, что opts не равен nil и содержит допустимые значения
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
setCmdEnv(cmd) // Устанавливает переменные окружения для команды
|
||||
err := cmd.Run() // Выполняет команду
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: sync: %w", err)
|
||||
}
|
||||
return nil
|
||||
opts = ensureOpts(opts) // Гарантирует, что opts не равен nil и содержит допустимые значения
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
setCmdEnv(cmd) // Устанавливает переменные окружения для команды
|
||||
err := cmd.Run() // Выполняет команду
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: sync: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Install устанавливает указанные пакеты с помощью DNF
|
||||
func (d *DNF) Install(opts *Opts, pkgs ...string) error {
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "install", "--allowerasing")
|
||||
cmd.Args = append(cmd.Args, pkgs...) // Добавляем названия пакетов к команде
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: install: %w", err)
|
||||
}
|
||||
return nil
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "install", "--allowerasing")
|
||||
cmd.Args = append(cmd.Args, pkgs...) // Добавляем названия пакетов к команде
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: install: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InstallLocal расширяет метод Install для установки пакетов, расположенных локально
|
||||
func (d *DNF) InstallLocal(opts *Opts, pkgs ...string) error {
|
||||
opts = ensureOpts(opts)
|
||||
return d.Install(opts, pkgs...)
|
||||
opts = ensureOpts(opts)
|
||||
return d.Install(opts, pkgs...)
|
||||
}
|
||||
|
||||
// Remove удаляет указанные пакеты с помощью DNF
|
||||
func (d *DNF) Remove(opts *Opts, pkgs ...string) error {
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "remove")
|
||||
cmd.Args = append(cmd.Args, pkgs...)
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: remove: %w", err)
|
||||
}
|
||||
return nil
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "remove")
|
||||
cmd.Args = append(cmd.Args, pkgs...)
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: remove: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upgrade обновляет указанные пакеты до более новых версий
|
||||
func (d *DNF) Upgrade(opts *Opts, pkgs ...string) error {
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
cmd.Args = append(cmd.Args, pkgs...)
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: upgrade: %w", err)
|
||||
}
|
||||
return nil
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
cmd.Args = append(cmd.Args, pkgs...)
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: upgrade: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpgradeAll обновляет все установленные пакеты
|
||||
func (d *DNF) UpgradeAll(opts *Opts) error {
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: upgradeall: %w", err)
|
||||
}
|
||||
return nil
|
||||
opts = ensureOpts(opts)
|
||||
cmd := d.getCmd(opts, "dnf", "upgrade")
|
||||
setCmdEnv(cmd)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dnf: upgradeall: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListInstalled возвращает список установленных пакетов и их версий
|
||||
func (d *DNF) ListInstalled(opts *Opts) (map[string]string, error) {
|
||||
out := map[string]string{}
|
||||
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME}\u200b%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\n")
|
||||
out := map[string]string{}
|
||||
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME}\u200b%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\n")
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
for scanner.Scan() {
|
||||
name, version, ok := strings.Cut(scanner.Text(), "\u200b")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
version = strings.TrimPrefix(version, "0:")
|
||||
out[name] = version
|
||||
}
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
for scanner.Scan() {
|
||||
name, version, ok := strings.Cut(scanner.Text(), "\u200b")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
version = strings.TrimPrefix(version, "0:")
|
||||
out[name] = version
|
||||
}
|
||||
|
||||
err = scanner.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = scanner.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// getCmd создает и возвращает команду exec.Cmd для менеджера пакетов DNF
|
||||
func (d *DNF) getCmd(opts *Opts, mgrCmd string, args ...string) *exec.Cmd {
|
||||
var cmd *exec.Cmd
|
||||
if opts.AsRoot {
|
||||
cmd = exec.Command(getRootCmd(d.rootCmd), mgrCmd)
|
||||
cmd.Args = append(cmd.Args, opts.Args...)
|
||||
cmd.Args = append(cmd.Args, args...)
|
||||
} else {
|
||||
cmd = exec.Command(mgrCmd, args...)
|
||||
}
|
||||
var cmd *exec.Cmd
|
||||
if opts.AsRoot {
|
||||
cmd = exec.Command(getRootCmd(d.rootCmd), mgrCmd)
|
||||
cmd.Args = append(cmd.Args, opts.Args...)
|
||||
cmd.Args = append(cmd.Args, args...)
|
||||
} else {
|
||||
cmd = exec.Command(mgrCmd, args...)
|
||||
}
|
||||
|
||||
if opts.NoConfirm {
|
||||
cmd.Args = append(cmd.Args, "-y") // Добавляет параметр автоматического подтверждения (-y)
|
||||
}
|
||||
if opts.NoConfirm {
|
||||
cmd.Args = append(cmd.Args, "-y") // Добавляет параметр автоматического подтверждения (-y)
|
||||
}
|
||||
|
||||
return cmd
|
||||
return cmd
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ import (
|
||||
"github.com/go-git/go-git/v5/plumbing/format/diff"
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"go.elara.ws/vercmp"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/internal/shutils/decoder"
|
||||
@ -46,6 +42,9 @@ import (
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
"plemya-x.ru/alr/pkg/distro"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
)
|
||||
|
||||
// Pull pulls the provided repositories. If a repo doesn't exist, it will be cloned
|
||||
|
3
repo.go
3
repo.go
@ -24,13 +24,12 @@ import (
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"plemya-x.ru/alr/pkg/repos"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var addrepoCmd = &cli.Command{
|
||||
|
@ -23,10 +23,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.elara.ws/vercmp"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"plemya-x.ru/alr/internal/config"
|
||||
"plemya-x.ru/alr/internal/db"
|
||||
"plemya-x.ru/alr/internal/types"
|
||||
@ -35,6 +31,9 @@ import (
|
||||
"plemya-x.ru/alr/pkg/loggerctx"
|
||||
"plemya-x.ru/alr/pkg/manager"
|
||||
"plemya-x.ru/alr/pkg/repos"
|
||||
"go.elara.ws/vercmp"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var upgradeCmd = &cli.Command{
|
||||
|
Loading…
Reference in New Issue
Block a user