@@ -1,19 +1,29 @@
 
		
	
		
			
				/*  
		
	
		
			
				 * ALR - Any Linux Repository  
		
	
		
			
				 * Любая Linux репозитория  
		
	
		
			
				 * Copyright (C) 2024 Евгений Храмов  
		
	
		
			
				 *  
		
	
		
			
				 * 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.  
		
	
		
			
				 * Это программное обеспечение свободно: вы можете распространять е г о   
		
	
		
			
				 * на условиях GNU General Public License, опубликованной Free Software Foundation,  
		
	
		
			
				 * либо версии 3 лицензии, либо (на ваш выбор) любой более поздней версии.  
		
	
		
			
				 *  
		
	
		
			
				 * 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.  
		
	
		
			
				 * Это программное обеспечение распространяется в надежде, что оно будет полезным,  
		
	
		
			
				 * но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемой гарантии  
		
	
		
			
				 * КОММЕРЧЕСКОЙ ПРИГОДНОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. См.  
		
	
		
			
				 * GNU General Public License для более подробной информации.  
		
	
		
			
				 *  
		
	
		
			
				 * You should have received a copy of the GNU General Public License  
		
	
		
			
				 * along with this program.  If not, see <http://www.gnu.org/licenses/>.  
		
	
		
			
				 * Вы должны были получить копию GNU General Public License  
		
	
		
			
				 * вместе с   
		
	
		
			
				 */  
		
	
		
			
				 
		
	
		
			
				package  build  
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -32,6 +42,7 @@ import (
 
		
	
		
			
					"strings" 
 
		
	
		
			
					"time" 
 
		
	
		
			
				 
		
	
		
			
				    // Импортируем пакеты для поддержки различных форматов пакетов (APK, DEB, RPM и ARCH). 
 
		
	
		
			
					_  "github.com/goreleaser/nfpm/v2/apk" 
 
		
	
		
			
					_  "github.com/goreleaser/nfpm/v2/arch" 
 
		
	
		
			
					_  "github.com/goreleaser/nfpm/v2/deb" 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -57,8 +68,8 @@ import (
 
		
	
		
			
					"mvdan.cc/sh/v3/syntax" 
 
		
	
		
			
				)  
		
	
		
			
				 
		
	
		
			
				// BuildPackage builds the script at the given path. It returns two slices. One contains the paths   
		
	
		
			
				// to the built package(s), the other contains the names of the built package(s) .  
		
	
		
			
				// Функция  BuildPackage выполняет сборку скрипта по указанному пути. Возвращает два среза.   
		
	
		
			
				// Один содержит пути к собранным пакетам, другой - имена собранных пакетов .  
		
	
		
			
				func  BuildPackage ( ctx  context . Context ,  opts  types . BuildOpts )  ( [ ] string ,  [ ] string ,  error )  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
				 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -72,9 +83,8 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// The first pass is just used to get variable values and runs before   
		
	
		
			
					// the script is displayed, so it's restricted so as to prevent malicious   
		
	
		
			
					// code from executing. 
 
		
	
		
			
				    // Первый проход предназначен для получения значений переменных и выполняется   
		
	
		
			
				    // до отображения скрипта, чтобы предотвратить выполнение вредоносного кода.   
		
	
		
			
					vars ,  err  :=  executeFirstPass ( ctx ,  info ,  fl ,  opts . Script ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -82,8 +92,8 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 
		
	
		
			
				 
		
	
		
			
					dirs  :=  getDirs ( ctx ,  vars ,  opts . Script ) 
 
		
	
		
			
				 
		
	
		
			
					// If opts.Clean isn't set and we find the package already built ,  
		
	
		
			
					// just return it rather than rebuilding   
		
	
		
			
				    // Если флаг opts.Clean не установлен, и пакет уже собран ,  
		
	
		
			
				    // возвращаем е г о а    
		
	
		
			
					if  ! opts . Clean  { 
 
		
	
		
			
						builtPkgPath ,  ok ,  err  :=  checkForBuiltPackage ( opts . Manager ,  vars ,  getPkgFormat ( opts . Manager ) ,  dirs . BaseDir ) 
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -95,7 +105,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 
		
	
		
			
						} 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// Ask the user if they'd like to see the build script   
		
	
		
			
				    // Спрашиваем у    
		
	
		
			
					err  =  cliutils . PromptViewScript ( ctx ,  opts . Script ,  vars . Name ,  config . Config ( ctx ) . PagerStyle ,  opts . Interactive ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						log . Fatal ( "Failed to prompt user to view build script" ) . Err ( err ) . Send ( ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -103,161 +113,161 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 
		
	
		
			
				 
		
	
		
			
					log . Info ( "Building package" ) . Str ( "name" ,  vars . Name ) . Str ( "version" ,  vars . Version ) . Send ( ) 
 
		
	
		
			
				 
		
	
		
			
					// The second pass will be used to execute the actual code ,  
		
	
		
			
					// so it's unrestricted. The script has already been displayed   
		
	
		
			
					// to the user by this point, so it should be safe   
		
	
		
			
				    // Второй проход будет использоваться для выполнения реального кода ,  
		
	
		
			
				    // поэтому он не ограничен. Скрипт уже был показан   
		
	
		
			
				    // пользователю к этому моменту, так что это должно быть безопасно.   
		
	
		
			
					dec ,  err  :=  executeSecondPass ( ctx ,  info ,  fl ,  dirs ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// Get the installed packages on the system  
 
		
	
		
			
					// Получаем список установленных пакетов в системе  
 
		
	
		
			
					installed ,  err  :=  opts . Manager . ListInstalled ( nil ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					cont ,  err  :=  performChecks ( ctx ,  vars ,  opts . Interactive ,  installed ) 
 
		
	
		
			
					cont ,  err  :=  performChecks ( ctx ,  vars ,  opts . Interactive ,  installed )  // Выполняем различные проверки  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					}  else  if  ! cont  { 
 
		
	
		
			
						os . Exit ( 1 ) 
 
		
	
		
			
						os . Exit ( 1 )  // Если проверки не пройдены, выходим из программы  
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// Prepare the directories for building   
		
	
		
			
				    // Подготавливаем директории для сборки   
		
	
		
			
					err  =  prepareDirs ( dirs ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					buildDeps ,  err  :=  installBuildDeps ( ctx ,  vars ,  opts ,  installed ) 
 
		
	
		
			
					buildDeps ,  err  :=  installBuildDeps ( ctx ,  vars ,  opts ,  installed )  // Устанавливаем зависимости для сборки  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					err  =  installOptDeps ( ctx ,  vars ,  opts ,  installed ) 
 
		
	
		
			
					err  =  installOptDeps ( ctx ,  vars ,  opts ,  installed )  // Устанавливаем опциональные зависимости  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					builtPaths ,  builtNames ,  repoDeps ,  err  :=  buildALRDeps ( ctx ,  opts ,  vars ) 
 
		
	
		
			
					builtPaths ,  builtNames ,  repoDeps ,  err  :=  buildALRDeps ( ctx ,  opts ,  vars )  // Собираем зависимости  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					log . Info ( "Downloading sources" ) . Send ( ) 
 
		
	
		
			
					log . Info ( "Downloading sources" ) . Send ( )  // Записываем в лог загрузку источников  
 
		
	
		
			
				 
		
	
		
			
					err  =  getSources ( ctx ,  dirs ,  vars ) 
 
		
	
		
			
					err  =  getSources ( ctx ,  dirs ,  vars )  // Загружаем исходники  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					err  =  executeFunctions ( ctx ,  dec ,  dirs ,  vars ) 
 
		
	
		
			
					err  =  executeFunctions ( ctx ,  dec ,  dirs ,  vars )  // Выполняем специальные функции  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					log . Info ( "Building package metadata" ) . Str ( "name" ,  vars . Name ) . Send ( ) 
 
		
	
		
			
					log . Info ( "Building package metadata" ) . Str ( "name" ,  vars . Name ) . Send ( )  // Логгируем сборку метаданных пакета  
 
		
	
		
			
				 
		
	
		
			
					pkgFormat  :=  getPkgFormat ( opts . Manager ) 
 
		
	
		
			
					pkgFormat  :=  getPkgFormat ( opts . Manager )  // Получаем формат пакета  
 
		
	
		
			
				 
		
	
		
			
					pkgInfo ,  err  :=  buildPkgMetadata ( vars ,  dirs ,  pkgFormat ,  append ( repoDeps ,  builtNames ... ) ) 
 
		
	
		
			
					pkgInfo ,  err  :=  buildPkgMetadata ( vars ,  dirs ,  pkgFormat ,  append ( repoDeps ,  builtNames ... ) )  // Собираем метаданные пакета  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					packager ,  err  :=  nfpm . Get ( pkgFormat ) 
 
		
	
		
			
					packager ,  err  :=  nfpm . Get ( pkgFormat )  // Получаем упаковщик для формата пакета  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					pkgName  :=  packager . ConventionalFileName ( pkgInfo ) 
 
		
	
		
			
					pkgPath  :=  filepath . Join ( dirs . BaseDir ,  pkgName ) 
 
		
	
		
			
					pkgName  :=  packager . ConventionalFileName ( pkgInfo )  // Получаем имя файла пакета  
 
		
	
		
			
					pkgPath  :=  filepath . Join ( dirs . BaseDir ,  pkgName )  // Определяем путь к пакету  
 
		
	
		
			
				 
		
	
		
			
					pkgFile ,  err  :=  os . Create ( pkgPath ) 
 
		
	
		
			
					pkgFile ,  err  :=  os . Create ( pkgPath )  // Создаём файл пакета  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					log . Info ( "Compressing package" ) . Str ( "name" ,  pkgName ) . Send ( ) 
 
		
	
		
			
					log . Info ( "Compressing package" ) . Str ( "name" ,  pkgName ) . Send ( )  // Логгируем сжатие пакета  
 
		
	
		
			
				 
		
	
		
			
					err  =  packager . Package ( pkgInfo ,  pkgFile ) 
 
		
	
		
			
					err  =  packager . Package ( pkgInfo ,  pkgFile )  // Упаковываем пакет  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					err  =  removeBuildDeps ( ctx ,  buildDeps ,  opts ) 
 
		
	
		
			
					err  =  removeBuildDeps ( ctx ,  buildDeps ,  opts )  // Удаляем зависимости для сборки  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// Add the path and name of the package we just built to the   
		
	
		
			
					// appropriate slices   
		
	
		
			
				    // Добавляем путь и имя только что собранного пакета в   
		
	
		
			
				    // соответствующие срезы   
		
	
		
			
					pkgPaths  :=  append ( builtPaths ,  pkgPath ) 
 
		
	
		
			
					pkgNames  :=  append ( builtNames ,  vars . Name ) 
 
		
	
		
			
				 
		
	
		
			
					// Remove any duplicates from the  pkgPaths and  pkgNames.  
		
	
		
			
					// Duplicates can be introduced if several of the dependencies   
		
	
		
			
					// depend on the same packages .  
		
	
		
			
				    // Удаляем дубликаты из  pkgPaths и  pkgNames.  
		
	
		
			
				    // Дубликаты могут появиться, если несколько зависимостей   
		
	
		
			
				    // зависят от одних и тех же пакетов .  
		
	
		
			
					pkgPaths  =  removeDuplicates ( pkgPaths ) 
 
		
	
		
			
					pkgNames  =  removeDuplicates ( pkgNames ) 
 
		
	
		
			
				 
		
	
		
			
					return  pkgPaths ,  pkgNames ,  nil 
 
		
	
		
			
					return  pkgPaths ,  pkgNames ,  nil  // Возвращаем пути и имена пакетов  
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// parseScript parses the build script using the built-in bash implementation   
		
	
		
			
				// Функция  parseScript анализирует скрипт сборки с    
		
	
		
			
				func  parseScript ( info  * distro . OSRelease ,  script  string )  ( * syntax . File ,  error )  {  
		
	
		
			
					fl ,  err  :=  os . Open ( script ) 
 
		
	
		
			
					fl ,  err  :=  os . Open ( script )  // Открываем файл скрипта  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
					defer  fl . Close ( ) 
 
		
	
		
			
					defer  fl . Close ( )  // Закрываем файл после выполнения  
 
		
	
		
			
				 
		
	
		
			
					file ,  err  :=  syntax . NewParser ( ) . Parse ( fl ,  "alr.sh" ) 
 
		
	
		
			
					file ,  err  :=  syntax . NewParser ( ) . Parse ( fl ,  "alr.sh" )  // Парсим скрипт с   
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					return  file ,  nil 
 
		
	
		
			
					return  file ,  nil  // Возвращаем синтаксическое дерево  
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// executeFirstPass executes the parsed script in a restricted environment   
		
	
		
			
				// to extract the build variables without executing any actual code .  
		
	
		
			
				// Функция  executeFirstPass выполняет парсированный скрипт в ограниченной среде,   
		
	
		
			
				// чтобы извлечь переменные сборки без выполнения реального кода .  
		
	
		
			
				func  executeFirstPass ( ctx  context . Context ,  info  * distro . OSRelease ,  fl  * syntax . File ,  script  string )  ( * types . BuildVars ,  error )  {  
		
	
		
			
					scriptDir  :=  filepath . Dir ( script ) 
 
		
	
		
			
					env  :=  createBuildEnvVars ( info ,  types . Directories { ScriptDir :  scriptDir } ) 
 
		
	
		
			
					scriptDir  :=  filepath . Dir ( script )  // Получаем директорию скрипта  
 
		
	
		
			
					env  :=  createBuildEnvVars ( info ,  types . Directories { ScriptDir :  scriptDir } )  // Создаём переменные окружения для сборки  
 
		
	
		
			
				 
		
	
		
			
					runner ,  err  :=  interp . New ( 
 
		
	
		
			
						interp . Env ( expand . ListEnviron ( env ... ) ) , 
 
		
	
		
			
						interp . StdIO ( os . Stdin ,  os . Stdout ,  os . Stderr ) , 
 
		
	
		
			
						interp . ExecHandler ( helpers . Restricted . ExecHandler ( handlers . NopExec ) ) , 
 
		
	
		
			
						interp . ReadDirHandler ( handlers . RestrictedReadDir ( scriptDir ) ) , 
 
		
	
		
			
						interp . StatHandler ( handlers . RestrictedStat ( scriptDir ) ) , 
 
		
	
		
			
						interp . OpenHandler ( handlers . RestrictedOpen ( scriptDir ) ) , 
 
		
	
		
			
						interp . Env ( expand . ListEnviron ( env ... ) ) ,  // Устанавливаем окружение  
 
		
	
		
			
						interp . StdIO ( os . Stdin ,  os . Stdout ,  os . Stderr ) ,  // Устанавливаем стандартный ввод-вывод  
 
		
	
		
			
						interp . ExecHandler ( helpers . Restricted . ExecHandler ( handlers . NopExec ) ) ,  // Ограничиваем выполнение  
 
		
	
		
			
						interp . ReadDirHandler ( handlers . RestrictedReadDir ( scriptDir ) ) ,  // Ограничиваем чтение директорий  
 
		
	
		
			
						interp . StatHandler ( handlers . RestrictedStat ( scriptDir ) ) ,  // Ограничиваем доступ к статистике файлов  
 
		
	
		
			
						interp . OpenHandler ( handlers . RestrictedOpen ( scriptDir ) ) ,  // Ограничиваем открытие файлов  
 
		
	
		
			
					) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					err  =  runner . Run ( ctx ,  fl ) 
 
		
	
		
			
					err  =  runner . Run ( ctx ,  fl )  // Запускаем скрипт  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					dec  :=  decoder . New ( info ,  runner ) 
 
		
	
		
			
					dec  :=  decoder . New ( info ,  runner )  // Создаём новый декодер  
 
		
	
		
			
				 
		
	
		
			
					var  vars  types . BuildVars 
 
		
	
		
			
					err  =  dec . DecodeVars ( & vars ) 
 
		
	
		
			
					err  =  dec . DecodeVars ( & vars )  // Декодируем переменные  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					return  & vars ,  nil 
 
		
	
		
			
					return  & vars ,  nil  // Возвращаем переменные сборки  
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// getDirs returns the appropriate directories for the script   
		
	
		
			
				// Функция getDirs возвращает соответствующие директории для скрипта   
		
	
		
			
				func  getDirs ( ctx  context . Context ,  vars  * types . BuildVars ,  script  string )  types . Directories  {  
		
	
		
			
					baseDir  :=  filepath . Join ( config . GetPaths ( ctx ) . PkgsDir ,  vars . Name ) 
 
		
	
		
			
					baseDir  :=  filepath . Join ( config . GetPaths ( ctx ) . PkgsDir ,  vars . Name )  // Определяем базовую директорию  
 
		
	
		
			
					return  types . Directories { 
 
		
	
		
			
						BaseDir :    baseDir , 
 
		
	
		
			
						SrcDir :     filepath . Join ( baseDir ,  "src" ) , 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -266,46 +276,46 @@ func getDirs(ctx context.Context, vars *types.BuildVars, script string) types.Di
 
		
	
		
			
					} 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// executeSecondPass executes the build script for the second time, this time without any restrictions.   
		
	
		
			
				// It returns a decoder that can be used to retrieve functions and variables from the script .  
		
	
		
			
				// Функция  executeSecondPass выполняет скрипт сборки второй раз без каких-либо ограничений. Возвращается декодер,   
		
	
		
			
				// который может быть использован для получения функций и переменных из скрипта .  
		
	
		
			
				func  executeSecondPass ( ctx  context . Context ,  info  * distro . OSRelease ,  fl  * syntax . File ,  dirs  types . Directories )  ( * decoder . Decoder ,  error )  {  
		
	
		
			
					env  :=  createBuildEnvVars ( info ,  dirs ) 
 
		
	
		
			
					env  :=  createBuildEnvVars ( info ,  dirs )  // Создаём переменные окружения для сборки  
 
		
	
		
			
				 
		
	
		
			
					fakeroot  :=  handlers . FakerootExecHandler ( 2  *  time . Second ) 
 
		
	
		
			
					fakeroot  :=  handlers . FakerootExecHandler ( 2  *  time . Second )  // Настраиваем "fakeroot" для выполнения  
 
		
	
		
			
					runner ,  err  :=  interp . New ( 
 
		
	
		
			
						interp . Env ( expand . ListEnviron ( env ... ) ) , 
 
		
	
		
			
						interp . StdIO ( os . Stdin ,  os . Stdout ,  os . Stderr ) , 
 
		
	
		
			
						interp . ExecHandler ( helpers . Helpers . ExecHandler ( fakeroot ) ) , 
 
		
	
		
			
						interp . Env ( expand . ListEnviron ( env ... ) ) ,  // Устанавливаем окружение  
 
		
	
		
			
						interp . StdIO ( os . Stdin ,  os . Stdout ,  os . Stderr ) ,  // Устанавливаем стандартный ввод-вывод  
 
		
	
		
			
						interp . ExecHandler ( helpers . Helpers . ExecHandler ( fakeroot ) ) ,  // Обрабатываем выполнение через fakeroot  
 
		
	
		
			
					) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					err  =  runner . Run ( ctx ,  fl ) 
 
		
	
		
			
					err  =  runner . Run ( ctx ,  fl )  // Запускаем скрипт  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  nil ,  err 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					return  decoder . New ( info ,  runner ) ,  nil 
 
		
	
		
			
					return  decoder . New ( info ,  runner ) ,  nil  // Возвращаем новый декодер  
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// prepareDirs prepares the directories for building .  
		
	
		
			
				// Функция  prepareDirs подготавливает директории для сборки .  
		
	
		
			
				func  prepareDirs ( dirs  types . Directories )  error  {  
		
	
		
			
					err  :=  os . RemoveAll ( dirs . BaseDir ) 
 
		
	
		
			
					err  :=  os . RemoveAll ( dirs . BaseDir )  // Удаляем базовую директорию, если она существует  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  err 
 
		
	
		
			
					} 
 
		
	
		
			
					err  =  os . MkdirAll ( dirs . SrcDir ,  0 o755 ) 
 
		
	
		
			
					err  =  os . MkdirAll ( dirs . SrcDir ,  0 o755 )  // Создаем директорию для источников  
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
		
			
						return  err 
 
		
	
		
			
					} 
 
		
	
		
			
					return  os . MkdirAll ( dirs . PkgDir ,  0 o755 ) 
 
		
	
		
			
					return  os . MkdirAll ( dirs . PkgDir ,  0 o755 )  // Создаем директорию для пакетов  
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// performChecks checks various things on the system to ensure that the package can be installed .  
		
	
		
			
				// Функция  performChecks проверяет различные аспекты в системе, чтобы убедиться, что пакет может быть установлен .  
		
	
		
			
				func  performChecks ( ctx  context . Context ,  vars  * types . BuildVars ,  interactive  bool ,  installed  map [ string ] string )  ( bool ,  error )  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
					if  ! cpu . IsCompatibleWith ( cpu . Arch ( ) ,  vars . Architectures )  { 
 
		
	
		
			
					if  ! cpu . IsCompatibleWith ( cpu . Arch ( ) ,  vars . Architectures )  {  // Проверяем совместимость архитектуры  
 
		
	
		
			
						cont ,  err  :=  cliutils . YesNoPrompt ( ctx ,  "Your system's CPU architecture doesn't match this package. Do you want to build anyway?" ,  interactive ,  true ) 
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
		
			
							return  false ,  err 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -316,7 +326,7 @@ func performChecks(ctx context.Context, vars *types.BuildVars, interactive bool,
 
		
	
		
			
						} 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					if  instVer ,  ok  :=  installed [ vars . Name ] ;  ok  { 
 
		
	
		
			
					if  instVer ,  ok  :=  installed [ vars . Name ] ;  ok  {  // Если пакет уже установлен, выводим предупреждение  
 
		
	
		
			
						log . Warn ( "This package is already installed" ) . 
 
		
	
		
			
							Str ( "name" ,  vars . Name ) . 
 
		
	
		
			
							Str ( "version" ,  instVer ) . 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -326,33 +336,33 @@ func performChecks(ctx context.Context, vars *types.BuildVars, interactive bool,
 
		
	
		
			
					return  true ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// installBuildDeps installs any build dependencies that aren't already installed and returns   
		
	
		
			
				// a slice containing the names of all the packages it installed .  
		
	
		
			
				// Функция  installBuildDeps устанавливает все зависимости сборки, которые еще не установлены, и возвращает   
		
	
		
			
				// срез, содержащий имена всех установленных пакетов .  
		
	
		
			
				func  installBuildDeps ( ctx  context . Context ,  vars  * types . BuildVars ,  opts  types . BuildOpts ,  installed  map [ string ] string )  ( [ ] string ,  error )  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
					var  buildDeps  [ ] string 
 
		
	
		
			
					if  len ( vars . BuildDepends )  >  0  { 
 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  vars . BuildDepends ) 
 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  vars . BuildDepends )  // Находим пакеты-зависимости  
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
		
			
							return  nil ,  err 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
						found  =  removeAlreadyInstalled ( found ,  installed ) 
 
		
	
		
			
						found  =  removeAlreadyInstalled ( found ,  installed )  // Убираем уже установленные зависимости  
 
		
	
		
			
				 
		
	
		
			
						log . Info ( "Installing build dependencies" ) . Send ( ) 
 
		
	
		
			
						log . Info ( "Installing build dependencies" ) . Send ( )  // Логгируем установку зависимостей  
 
		
	
		
			
				 
		
	
		
			
						flattened  :=  cliutils . FlattenPkgs ( ctx ,  found ,  "install" ,  opts . Interactive ) 
 
		
	
		
			
						flattened  :=  cliutils . FlattenPkgs ( ctx ,  found ,  "install" ,  opts . Interactive )  // Уплощаем список зависимостей  
 
		
	
		
			
						buildDeps  =  packageNames ( flattened ) 
 
		
	
		
			
						InstallPkgs ( ctx ,  flattened ,  notFound ,  opts ) 
 
		
	
		
			
						InstallPkgs ( ctx ,  flattened ,  notFound ,  opts )  // Устанавливаем пакеты  
 
		
	
		
			
					} 
 
		
	
		
			
					return  buildDeps ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// installOptDeps asks the user which, if any, optional dependencies they want to install .  
		
	
		
			
				// If the user chooses to install any optional dependencies, it performs the installation .  
		
	
		
			
				// Функция  installOptDeps спрашивает у  .  
		
	
		
			
				// Если пользователь решает установить какие-либо опциональные зависимости, выполняется их установка .  
		
	
		
			
				func  installOptDeps ( ctx  context . Context ,  vars  * types . BuildVars ,  opts  types . BuildOpts ,  installed  map [ string ] string )  error  {  
		
	
		
			
					if  len ( vars . OptDepends )  >  0  { 
 
		
	
		
			
						optDeps ,  err  :=  cliutils . ChooseOptDepends ( ctx ,  vars . OptDepends ,  "install" ,  opts . Interactive ) 
 
		
	
		
			
						optDeps ,  err  :=  cliutils . ChooseOptDepends ( ctx ,  vars . OptDepends ,  "install" ,  opts . Interactive )  // Пользователя просят выбрать опциональные зависимости  
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
		
			
							return  err 
 
		
	
		
			
						} 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -361,63 +371,63 @@ func installOptDeps(ctx context.Context, vars *types.BuildVars, opts types.Build
 
		
	
		
			
							return  nil 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  optDeps ) 
 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  optDeps )  // Находим опциональные зависимости  
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
		
			
							return  err 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
						found  =  removeAlreadyInstalled ( found ,  installed ) 
 
		
	
		
			
						found  =  removeAlreadyInstalled ( found ,  installed )  // Убираем уже установленные зависимости  
 
		
	
		
			
						flattened  :=  cliutils . FlattenPkgs ( ctx ,  found ,  "install" ,  opts . Interactive ) 
 
		
	
		
			
						InstallPkgs ( ctx ,  flattened ,  notFound ,  opts ) 
 
		
	
		
			
						InstallPkgs ( ctx ,  flattened ,  notFound ,  opts )  // Устанавливаем выбранные пакеты  
 
		
	
		
			
					} 
 
		
	
		
			
					return  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// buildALRDeps builds all the ALR dependencies of the package. It returns the paths and names   
		
	
		
			
				// of the packages it built, as well as all the dependencies it didn't find in the ALR repo so   
		
	
		
			
				// they can be installed from the system repos .  
		
	
		
			
				// Функция  buildALRDeps собирает все ALR зависимости пакета. Возвращает пути и имена   
		
	
		
			
				// пакетов, которые она собрала, а    
		
	
		
			
				// чтобы они могли быть установлены из системных репозиториев .  
		
	
		
			
				func  buildALRDeps ( ctx  context . Context ,  opts  types . BuildOpts ,  vars  * types . BuildVars )  ( builtPaths ,  builtNames ,  repoDeps  [ ] string ,  err  error )  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
					if  len ( vars . Depends )  >  0  { 
 
		
	
		
			
						log . Info ( "Installing dependencies" ) . Send ( ) 
 
		
	
		
			
				 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  vars . Depends ) 
 
		
	
		
			
						found ,  notFound ,  err  :=  repos . FindPkgs ( ctx ,  vars . Depends )  // Поиск зависимостей  
 
		
	
		
			
						if  err  !=  nil  { 
 
		
	
		
			
							return  nil ,  nil ,  nil ,  err 
 
		
	
		
			
						} 
 
		
	
		
			
						repoDeps  =  notFound 
 
		
	
		
			
				 
		
	
		
			
						// If there are multiple options for some packages, flatten them all into a single slice   
		
	
		
			
				        // Если для некоторых пакетов есть несколько опций, упрощаем их все в один срез   
		
	
		
			
						pkgs  :=  cliutils . FlattenPkgs ( ctx ,  found ,  "install" ,  opts . Interactive ) 
 
		
	
		
			
						scripts  :=  GetScriptPaths ( ctx ,  pkgs ) 
 
		
	
		
			
						for  _ ,  script  :=  range  scripts  { 
 
		
	
		
			
							newOpts  :=  opts 
 
		
	
		
			
							newOpts . Script  =  script 
 
		
	
		
			
				 
		
	
		
			
							// Build the dependency   
		
	
		
			
				            // Собираем зависимости   
		
	
		
			
							pkgPaths ,  pkgNames ,  err  :=  BuildPackage ( ctx ,  newOpts ) 
 
		
	
		
			
							if  err  !=  nil  { 
 
		
	
		
			
								return  nil ,  nil ,  nil ,  err 
 
		
	
		
			
							} 
 
		
	
		
			
				 
		
	
		
			
							// Append the paths of all the built packages to  builtPaths  
		
	
		
			
				            // Добавляем пути всех собранных пакетов в  builtPaths  
		
	
		
			
							builtPaths  =  append ( builtPaths ,  pkgPaths ... ) 
 
		
	
		
			
							// Append the names of all the built packages to builtName s  
		
	
		
			
				            // Добавляем пути всех собранных пакетов в builtPath s  
		
	
		
			
							builtNames  =  append ( builtNames ,  pkgNames ... ) 
 
		
	
		
			
							// Append the name of the current package to  builtNames  
		
	
		
			
				            // Добавляем имя текущего пакета в  builtNames  
		
	
		
			
							builtNames  =  append ( builtNames ,  filepath . Base ( filepath . Dir ( script ) ) ) 
 
		
	
		
			
						} 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					// Remove any potential duplicates, which can be introduced if   
		
	
		
			
					// several of the dependencies depend on the same packages .  
		
	
		
			
				    // Удаляем возможные дубликаты, которые могут быть введены, если   
		
	
		
			
				    // несколько зависимостей зависят от одних и тех же пакетов .  
		
	
		
			
					repoDeps  =  removeDuplicates ( repoDeps ) 
 
		
	
		
			
					builtPaths  =  removeDuplicates ( builtPaths ) 
 
		
	
		
			
					builtNames  =  removeDuplicates ( builtNames ) 
 
		
	
		
			
					return  builtPaths ,  builtNames ,  repoDeps ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// executeFunctions executes the special ALR functions, such as  version(), prepare(), etc .  
		
	
		
			
				// Функция  executeFunctions выполняет специальные функции ALR, такие как  version(), prepare() и т.д .  
		
	
		
			
				func  executeFunctions ( ctx  context . Context ,  dec  * decoder . Decoder ,  dirs  types . Directories ,  vars  * types . BuildVars )  ( err  error )  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
					version ,  ok  :=  dec . GetFunc ( "version" ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -465,22 +475,34 @@ func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Dire
 
		
	
		
			
						} 
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
				    // Выполнение всех функций, начинающихся с  
 
		
	
		
			
				    for  { 
 
		
	
		
			
				        packageFn ,  ok  :=  dec . GetFunc ( "package" ) 
 
		
	
		
			
				        if  ok  { 
 
		
	
		
			
				            log . Info ( "Executing package()" ) . Send ( ) 
 
		
	
		
			
				 
		
	
		
			
				            err  =  packageFn ( ctx ,  interp . Dir ( dirs . SrcDir ) ) 
 
		
	
		
			
				            if  err  !=  nil  { 
 
		
	
		
			
				                return  err 
 
		
	
		
			
				            } 
 
		
	
		
			
				        } 
 
		
	
		
			
				 
		
	
		
			
				        // Проверка на наличие дополнительных функций package_* 
 
		
	
		
			
				        packageFuncName  :=  "package_" 
 
		
	
		
			
				        if  packageFunc ,  ok  :=  dec . GetFunc ( packageFuncName ) ;  ok  { 
 
		
	
		
			
				            log . Info ( "Executing "  +  packageFuncName ) . Send ( ) 
 
		
	
		
			
				            err  =  packageFunc ( ctx ,  interp . Dir ( dirs . SrcDir ) ) 
 
		
	
		
			
				            if  err  !=  nil  { 
 
		
	
		
			
				                return  err 
 
		
	
		
			
				            } 
 
		
	
		
			
				        }  else  { 
 
		
	
		
			
						log . Fatal ( "The package() function is required" ) . Send ( )   
		
	
		
			
				            break  // Если больше нет функций package_*, выходим из цикла   
		
	
		
			
				        } 
 
		
	
		
			
				    } 
 
		
	
		
			
				 
		
	
		
			
					return  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// buildPkgMetadata builds the metadata for the package that's going to be built .  
		
	
		
			
				// Функция  buildPkgMetadata создает метаданные для пакета, который будет собран .  
		
	
		
			
				func  buildPkgMetadata ( vars  * types . BuildVars ,  dirs  types . Directories ,  pkgFormat  string ,  deps  [ ] string )  ( * nfpm . Info ,  error )  {  
		
	
		
			
					pkgInfo  :=  & nfpm . Info { 
 
		
	
		
			
						Name :         vars . Name , 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -501,7 +523,7 @@ func buildPkgMetadata(vars *types.BuildVars, dirs types.Directories, pkgFormat s
 
		
	
		
			
					} 
 
		
	
		
			
				 
		
	
		
			
					if  pkgFormat  ==  "apk"  { 
 
		
	
		
			
						 // Alpine refuses to install packages that provide themselves, so remove any such provides   
		
	
		
			
				         // Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы   
		
	
		
			
						pkgInfo . Overridables . Provides  =  slices . DeleteFunc ( pkgInfo . Overridables . Provides ,  func ( s  string )  bool  { 
 
		
	
		
			
							return  s  ==  pkgInfo . Name 
 
		
	
		
			
						} ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -526,8 +548,8 @@ func buildPkgMetadata(vars *types.BuildVars, dirs types.Directories, pkgFormat s
 
		
	
		
			
					return  pkgInfo ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// buildContents builds the contents section of the package, which contains the files   
		
	
		
			
				// that will be placed into the final package .  
		
	
		
			
				// Функция buildContents создает секцию содержимого пакета, которая содержит файлы,   
		
	
		
			
				// которые будут включены в конечный пакет .  
		
	
		
			
				func  buildContents ( vars  * types . BuildVars ,  dirs  types . Directories )  ( [ ] * files . Content ,  error )  {  
		
	
		
			
					contents  :=  [ ] * files . Content { } 
 
		
	
		
			
					err  :=  filepath . Walk ( dirs . PkgDir ,  func ( path  string ,  fi  os . FileInfo ,  err  error )  error  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -539,7 +561,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 
		
	
		
			
								return  err 
 
		
	
		
			
							} 
 
		
	
		
			
				 
		
	
		
			
							// If the directory is empty, skip it   
		
	
		
			
				            // Если директория пустая, пропускаем её   
		
	
		
			
							_ ,  err  =  f . Readdirnames ( 1 ) 
 
		
	
		
			
							if  err  !=  io . EOF  { 
 
		
	
		
			
								return  nil 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -556,13 +578,13 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 
		
	
		
			
				 
		
	
		
			
							return  f . Close ( ) 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
				        // Если файл является символической ссылкой, прорабатываем это 
 
		
	
		
			
						if  fi . Mode ( ) & os . ModeSymlink  !=  0  { 
 
		
	
		
			
							link ,  err  :=  os . Readlink ( path ) 
 
		
	
		
			
							if  err  !=  nil  { 
 
		
	
		
			
								return  err 
 
		
	
		
			
							} 
 
		
	
		
			
							// Remove pkgdir from the symlink's path   
		
	
		
			
				            // Удаляем pkgdir из пути символической ссылки   
		
	
		
			
							link  =  strings . TrimPrefix ( link ,  dirs . PkgDir ) 
 
		
	
		
			
				 
		
	
		
			
							contents  =  append ( contents ,  & files . Content { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -577,7 +599,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 
		
	
		
			
				 
		
	
		
			
							return  nil 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
				        // Обрабатываем обычные файлы 
 
		
	
		
			
						fileContent  :=  & files . Content { 
 
		
	
		
			
							Source :       path , 
 
		
	
		
			
							Destination :  trimmed , 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -588,7 +610,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 
		
	
		
			
							} , 
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
						// If the file is supposed to be backed up, set its type to  config|noreplace  
		
	
		
			
				        // Если файл должен быть сохранен, установите е г о   config|noreplace  
		
	
		
			
						if  slices . Contains ( vars . Backup ,  trimmed )  { 
 
		
	
		
			
							fileContent . Type  =  "config|noreplace" 
 
		
	
		
			
						} 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -600,8 +622,8 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 
		
	
		
			
					return  contents ,  err 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// removeBuildDeps asks the user if they'd like to remove the build dependencies that were   
		
	
		
			
				// installed by installBuildDeps. If so, it uses the package manager to do that .  
		
	
		
			
				// Функция  removeBuildDeps спрашивает у    
		
	
		
			
				// установленные для сборки. Если да, использует менеджер пакетов для их удаления .  
		
	
		
			
				func  removeBuildDeps ( ctx  context . Context ,  buildDeps  [ ] string ,  opts  types . BuildOpts )  error  {  
		
	
		
			
					if  len ( buildDeps )  >  0  { 
 
		
	
		
			
						remove ,  err  :=  cliutils . YesNoPrompt ( ctx ,  "Would you like to remove the build dependencies?" ,  opts . Interactive ,  false ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -625,8 +647,8 @@ func removeBuildDeps(ctx context.Context, buildDeps []string, opts types.BuildOp
 
		
	
		
			
					return  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// checkForBuiltPackage tries to detect a previously-built package and returns its path   
		
	
		
			
				// and  true if it finds one. If it doesn't find it, it returns  "", false, nil.  
		
	
		
			
				// Функция  checkForBuiltPackage пытается обнаружить ранее собранный пакет и вернуть е г о    
		
	
		
			
				// и  true, если нашла. Если нет, возвратит  "", false, nil.  
		
	
		
			
				func  checkForBuiltPackage ( mgr  manager . Manager ,  vars  * types . BuildVars ,  pkgFormat ,  baseDir  string )  ( string ,  bool ,  error )  {  
		
	
		
			
					filename ,  err  :=  pkgFileName ( vars ,  pkgFormat ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -643,8 +665,8 @@ func checkForBuiltPackage(mgr manager.Manager, vars *types.BuildVars, pkgFormat,
 
		
	
		
			
					return  pkgPath ,  true ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// pkgFileName returns the filename of the package if it were to be built .  
		
	
		
			
				// This is used to check if the package has already been built .  
		
	
		
			
				// Функция  pkgFileName возвращает имя файла пакета, если оно было бы создано .  
		
	
		
			
				// Это используется для проверки, был ли пакет уже собран .  
		
	
		
			
				func  pkgFileName ( vars  * types . BuildVars ,  pkgFormat  string )  ( string ,  error )  {  
		
	
		
			
					pkgInfo  :=  & nfpm . Info { 
 
		
	
		
			
						Name :     vars . Name , 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -662,8 +684,8 @@ func pkgFileName(vars *types.BuildVars, pkgFormat string) (string, error) {
 
		
	
		
			
					return  packager . ConventionalFileName ( pkgInfo ) ,  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// getPkgFormat returns the package format of the package manager ,  
		
	
		
			
				// or  ALR_PKG_FORMAT if that's set .  
		
	
		
			
				// Функция  getPkgFormat возвращает формат пакета из менеджера пакетов ,  
		
	
		
			
				// или  ALR_PKG_FORMAT, если он установлен .  
		
	
		
			
				func  getPkgFormat ( mgr  manager . Manager )  string  {  
		
	
		
			
					pkgFormat  :=  mgr . Format ( ) 
 
		
	
		
			
					if  format ,  ok  :=  os . LookupEnv ( "ALR_PKG_FORMAT" ) ;  ok  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -672,8 +694,8 @@ func getPkgFormat(mgr manager.Manager) string {
 
		
	
		
			
					return  pkgFormat 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// createBuildEnvVars creates the environment variables that will be set in the   
		
	
		
			
				// build script when it's executed .  
		
	
		
			
				// Функция  createBuildEnvVars создает переменные окружения, которые будут установлены   
		
	
		
			
				// в скрипте сборки при е г о  .  
		
	
		
			
				func  createBuildEnvVars ( info  * distro . OSRelease ,  dirs  types . Directories )  [ ] string  {  
		
	
		
			
					env  :=  os . Environ ( ) 
 
		
	
		
			
				 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -703,7 +725,7 @@ func createBuildEnvVars(info *distro.OSRelease, dirs types.Directories) []string
 
		
	
		
			
					return  env 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// getSources downloads the sources from the script .  
		
	
		
			
				// Функция  getSources загружает исходники скрипта .  
		
	
		
			
				func  getSources ( ctx  context . Context ,  dirs  types . Directories ,  bv  * types . BuildVars )  error  {  
		
	
		
			
					log  :=  loggerctx . From ( ctx ) 
 
		
	
		
			
					if  len ( bv . Sources )  !=  len ( bv . Checksums )  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -720,9 +742,9 @@ func getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars
 
		
	
		
			
						} 
 
		
	
		
			
				 
		
	
		
			
						if  ! strings . EqualFold ( bv . Checksums [ i ] ,  "SKIP" )  { 
 
		
	
		
			
							// If the checksum contains a colon, use the part before the colon   
		
	
		
			
							// as the algorithm and the part after as the actual checksum .  
		
	
		
			
							// Otherwise, use the default sha256 with the whole string as the checksum .  
		
	
		
			
				            // Если контрольная сумма содержит двоеточие, используйте часть до двоеточия   
		
	
		
			
				            // как алгоритм, а  .  
		
	
		
			
				            // В с  .  
		
	
		
			
							algo ,  hashData ,  ok  :=  strings . Cut ( bv . Checksums [ i ] ,  ":" ) 
 
		
	
		
			
							if  ok  { 
 
		
	
		
			
								checksum ,  err  :=  hex . DecodeString ( hashData ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -749,7 +771,7 @@ func getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars
 
		
	
		
			
					return  nil 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// setScripts adds any hook scripts to the package metadata .  
		
	
		
			
				// Функция  setScripts добавляет скрипты-перехватчики к метаданным пакета .  
		
	
		
			
				func  setScripts ( vars  * types . BuildVars ,  info  * nfpm . Info ,  scriptDir  string )  {  
		
	
		
			
					if  vars . Scripts . PreInstall  !=  ""  { 
 
		
	
		
			
						info . Scripts . PreInstall  =  filepath . Join ( scriptDir ,  vars . Scripts . PreInstall ) 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -786,8 +808,8 @@ func setScripts(vars *types.BuildVars, info *nfpm.Info, scriptDir string) {
 
		
	
		
			
					} 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// setVersion changes the version variable in the script  runner.  
		
	
		
			
				// It's used to set the version to the output of the  version() function .  
		
	
		
			
				// Функция  setVersion изменяет переменную версии в скрипте  runner.  
		
	
		
			
				// Она используется для установки версии на вывод функции  version().  
		
	
		
			
				func  setVersion ( ctx  context . Context ,  r  * interp . Runner ,  to  string )  error  {  
		
	
		
			
					fl ,  err  :=  syntax . NewParser ( ) . Parse ( strings . NewReader ( "version='" + to + "'" ) ,  "" ) 
 
		
	
		
			
					if  err  !=  nil  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -796,7 +818,7 @@ func setVersion(ctx context.Context, r *interp.Runner, to string) error {
 
		
	
		
			
					return  r . Run ( ctx ,  fl ) 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// removeAlreadyInstalled returns a map without any dependencies that are already installed   
		
	
		
			
				// Функция  removeAlreadyInstalled возвращает карту без каких-либо зависимостей, которые уже установлены.   
		
	
		
			
				func  removeAlreadyInstalled ( found  map [ string ] [ ] db . Package ,  installed  map [ string ] string )  map [ string ] [ ] db . Package  {  
		
	
		
			
					filteredPackages  :=  make ( map [ string ] [ ] db . Package ) 
 
		
	
		
			
				 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -813,7 +835,7 @@ func removeAlreadyInstalled(found map[string][]db.Package, installed map[string]
 
		
	
		
			
					return  filteredPackages 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// packageNames returns the names of all the given packages   
		
	
		
			
				// Функция  packageNames возвращает имена всех предоставленных пакетов.   
		
	
		
			
				func  packageNames ( pkgs  [ ] db . Package )  [ ] string  {  
		
	
		
			
					names  :=  make ( [ ] string ,  len ( pkgs ) ) 
 
		
	
		
			
					for  i ,  p  :=  range  pkgs  { 
 
		
	
	
		
			
				
					
					
						
					 
				
			
			@@ -822,7 +844,7 @@ func packageNames(pkgs []db.Package) []string {
 
		
	
		
			
					return  names 
 
		
	
		
			
				}  
		
	
		
			
				 
		
	
		
			
				// removeDuplicates removes any duplicates from the given slice   
		
	
		
			
				// Функция  removeDuplicates убирает любые дубликаты из предоставленного среза.   
		
	
		
			
				func  removeDuplicates ( slice  [ ] string )  [ ] string  {  
		
	
		
			
					seen  :=  map [ string ] struct { } { } 
 
		
	
		
			
					result  :=  [ ] string { }