Собираем header-файлы для git репозиторием при помощи C#

от автора


Зачем? Немного предыстории

Всем привет! Работаю я в группе программистов – мы занимаемся программированием микроконтроллеров и блоков управления на их основе для наземного транспорта. Так уж у нас задалось, что версий одного и того же ПО с разным функционалом/багами довольно много, которое мы зашивали в разное время, то одна из задач: определить версию ПО или его библиотек в зашитом перед нами блоке.

Ранее, при сборке проекта использовались написанные нами шаблоны, из которых получался заголовочный файл с переменными, через которые можно было узнать версии ПО. При переходе на 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *