原问题
在构建我们的项目时,我希望每个存储库的 mercurial id 嵌入到该存储库的产品(库、应用程序或测试应用程序)中。
我发现如果您确切地知道构建他们正在使用的特定版本的应用程序的内容,那么调试由 8 个时区以外的客户运行的应用程序会变得非常容易。因此,我们系统中的每个项目(应用程序或库)都实现了一种获取相关修订信息的方法。
我还发现能够查看应用程序是否已使用存储库中的干净(未修改)变更集进行编译非常有用。当存储库中有未提交的更改时,'Hg id' 有用地将 + 附加到变更集 ID,因此这使我们可以轻松查看人们是否正在运行代码的干净版本或修改版本。
我当前的解决方案详述如下,满足基本要求,但存在许多问题。
当前解决方案
目前,对于每个 Visual Studio 解决方案,我添加了以下“预构建事件命令行”命令:
cd $(ProjectDir)
HgID
@echo off
type HgId.pre > HgId.cs
For /F "delims=" %%a in ('hg id') Do <nul >>HgID.cs set /p = @"%%a"
echo ; >> HgId.cs
echo } >> HgId.cs
echo } >> HgId.cs
namespace My.Namespace {
/// <summary> Auto generated Mercurial ID class. </summary>
internal class HgID {
/// <summary> Mercurial version ID [+ is modified] [Named branch]</summary>
public const string Version =
@echo off
type HgId.pre > HgId.cst
For /F "delims=" %%a in ('hg id') Do <nul >>HgId.cst set /p = @"%%a"
echo ; >> HgId.cst
echo } >> HgId.cst
echo } >> HgId.cst
fc HgId.cs HgId.cst >NUL
if %errorlevel%==0 goto :ok
copy HgId.cst HgId.cs
:ok
del HgId.cst
最佳答案
我想我有一个答案给你。这将有点复杂,但它使您不必执行任何批处理文件。您可以依靠 MSBuild 和自定义任务为您执行此操作。我已经使用了 MSBuild 的扩展包(可在 CodePlex 获得) - 但是您需要的第二项任务是您可以轻松编写自己的内容。
使用此解决方案,您可以右键单击 DLL 并在文件属性中查看 DLL(或 EXE)来自哪个 Mercurial 版本。
以下是步骤:
using System;
using System.Diagnostics;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
namespace BuildTasks
{
public class GetMercurialVersionNumber : Task
{
public override bool Execute()
{
bool bSuccess = true;
try
{
GetMercurialVersion();
Log.LogMessage(MessageImportance.High, "Build's Mercurial Id is {0}", MercurialId);
}
catch (Exception ex)
{
Log.LogMessage(MessageImportance.High, "Could not retrieve or convert Mercurial Id. {0}\n{1}", ex.Message, ex.StackTrace);
Log.LogErrorFromException(ex);
bSuccess = false;
}
return bSuccess;
}
[Output]
public string MercurialId { get; set; }
[Required]
public string DirectoryPath { get; set; }
private void GetMercurialVersion()
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WorkingDirectory = DirectoryPath;
p.StartInfo.FileName = "hg";
p.StartInfo.Arguments = "id";
p.Start();
string output = p.StandardOutput.ReadToEnd().Trim();
Log.LogMessage(MessageImportance.Normal, "Standard Output: " + output);
string error = p.StandardError.ReadToEnd().Trim();
Log.LogMessage(MessageImportance.Normal, "Standard Error: " + error);
p.WaitForExit();
Log.LogMessage(MessageImportance.Normal, "Retrieving Mercurial Version Number");
Log.LogMessage(MessageImportance.Normal, output);
Log.LogMessage(MessageImportance.Normal, "DirectoryPath is {0}", DirectoryPath);
MercurialId = output;
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--this is the import tag for the MSBuild Extension pack. See their documentation for installation instructions.-->
<Import Project="C:\Program Files (x86)\MSBuild\ExtensionPack\MSBuild.ExtensionPack.tasks" />
<!--Below is the required UsingTask tag that brings in our custom task.-->
<UsingTask TaskName="BuildTasks.GetMercurialVersionNumber"
AssemblyFile="C:\Users\mpld81\Documents\Visual Studio 2008\Projects\LambaCrashCourseProject\BuildTasks\bin\Debug\BuildTasks.dll" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D4BA6C24-EA27-474A-8444-4869D33C22A9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LibraryUnderHg</RootNamespace>
<AssemblyName>LibraryUnderHg</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="Build" DependsOnTargets="BeforeBuild">
<!--This Item group is a list of configuration files to affect with the change. In this case, just this project's.-->
<ItemGroup>
<AssemblyInfoFiles Include="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs" />
</ItemGroup>
<!--Need the extension pack to do this. I've put the Mercurial Id in the Product Name Attribute on the Assembly.-->
<MSBuild.ExtensionPack.Framework.AssemblyInfo AssemblyInfoFiles="@(AssemblyInfoFiles)"
AssemblyProduct="Hg: $(MercurialId)"
/>
<!--This is here as an example of messaging you can use to debug while you are setting yours up.-->
<Message Text="In Default Target, File Path is: @(AssemblyInfoFiles)" Importance="normal" />
</Target>
<Target Name="BeforeBuild">
<!--This is the custom build task. The Required Property in the task is set using the property name (DirectoryPath)-->
<BuildTasks.GetMercurialVersionNumber DirectoryPath="$(MSBuildProjectDirectory)">
<!--This captures the output by reading the task's MercurialId Property and assigning it to a local
MSBuild Property called MercurialId - this is reference in the Build Target above.-->
<Output TaskParameter="MercurialId" PropertyName="MercurialId" />
</BuildTasks.GetMercurialVersionNumber>
</Target>
<!--<Target Name="AfterBuild">
</Target>-->
</Project>
关于c# - 自动在 Visual Studio c# 项目中嵌入 mercurial 修订信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2386440/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha