Решил переписать свой autoincrement (статья1, статья2). Получилась вторая версия. В чём её отличия? Она не зависит от среды ( можно использовать для visual basic проектов, да и вообще для любых, в которых версия хранится в файле. Итак пару слов об получившейся утилите, а потом про прелести .net4
Утилита представляет собой программу и plugin. Причем plugin можно легко написать самому, следуя примеру. Я использую bazaar, которую ОЧЕНЬ рекомендую. Для него уже написан plugin.
Итак посмотрим что за программа получилась:
Напомню, стандартный вид версии для .net – major.minor.build.revision
Каждый plugin имеет свой однобуквенный идентификатор (не цифровой). Это сделано, чтобы упростить его использование.
Я могу написать vbinc2.exe -v0001 – увеличится только версия revision.
Могу написать vbinc2.exe -v0011 – увеличится и build и revision
Могу написать vbinc2.exe -v001-1 – увеличится на 1 build, а revision уменьшится на единицу.
Теперь что с plugin. Скажем, если у меня рядом с exe лежит plugin для bazaar, id которого равен b – я могу написать:
vbinc2.exe -v00b1
В этом случае для build будет взято то, что вернёт плагин с id “b”
Т.е. если текущая ревизия 5 – на месте build всегда будет 5 (пока мы не сделаем commit) а revision увеличится на 1.
Можно написать пару плагинов как вам удобно и использовать их так:
vbinc2.exe -v00bc
тогда build возьмется из одного plugin, а revision из другого…
Итак, что у нас с кодом… Во превых организация plugin. 4 .net имеет внутри втроенную подсистему для ораганизации plugins. Всё, что надо – описать интерфейс, вставить один аттрибут и пару функций:
Описываем интерфейс:
Copy Source | Copy HTML
public interface IVbinc2Sdk
{
string Id { get; }
string Name { get; }
string Description { get; }
int GetData();
}
Описываем Export в реализующем его классе:
Copy Source | Copy HTML
[Export(typeof(IVbinc2Sdk))]
public class Vbinc2Bzr : IVbinc2Sdk
{
private readonly string _id = "b";
private readonly string _name = "Bazaar";
private readonly string _desc = "Bazaar vcs plugin";
private static readonly StringBuilder GetOutput = new StringBuilder("");
public int GetData()
{
try
{
Вот и сам кусок, который занимается plugin…
Copy Source | Copy HTML
//Добавляем
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
//...
//Добавляем
class Program
{
[ImportMany(typeof(IVbinc2Sdk))]
protected IVbinc2Sdk[] Plugins { get; set; }
//...
//Сам main
static void Main(string[] args)
{
Program p = new Program();
p.Run(args);
}
...
private void Run(string[] args)
{
Compose();
}
...
private void Compose()
{
var catPlugs = new AggregateCatalog();
catPlugs.Catalogs.Add(new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));
var contPlugs = new CompositionContainer(catPlugs);
contPlugs.ComposeParts(this);
}
//и работа с плагинами:
private void ShowPlugins()
{
foreach (IVbinc2Sdk plugin in Plugins)
{
Console.WriteLine("--- Plugin: {0} ---", plugin.Name);
Console.WriteLine("{0}", plugin.Description);
Console.WriteLine("id: {0}", plugin.Id);
Console.WriteLine("");
}
}
//ВСЁ! Теперь можно накласть plugins, поместить их рядом с exe файлом и они
//будут сами распознаваться, читаться и т.д.
//СУПЕР!
Можно задать ключик -n – тогда взятое из plugin число будет увеличено на единицу…
Чтобы посмотреть help – -h
Чтобы посмотреть примеры (!) – -e
Если что непонятно – обращайтесь…
Сам проект лежит в [download id=”17″]. VS2010 .net4
Код мне не нравится, но я экспериментирую, учусь. Если покажете мне места, где можно пооптимизировать или “так никто не делает” – буду рад. Кроме того мне совершенно не нравится момент записи результата. Надо будет переписать по другому.
К примеру я в корне solution сделал директорию _v и поместил туда три файла:
vbinc2bzr.dll
vbinc2sdk.dll
vbinc2.exe
Потом в каждом проекте дописал в pre-build actions:
if $(ConfigurationName) == Release $(SolutionDir)\_v\vbinc2.exe -v00b1 -n
if $(ConfigurationName) == Release $(SolutionDir)\_v\vbinc2.exe -v00b1 -n -r”\[assembly\: AssemblyFileVersion\(“”(\d+)\.(\d+)\.(\d+)\.(\d+)””\)\]”
Какие недостатки…
плюсы…