Зачем? Немного предыстории
Всем привет! Работаю я в группе программистов – мы занимаемся программированием микроконтроллеров и блоков управления на их основе для наземного транспорта. Так уж у нас задалось, что версий одного и того же ПО с разным функционалом/багами довольно много, которое мы зашивали в разное время, то одна из задач: определить версию ПО или его библиотек в зашитом перед нами блоке.
Ранее, при сборке проекта использовались написанные нами шаблоны, из которых получался заголовочный файл с переменными, через которые можно было узнать версии ПО. При переходе на git столкнулись с такой проблемой, что похожих шаблонов не предусмотрено. Следовательно нужно делать самим!
Работаем!
Для начала пришлось определиться, что нам нужно от программы и какой будет формат работы с ней.
Сформировались вот такие вот требования:
- Программа должна запускаться и работать в 1 клик(для упрощения сборки проекта)
- В отдельных репозиториях должны быть файлы-шаблоны
- Рядом с программой будет файл конфигурационный файл, по которому будет собирать
- Созданные заголовочные файлы будут лежать рядом с шаблонами
И конечно же список заменяемых «переменных» для шаблона и сам шаблон:
- $git_commit — полный закомментированный текст команды «git status -s»
- $git_namespace — наименование заголовочного файла
- $git_countFromHead — число коммитов с создания репозитория
- $git_hash — хэш данного коммита(5 первых символов)
- $git_numUnrevisionedFiles — число незакоммиченных файлов
- $git_timeNow_second — Секунда сборки
- $git_timeNow_minute — Минута сборки
- $git_timeNow_hour — Час сборки
- $git_timeNow_day — День сборки
- $git_timeNow_month — Месяц сборки
- $git_timeNow_year — Год сборки
Почему такой странный формат времени? Потому что используем формат std::tm
$git_commit #ifndef $git_namespace #define $git_namespace #include <ctime> namespace $git_namespace { const unsigned int countFromHead = $git_countFromHead; const unsigned int hash = 0x$git_hash; const unsigned int numUnrevisionedFiles = $git_numUnrevisionedFiles; const std::tm timeNow = { $git_timeNow_second, $git_timeNow_minute, $git_timeNow_hour, $git_timeNow_day, $git_timeNow_month, $git_timeNow_year - 1900 }; } #endif
Немного кода
Запускаем git и извлекаем данные
Process git = new Process(); git.StartInfo = new ProcessStartInfo(f[0], " --login -i"); git.StartInfo.RedirectStandardInput = true;// перенаправить вход git.StartInfo.RedirectStandardOutput = true;//перенаправить выход git.StartInfo.UseShellExecute = false; git.Start(); git.StandardInput.WriteLine("git rev-list HEAD --count"); string revlist = git.StandardOutput.ReadLine();
Ищем и меняем файлы в шаблоне
string str = string.Empty; File.Copy(path + filename + ".template",filename + ".h"); using (System.IO.StreamReader reader = System.IO.File.OpenText(filename + ".h")) { str = reader.ReadToEnd(); } str = str.Replace("$git_namespace", cur_head[0]); // Хэш данного коммита str = str.Replace("$git_countFromHead", git_revlist(cur_head)); str = str.Replace("$git_numUnrevisionedFiles", cur_commit.Length); str = str.Replace("$git_hash", cur_hash); // Хэш данного коммита str = str.Replace("$git_timeNow_second", DateTime.Now.Second.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_minute", DateTime.Now.Minute.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_hour", DateTime.Now.Hour.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_day", DateTime.Now.Day.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_month", DateTime.Now.Month.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_year", DateTime.Now.Year.ToString()); // Текущая время-дата str = str.Replace("$git_commit", cur_commit); // состояние коммита using (System.IO.StreamWriter file = new System.IO.StreamWriter(cur_head[0] + ".h")) { file.Write(str); }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Diagnostics; namespace hgitcreate { class Program { static string git_hash(string[] head) { string git_hash = "0"; string[] f = Directory.GetFiles(@"C:\Program Files (x86)\Git\bin", "sh.exe"); //ищем git if (f.Length == 0) { f = Directory.GetFiles(@"C:\Program Files\Git\bin", "sh.exe"); } else { if (f.Length != 0) { Process git = new Process(); git.StartInfo = new ProcessStartInfo(f[0], " --login -i");//задаем имя исполняемого файла //git.StartInfo.CreateNoWindow = true;//не создавать окно //git.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; git.StartInfo.RedirectStandardInput = true;// перенаправить вход git.StartInfo.RedirectStandardOutput = true;//перенаправить выход git.StartInfo.UseShellExecute = false;//обязательный параметр, для работы предыдущих // Process.Start(f[0], " --login -i"); git.Start(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardInput.WriteLine("git log"); git_hash = git.StandardOutput.ReadLine(); git_hash = git_hash.Substring(7, 7); } else { Console.Write("git(sh.exe) not found"); } } return git_hash; } static string git_commit(string[] head) { string git_commit = "0"; string[] f = Directory.GetFiles(@"C:\Program Files (x86)\Git\bin", "sh.exe"); //ищем git if (f.Length == 0) { f = Directory.GetFiles(@"C:\Program Files\Git\bin", "sh.exe"); } else { if (f.Length != 0) { Process git = new Process(); git.StartInfo = new ProcessStartInfo(f[0], " --login -i");//задаем имя исполняемого файла //git.StartInfo.CreateNoWindow = true;//не создавать окно //git.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; git.StartInfo.RedirectStandardInput = true;// перенаправить вход git.StartInfo.RedirectStandardOutput = true;//перенаправить выход git.StartInfo.UseShellExecute = false;//обязательный параметр, для работы предыдущих // Process.Start(f[0], " --login -i"); git.Start(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardInput.WriteLine("git status -s"); git_commit = "/* "; int i = 1; git_commit += git.StandardOutput.ReadLine() + " \n "; while (git.StandardOutput.Peek() != -1) { i++; git_commit += git.StandardOutput.ReadLine() + " \n "; } git_commit += " */ \n //" + i.ToString(); } else { Console.Write("git(sh.exe) not found"); } } return git_commit; } static string git_revlist(string[] head) { string git_revlist = "0"; string[] f = Directory.GetFiles(@"C:\Program Files (x86)\Git\bin", "sh.exe"); //ищем git if (f.Length == 0) { f = Directory.GetFiles(@"C:\Program Files\Git\bin", "sh.exe"); } else { if (f.Length != 0) { Process git = new Process(); git.StartInfo = new ProcessStartInfo(f[0], " --login -i");//задаем имя исполняемого файла //git.StartInfo.CreateNoWindow = true;//не создавать окно //git.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; git.StartInfo.RedirectStandardInput = true;// перенаправить вход git.StartInfo.RedirectStandardOutput = true;//перенаправить выход git.StartInfo.UseShellExecute = false;//обязательный параметр, для работы предыдущих // Process.Start(f[0], " --login -i"); git.Start(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardOutput.ReadLine(); git.StandardInput.WriteLine("git rev-list HEAD --count"); git_revlist = git.StandardOutput.ReadLine(); } else { Console.Write("git(sh.exe) not found"); } } return git_revlist; } static void Main(string[] args) { try { string[] heads = File.ReadAllLines("config.csv"); if (heads.Length > 0) { for (int i = 0; i < heads.Length; i++) { string[] cur_head = heads[i].Split(';'); File.Delete(cur_head[1] + cur_head[0] + ".h"); File.Copy(cur_head[1] + cur_head[0] + ".template", cur_head[1] + cur_head[0] + ".h"); string cur_hash = git_hash(cur_head); string cur_commit = git_commit(cur_head); //Console.ReadKey(); string str = string.Empty; using (System.IO.StreamReader reader = System.IO.File.OpenText(cur_head[1] + cur_head[0] + ".h")) { str = reader.ReadToEnd(); } str = str.Replace("$git_namespace", cur_head[0]); // Хэш данного коммита str = str.Replace("$git_countFromHead", git_revlist(cur_head)); str = str.Replace("$git_numUnrevisionedFiles", cur_commit.Substring(cur_commit.Length - 1, 1)); str = str.Replace("$git_hash", cur_hash); // Хэш данного коммита str = str.Replace("$git_timeNow_second", DateTime.Now.Second.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_minute", DateTime.Now.Minute.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_hour", DateTime.Now.Hour.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_day", DateTime.Now.Day.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_month", DateTime.Now.Month.ToString()); // Текущая время-дата str = str.Replace("$git_timeNow_year", DateTime.Now.Year.ToString()); // Текущая время-дата str = str.Replace("$git_commit", cur_commit); // состояние коммита using (System.IO.StreamWriter file = new System.IO.StreamWriter(cur_head[1] + cur_head[0] + ".h")) { file.Write(str); } } } else { Console.WriteLine("Конфигурационный файл пусть"); } } catch(ArgumentException ex) { Console.WriteLine(ex.Message); // Console.ReadKey(); } } } }
/* D ../../../git_header_maker/git.ps1 D ../../../git_header_maker/gitAll.ps1 M ../../../git_header_maker/git_test1.h M ../../../git_header_maker/git_test2.h D "../../../git_header_maker/git_version_lpc2000 \342\200\224 \320\272\320\276\320\277\320\270\321\217.h" M ../../../git_header_maker/git_version_lpc2000.h D ../../../git_header_maker/git_version_lpc2000.h M ../../App.config M ../../Program.cs M ../../Properties/AssemblyInfo.cs M ../../hgitcreate.csproj ?? ../../../config.csv ?? ../../../hgitcreate.exe ?? ../../../main exe/ */ //14 #ifndef git_version_lpc2000 #define git_version_lpc2000 #include <ctime> namespace git_version_lpc2000 { const unsigned int countFromHead = 3; const unsigned int hash = 0x957d20e; const unsigned int numUnrevisionedFiles = 4; const std::tm timeNow = { 56, 33, 17, 3, 7, 2015 - 1900 }; } #endif
Выводы
А вывода нет, просто небольшой костыль для упрощения сборки проекта и кому-нибудь на заметку.
ссылка на оригинал статьи http://geektimes.ru/post/253034/
Добавить комментарий