/////////////////////////////////////////////////////////// // GGBuildTools // // Набор утилит для сборки проектов Gipat Group // // Copyright (C) 2007 Gipat Group // // Распространяется на условиях // // Gipat Group's opened EI-editor-utility license // // версии 1.0 // // // // www.gipatgroup.org // /////////////////////////////////////////////////////////// //К работе над данным файлом приложили руки, ноги.... короче аффтары: // 1) Sagrer (sagrer@yandex.ru) //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// // Модуль для работы с файлами *.sconf // // В этом файле хранится конфигурация // // для GGBuildTools // // версия формата 1 // //////////////////////////////////////////////////// unit SconfFormat; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LCLAnIniFile; const ScF_Version = 1; //Версия формата в этом исходнике. //Коды типа проекта ScF_ProjectType_Unknown = -1; //Тип неизвестен. ScF_ProjectType_VerInfoTxtOnly = 0; //Проект, у которого GGBuildTools используется только для манипуляции *.vit файлами с инфой о версии. ScF_ProjectType_PascalCode = 1; //Проект в котором номер версии забивается в *.pas ScF_ProjectType_CppCode = 2; //Проект в котором номер версии забивается в *.h //Типы архива. ScF_ArchiveType_Unknown = 'Unknown'; //Тип неизвестен. ScF_ArchiveType_7z = '7z'; //Тип архива *.7z. //Дефолтные значения для инфы файла. //[Main] ScF_Def_Main_FormatVersion = ScF_Version; ScF_Def_Main_ProjectType = ScF_ProjectType_Unknown; ScF_Def_Main_ProjectVer = '0.0.0.0'; ScF_Def_Main_UseSvn = false; ScF_Def_Main_ProjectRootDir = '.\'; //[IssBuilder] ScF_Def_IssBuilder_FilesDir = '.\distro\'; ScF_Def_IssBuilder_DefaultIssName = 'default.iss'; ScF_Def_IssBuilder_OutputDir = '.\installers\'; ScF_Def_IssBuilder_VersionsCacheDir = '.\ggbt\iss_cache\'; ScF_Def_IssBuilder_SaveToCache = false; ScF_Def_IssBuilder_CreateFull = true; ScF_Def_IssBuilder_CreateFull_AllowUpdate = false; ScF_Def_IssBuilder_CreateFull_UpdVers = '0'; ScF_Def_IssBuilder_CreateSeparateUpds = false; ScF_Def_IssBuilder_CreateSeparateUpds_UpdVers = '0'; ScF_Def_IssBuilder_CreateCumulateUpdate = false; ScF_Def_IssBuilder_CreateCumulateUpdate_UpdVers = '0'; //[SourcePackBuilder] ScF_Def_SourcePackBuilder_FilesDir = '.\source\'; ScF_Def_SourcePackBuilder_OutputDir = '.\sources\'; ScF_Def_SourcePackBuilder_ArchiveFormat = ScF_ArchiveType_7z; type RSconfMainSectionInfo = record //Структура с инфой из секции [Main] FormatVersion : Integer; //Версия формата конфега ProjectType : Integer; //Тип проекта. Возможные типы (на данный момент): Delphi, Builder, VerInfoTxtOnly, PascalCode, CppCode ProjectVer : AnsiString; //Либо разделенный точками номер версии (до 3 цифр вроде "0.1.2"), либо слово "Project" означающее что первые 3 цифры берутся из других файлов (в зависимости от типа проекта). UseSvn : Boolean; //Используется ли svn. ProjectRootDir : AnsiString; //Относительный (относитально ..\[папка со *.sconf] ) путь (windows) к корневой папке проекта. По умолчанию = ".\". end; RSconfIssBuilderSectionInfo = record //Структура с инфой из секции [IssBuilder] FilesDir : AnsiString; //Путь от root к папке где лежат файлы для запаковки в инсталлер (обычно это скомпиленные бинарники + сопутствующее файло). DefaultIssName : AnsiString; //Имя дефолтной iss-заготовки. OutputDir : AnsiString; //Путь от root к папке куда ложить скомпиленный инсталлер. VersionsCacheDir : AnsiString; //Путь от root к папке, куда ложить архив версий (файлы всех когда-либо собранных дистров). SaveToCache : Boolean; //Сохранять ли в кеш файлы для собранной версии. CreateFull : Boolean; //Создавать ли пакет, который может только ставиться с нуля. CreateFull_AllowUpdate : Boolean; //Создавать ли пакет, который может как обновить версию, так и поставить все с нуля. CreateFull_UpdVers : AnsiString; //Либо All, либо From:X где X - 4 цифры разделенные точками - номер версии начиная с которой (включительно) генерить апдейты, либо цифра - сколько сгенеренных версий (из кеша flist и iss) начиная от последней подвергать апдейту. CreateSeparateUpds : Boolean; //Создавать ли пакеты обновления с отдельных версий. CreateSeparateUpds_UpdVers : AnsiString; //Либо All, либо From:X где X - 4 цифры разделенные точками - номер версии начиная с которой (включительно) генерить апдейты, либо цифра - сколько сгенеренных версий (из кеша flist и iss) начиная от последней подвергать апдейту. CreateCumulateUpdate : Boolean; //Создавать ли кумулятивный пакет обновления. CreateCumulateUpdate_UpdVers : AnsiString; //Либо All, либо From:X где X - 4 цифры разделенные точками - номер версии начиная с которой (включительно) генерить апдейты, либо цифра - сколько сгенеренных версий (из кеша flist и iss) начиная от последней подвергать апдейту. end; RSconfSourcePackBuilderSectionInfo = record //Структура с инфой о секции [SourcePackBuilder] FilesDir : AnsiString; //Путь от root к папке где лежат файлы для запаковки в архив. OutputDir : AnsiString; //Путь от root к папке куда ложить архив. ArchiveFormat : AnsiString; //Тип архива в который все пакуется. end; TSconfFormat = class //Класс для работы с файлами формата *.sconf private //Закрытые методы... procedure ParseProjectType(const ProjectTypeStr : AnsiString); //Закинуть инфу о типе проекта из строки в инфу объекта класса. function GenerateProjectTypeString() : AnsiString; //Генерит тип проекта в виде строчки, например для записи в инишку. public //Переменные MainSection : RSconfMainSectionInfo; // Инфа из секции [Main] IssBuilderSection : RSconfIssBuilderSectionInfo; // Инфа из секции [IssBuilder] SourcePackBuilderSection : RSconfSourcePackBuilderSectionInfo; // Инфа из секции [SourcePackBuilder] ErrorMessage : AnsiString; // Сообщение о ошибке если была. //Конструкторы-деструкторы... constructor Create; destructor Destroy; override; //Открытые методы... procedure Clear(); //Очистить инфу класса и проставить дефолтные значения. function Load(const FileName : AnsiString) : boolean; //Загрузить файл в класс. function Save(const FileName : AnsiString) : boolean; //Сохранить инфу из класса в файл. end; implementation ///////////////////////////////////////////// // TSconfFormat // ///////////////////////////////////////////// //-----------------------------------------// // Конструкторы-деструкторы... // //-----------------------------------------// constructor TSconfFormat.Create; begin //Проставить дефолтные значения... Self.Clear(); ErrorMessage := 'none'; //Создать вложенные объекты классов... end; destructor TSconfFormat.Destroy; begin //Выкидываем мусор //Выполнить унаследованный деструктор inherited; end; //------------------------------------------// // Закрытые методы... // //------------------------------------------// procedure TSconfFormat.ParseProjectType(const ProjectTypeStr : AnsiString); //Закинуть инфу о типе проекта из строки в инфу объекта класса. begin if LowerCase(ProjectTypeStr) = 'verinfotxtonly' then begin MainSection.ProjectType := ScF_ProjectType_VerInfoTxtOnly; end else if LowerCase(ProjectTypeStr) = 'pascalcode' then begin MainSection.ProjectType := ScF_ProjectType_PascalCode; end else if LowerCase(ProjectTypeStr) = 'cppcode' then begin MainSection.ProjectType := ScF_ProjectType_CppCode; end else begin MainSection.ProjectType := ScF_ProjectType_Unknown; end; end; function TSconfFormat.GenerateProjectTypeString() : AnsiString; //Генерит тип проекта в виде строчки, например для записи в инишку. begin //Типо умолчальное значение. Result := ''; //Генерим. if MainSection.ProjectType = ScF_ProjectType_VerInfoTxtOnly then begin Result := 'VerInfoTxtOnly'; end else if MainSection.ProjectType = ScF_ProjectType_PascalCode then begin Result := 'PascalCode'; end else if MainSection.ProjectType = ScF_ProjectType_CppCode then begin Result := 'CppCode'; end else if MainSection.ProjectType = ScF_ProjectType_Unknown then begin Result := 'Unknown'; end; end; //------------------------------------------// // Открытые методы... // //------------------------------------------// procedure TSconfFormat.Clear(); //Очистить инфу класса и проставить дефолтные значения. begin //Проставить дефолтные значения... //[Main] MainSection.FormatVersion := ScF_Def_Main_FormatVersion; MainSection.ProjectType := ScF_Def_Main_ProjectType; MainSection.ProjectVer := ScF_Def_Main_ProjectVer; MainSection.UseSvn := ScF_Def_Main_UseSvn; MainSection.ProjectRootDir := ScF_Def_Main_ProjectRootDir; //[IssBuilder] IssBuilderSection.FilesDir := ScF_Def_IssBuilder_FilesDir; IssBuilderSection.DefaultIssName := ScF_Def_IssBuilder_DefaultIssName; IssBuilderSection.OutputDir := ScF_Def_IssBuilder_OutputDir; IssBuilderSection.VersionsCacheDir := ScF_Def_IssBuilder_VersionsCacheDir; IssBuilderSection.SaveToCache := ScF_Def_IssBuilder_SaveToCache; IssBuilderSection.CreateFull := ScF_Def_IssBuilder_CreateFull; IssBuilderSection.CreateFull_AllowUpdate := ScF_Def_IssBuilder_CreateFull_AllowUpdate; IssBuilderSection.CreateFull_UpdVers := ScF_Def_IssBuilder_CreateFull_UpdVers; IssBuilderSection.CreateSeparateUpds := ScF_Def_IssBuilder_CreateSeparateUpds; IssBuilderSection.CreateSeparateUpds_UpdVers := ScF_Def_IssBuilder_CreateSeparateUpds_UpdVers; IssBuilderSection.CreateCumulateUpdate := ScF_Def_IssBuilder_CreateCumulateUpdate; IssBuilderSection.CreateCumulateUpdate_UpdVers := ScF_Def_IssBuilder_CreateCumulateUpdate_UpdVers; //[SourcePackBuilder] SourcePackBuilderSection.FilesDir := ScF_Def_SourcePackBuilder_FilesDir; SourcePackBuilderSection.OutputDir := ScF_Def_SourcePackBuilder_OutputDir; SourcePackBuilderSection.ArchiveFormat := ScF_Def_SourcePackBuilder_ArchiveFormat; end; function TSconfFormat.Load(const FileName : AnsiString) : boolean; //Загрузить файл в класс. var IniFile1 : TAnIniFile; AllOk : boolean; begin //Инициализация. IniFile1 := TAnIniFile.Create; Result := false; //Проверяем, существует ли файл... AllOk := FileExists(FileName); if AllOk = false then begin //Если файла не существует... ErrorMessage := 'File '+FileName+' is not exists.'; end else begin //Если сам файлик вообще существует... Загружаем... AllOk := IniFile1.Load(FileName); if AllOk = false then begin //Не удалось загрузить файл. ErrorMessage := 'Error, loading file '+FileName; end; end; if AllOk = true then begin //Ок, загружено. Читаем сигнатуру... if IniFile1.ReadString('Main','FormatName') <> 'Sconf' then begin //Это не Sconf-файл. AllOk := false; ErrorMessage := 'File '+FileName+' is not Sconf file.'; end; end; if AllOk = true then begin //Проверяем версию формата... MainSection.FormatVersion := IniFile1.ReadInteger('Main','FormatVersion'); if MainSection.FormatVersion > ScF_Version then begin //Формат более новой версии чем код в бинарнике. AllOk := false; ErrorMessage := 'File '+FileName+' has more new version ('+IntToStr(MainSection.FormatVersion)+') then i know ('+IntToStr(ScF_Version)+'). Aborted loading. Try update to a new version of this software.'; end; end; if AllOk = true then begin //Собсно читаем инфу... //Когда будет версий формата больше одной - тут будет еще и поверсионка. //[Main] Self.ParseProjectType(IniFile1.ReadString('Main','ProjectType')); MainSection.ProjectVer := IniFile1.ReadString('Main','ProjectVer'); MainSection.UseSvn := IniFile1.ReadBool('Main','UseSvn'); MainSection.ProjectRootDir := IniFile1.ReadString('Main','ProjectRootDir'); //[IssBuilder] IssBuilderSection.FilesDir := IniFile1.ReadString('IssBuilder','FilesDir'); IssBuilderSection.DefaultIssName := IniFile1.ReadString('IssBuilder','DefaultIssName'); IssBuilderSection.OutputDir := IniFile1.ReadString('IssBuilder','OutputDir'); IssBuilderSection.VersionsCacheDir := IniFile1.ReadString('IssBuilder','VersionsCacheDir'); IssBuilderSection.SaveToCache := IniFile1.ReadBool('IssBuilder','SaveToCache'); IssBuilderSection.CreateFull := IniFile1.ReadBool('IssBuilder','CreateFull'); IssBuilderSection.CreateFull_AllowUpdate := IniFile1.ReadBool('IssBuilder','CreateFull_AllowUpdate'); IssBuilderSection.CreateFull_UpdVers := IniFile1.ReadString('IssBuilder','CreateFull_UpdVers'); IssBuilderSection.CreateSeparateUpds := IniFile1.ReadBool('IssBuilder','CreateSeparateUpds'); IssBuilderSection.CreateSeparateUpds_UpdVers := IniFile1.ReadString('IssBuilder','CreateSeparateUpds_UpdVers'); IssBuilderSection.CreateCumulateUpdate := IniFile1.ReadBool('IssBuilder','CreateCumulateUpdate'); IssBuilderSection.CreateCumulateUpdate_UpdVers := IniFile1.ReadString('IssBuilder','CreateCumulateUpdate_UpdVers'); //[SourcePackBuilder] SourcePackBuilderSection.FilesDir := IniFile1.ReadString('SourcePackBuilder','FilesDir'); SourcePackBuilderSection.OutputDir := IniFile1.ReadString('SourcePackBuilder','OutputDir'); SourcePackBuilderSection.ArchiveFormat := IniFile1.ReadString('SourcePackBuilder','ArchiveFormat'); //Ну, вроде бы все что надо прочитано. Теперь отмечаем что фсеок и собсно все. Result := true; end; //Чистим мусор. IniFile1.Free; end; function TSconfFormat.Save(const FileName : AnsiString) : boolean; //Сохранить инфу из класса в файл. var IniFile1 : TAnIniFile; begin //Все достаточно просто. Создаем пустой файл и просто вписываем нужные параметры... Result := false; //Типо умолчальное значение. //Инициализация IniFile1 := TAnIniFile.Create; //Собсно генерим файл для сейва. IniFile1.MakNewFile; //Типо служебное, хотя в принципе и в [Main]. IniFile1.WriteString('Main','FormatName','Sconf'); //Сигнатура IniFile1.WriteInteger('Main','FormatVersion',ScF_Version); //Версия формата //[Main] IniFile1.WriteString('Main','ProjectType',GenerateProjectTypeString()); IniFile1.WriteString('Main','ProjectVer',MainSection.ProjectVer); IniFile1.WriteBool('Main','UseSvn',MainSection.UseSvn); IniFile1.WriteString('Main','ProjectRootDir',MainSection.ProjectRootDir); //[IssBuilder] IniFile1.WriteString('IssBuilder','FilesDir',IssBuilderSection.FilesDir); IniFile1.WriteString('IssBuilder','DefaultIssName',IssBuilderSection.DefaultIssName); IniFile1.WriteString('IssBuilder','OutputDir',IssBuilderSection.OutputDir); IniFile1.WriteString('IssBuilder','VersionsCacheDir',IssBuilderSection.VersionsCacheDir); IniFile1.WriteBool('IssBuilder','SaveToCache',IssBuilderSection.SaveToCache); IniFile1.WriteBool('IssBuilder','CreateFull',IssBuilderSection.CreateFull); IniFile1.WriteBool('IssBuilder','CreateFull_AllowUpdate',IssBuilderSection.CreateFull_AllowUpdate); IniFile1.WriteString('IssBuilder','CreateFull_UpdVers',IssBuilderSection.CreateFull_UpdVers); IniFile1.WriteBool('IssBuilder','CreateSeparateUpds',IssBuilderSection.CreateSeparateUpds); IniFile1.WriteString('IssBuilder','CreateSeparateUpds_UpdVers',IssBuilderSection.CreateSeparateUpds_UpdVers); IniFile1.WriteBool('IssBuilder','CreateCumulateUpdate',IssBuilderSection.CreateCumulateUpdate); IniFile1.WriteString('IssBuilder','CreateCumulateUpdate_UpdVers',IssBuilderSection.CreateCumulateUpdate_UpdVers); //[SourcePackBuilder] IniFile1.WriteString('SourcePackBuilder','FilesDir',SourcePackBuilderSection.FilesDir); IniFile1.WriteString('SourcePackBuilder','OutputDir',SourcePackBuilderSection.OutputDir); IniFile1.WriteString('SourcePackBuilder','ArchiveFormat',SourcePackBuilderSection.ArchiveFormat); //И пишем сгенеренное на диск. Result := IniFile1.Save(FileName); //И заодно результат сообщим %). //Если там был какой-то файл уже - то его уже переколбасило, старый файл потерян %). //Ибо надо было проверять это все извне этой функции, там где все вызывается, это не работа //для объекта этого класса - проверять чего там есть или нет и разговаривать с юзверем, ему вообще //без понятия режим работы, толи он в консоли, толи GUI, толи еще как.... //Чистим мусор IniFile1.Free; end; end.