转载:Using PowerShell in the build process 使用Powershell进行build
2010-01-28 14:54
501 查看
Using PowerShell in the build process
by Mike Linnen四月 08, 2009 06:37
I
have used NAnt and MSBuild for years on many projects and I always
thought there has to be a better way to script build processes. Well I
took a look at PowerShell
and psake
and so far I like it. psake
is a PowerShell
script that makes breaking up your build script into target tasks very
easy. These tasks can also have dependencies on other tasks. This
allows you to call into the build script requesting a specific task to
be built and have the dependant tasks get executed first. This concept
is not anything new to build frameworks but it is a great starting
point to use the goodness of PowerShell in a build environment.
You can get psake from the Google Code repository
.
I first tried the download link for v0.21 but I had some problems
getting it to run my tasks so I went directly to the source and grabbed
the tip version (version r27 at the time) of psake.ps1 and my problems
went away.
You can start off by using the default.ps1 script
as a basis for your build process. For a simple build process that I
wanted to have for some of my small projects I wanted to be able to do
the following:
“Clean”the local directory
“Compile” the VS 2008 Solution
“Test” the nunit tests
“Package” the results into a zip for easy xcopy deployment
Here is what I ended up with as a starting point for my default.ps1.
![](http://www.protosystem.net/image.axd?picture=image_thumb.png)
This
really doesn't do anything so far except set up some properties for
paths and define the target tasks I want to support. The psake.ps1
script assumes your build script is named default.ps1 unless you pass
in another script name as an argument. Also since the task default is
defined in my build script if I don't pass in a target task then the
default task is executed which I have set as Test.
Build invoked without any target task:
![](http://www.protosystem.net/image.axd?picture=image_thumb_1.png)
Build invoked with the target task Package specified:
![](http://www.protosystem.net/image.axd?picture=image_thumb_2.png)
So
now I have the shell of my build so lets get it to compile my Visual
Studio 2008 solution. All I have to do is add the code to the Compile
task to launch VS 2008 passing in some command line options.
![](http://www.protosystem.net/image.axd?picture=image_thumb_3.png)
And here it is in action:
![](http://www.protosystem.net/image.axd?picture=image_thumb_4.png)
Notice
I had to pipe the result of the command line call to “out-null”. If I
didn't do this the call to VS 2008 would run in the background and
control would be passed back to my PowerShell script immediately. I
want to be sure that my build script would wait for the compile to
complete before it would continue on.
What about if the
compile fails? As it is right now the build script does not detect
that the compile completed successfully or not. VS 2008 (and previous
versions of VS) return an exit code that defines if the compile was
successful or not. If the exit code = 0 then you can assume it was
successful. So all we need to do is test the exit code after the call
to VS 2008. PowerShell makes this easy with the $LastExitCode
variable. Throwing an exception in a task is detected by the psake.ps1
script and stops the build for you.
![](http://www.protosystem.net/image.axd?picture=image_thumb_5.png)
I
placed a syntax error in a source file and when I call the Test target
the Compile target fails and the Test target never executes:
![](http://www.protosystem.net/image.axd?picture=image_thumb_6.png)
Now
I want to add in the ability to get the latest code from my source
control repository. Here is were I wanted the ability to support
multiple solutions for different source control repositories like
Subversion or SourceGear Vault. But lets get it to work first with
Subversion and then later refactor it to support other repositories.
For starters lets simply add the support for getting latest code in the
Compile task.
![](http://www.protosystem.net/image.axd?picture=image_thumb_7.png)
As
you can see right now this is very procedural and could certainly use
some refactoring, but lets get it to work first and then worry about
refactoring. Here it is in action:
![](http://www.protosystem.net/image.axd?picture=image_thumb_8.png)
As
I mentioned before I want to be able to support multiple source control
solutions. The idea here is something similar to what CI Factory
uses. In CI Factory
you have what is known as a Package. A Package is nothing more than an
implementation of a build script problem for a given product. For
example you might have a source control package that uses Subversion
and another source control package that uses SourceGear Vault. You
simply include the package you want for the source control product that
you are using. Psake also allows for you to include external scripts
in your build process. Here is how we would change what we have right
now to support multiple source control solutions.
So I created
a Packages folder under the current folder that my psake.ps1 script
resides. I then created a file called SourceControl.SVN.ps1 in the
Packages folder that looked like the following:
![](http://www.protosystem.net/image.axd?picture=image_thumb_9.png)
In
the default.ps1 script Compile task I replaced the source control get
latest code (told you I was going to refactor it) with a call to the
SourceControl.GetLatest function (Line #20). I also added a call to
the psake include function (Line #10) passing in the following
“Packages/SourceControl.SVN.ps1”. Here is what the default.ps1 looks
like now:
![](http://www.protosystem.net/image.axd?picture=image_thumb_10.png)
So
if I wanted to support SourceGear Vault I would simply create another
package file called SourceControl.Vault.ps1 and place the
implementation inside the GetLatest function and change the include
statement in the default.ps1 script to reference the vault version of
source control. I plan on adding in support for my Unit Tests the same
way I did the source control, that way I can easily have support for
multiple unit testing frameworks.
Conclusion
Asyou can see it is pretty easy to use PowerShell to replace your build
process. This post was just a short introduction on how you might get
started and end that crazy XML syntax that has been used for so long in
build scripting. I have a lot more to do on this to make it actually
usable for some of my small projects but hopefully I can evolve it into
something that will be easy to maintain and reliable. All in all I
think PowerShell has some pretty cool ways of scripting some nice build
solutions.
相关文章推荐
- 在通配符中使用范围运算符(Using the Range Operator in Wildcard Queries)
- 转载:SQL through PowerShell 使用Powershell访问SQL并对数据进行读写增加删除操作
- python2.7升级到python3后,用pip进行安装时报Fatal error in launcher:Unbale to create process using`""
- How to get the password text in a text with password property from another process using C++ - 用C++如何从不同进程获取密码框文本
- 转载 PHP学习笔记 - 在Eclipse中使用XDebug调试代码 | Using XDebug debug code in eclipse
- how the process using the hard disk in linux
- How to get the running applications in windows task manager using powershell
- The easy way to execute sudo command in Python using subprocess.Popen
- 使用cocapods报错 [!] Your Podfile has had smart quotes sanitised. To avoid issues in the future, you should not use TextEdit for editing it. If you are not using TextEdit, you should turn off smart quotes
- Find Exchange Servers in the Local Active Directory Site using PowerShell
- We are already in the process of making 11 connections and the number of simultaneous builds has be
- 使用VS进行工作流开发系列博客1-"So You Want to Develop Custom Workflows in Visual Studio..." - The Blog Series
- 【转载】在ASP.NET 2.0 中如何使用多个Sitemap文件【Using Multiple Sitemap Files in ASP.NET 2.0--英文】
- Using the WebLogic Maven Plug-In for Deployment:自己build weblogic maven plugin
- [转载]A cycle was detected in the build path of project
- 【Python错误】windows下使用pip/easy_install提示Fatal error in launcher: Unable to create process using...
- 在响应链中使用视图控制器Using View Controllers in the Responder Chain[苹果官方文档的翻译]
- python pip使用报错:Fatal error in launcher: Unable to create process using '"'
- 【转载】10.1\t使用项目视图类(Using the Item View Convenience Classes)
- 状态模式在领域驱动设计中的使用(Using the State pattern in a Domain Driven Design)