Giter Site home page Giter Site logo

psake's Introduction

Welcome to the psake project

Azure Pipelines GitHub Actions PS Gallery Chocolatey Nuget.org Gitter
Azure Pipelines Build Status GitHub Actions Status PowerShell Gallery Chocolatey Nuget downloads Join the chat at https://gitter.im/psake/psake

psake is a build automation tool written in PowerShell. It avoids the angle-bracket tax associated with executable XML by leveraging the PowerShell syntax in your build scripts. psake has a syntax inspired by rake (aka make in Ruby) and bake (aka make in Boo), but is easier to script because it leverages your existing command-line knowledge.

psake is pronounced sake – as in Japanese rice wine. It does NOT rhyme with make, bake, or rake.

How to get started

Step 1: Download and extract the project

You will need to "unblock" the zip file before extracting - PowerShell by default does not run files downloaded from the Internet. Just right-click the zip and click on "properties" and click on the "unblock" button.

Step 2: CD into the directory where you extracted the project (where the psake.psm1 file is)

Import-Module .\psake.psm1

If you encounter the following error "Import-Module : ...psake.psm1 cannot be loaded because the execution of scripts is disabled on this system." Please see "get-help about_signing" for more details.

  1. Run PowerShell as administrator
  2. Set-ExecutionPolicy RemoteSigned

Get-Help Invoke-psake -Full

  • this will show you help and examples of how to use psake

Step 3: Run some examples

CD .\examples

Invoke-psake

  • This will execute the "default" task in the "psakefile.ps1"

Invoke-psake .\psakefile.ps1 Clean

  • will execute the single task in the psakefile.ps1 script

Step 4: Set your PATH variable

If you wish to use the psake command from outside of the install folder, add the folder install directory to your PATH variable.

Step 5: (With VS2017) Install the VSSetup dependency

psake uses VSSetup to locate msbuild when using Visual Studio 2017. The VSSetup PowerShell module must be installed prior to compiling a VS2017 project with psake. Install instructions for VSSetup can be found here and here.

Release Notes

You can find all the information about each release of psake in the releases section.

How To Contribute, Collaborate, Communicate

If you'd like to get involved with psake, we have discussion groups over at Google: psake-dev psake-users

Anyone can fork the main repository and submit patches, as well. And lastly, the wiki and issues list are also open for additions, edits, and discussion.

Also check out the psake-contrib project for scripts, modules and functions to help you with a build.

License

psake is released under the MIT license.

psake's People

Contributors

alexandear avatar candland avatar damianh avatar devblackops avatar dlwyatt avatar ejsmith avatar ferventcoder avatar gep13 avatar gregmcguffey avatar idavis avatar iristyle avatar jameskovacs avatar jeffreyabecker avatar jmatos avatar jsnape avatar kblooie avatar lanwin avatar lholman avatar mabead avatar marking avatar nightroman avatar pedroreys avatar powerschill avatar rkeithhill avatar sleepersmith avatar smbecker avatar staxmanade avatar stej avatar uberdoodles avatar whut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

psake's Issues

issue with calculated properties and passing properties from commandline

When using the properties block in the build script with default values, i might have something like this

properties {
$x = 1
$y = 2
$z = $x + $y
}

Where $z is a calculated variable that is derived from $x and $y

But, I could call the build script from the commandline passing in a value of 5 for $x. In this case, the values for the variables end up being
$x=5
$y=2
$z=3

But, the build script would expect $z to be 7 and not 3. Since the value for $z gets evaluated before the value of $x from the commandline gets set for x, we have this issue.

I don't think psake is designed for this, and this will need me to do funny things to get my variables to values i would expect them to be

Ideally, the default values for non-derived values can come from 3 places. They are listed here in order of incerasing priority

  1. the defaults specified in the property block of the build script
  2. machine specific files that contains values for properties that will override the values above
  3. property values specified from the commandline by the user that overrides both of the above

The 3 things above will need to be evaluated before the calculated/derived properties are calculated.

Any thoughts/suggestions/help regarding this?

Thank You,
Vish

Error when executing Invoke-psake without parameters

The following error occurs when I'm executing Invoke-psake command without parameters intending to invoke default task in default.ps1 file in current directory. But then I am specifies either filename or task name (default in my case) Invoke-psake command executes correctly.

14.02.2012 11:39:59: An Error Occurred:
Test-Path : Cannot bind argument to parameter 'Path' because it is an empty string.
At D:\Configuration\Tools\Psake\psake.psm1:274 char:26
+         Assert (test-path <<<<  $buildFile -pathType Leaf) ($msgs.error_build_file_not_found -f $buildFile)
    + CategoryInfo          : InvalidData: (:) [Test-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.Test
   PathCommand

MSTest Failure not failing build; exit code 1

MSTest forces the exit code of Invoke-PSake to 1 if any test fails, regardless of ContinueOnError.

If I have a script such as:

Task test -ContinueOnError {
    exec { & MSTest /testcontainer:Failing.UnitTests.dll } 
}

That I invoke with a batch file such as:

powershell.exe -Version 2 -NoProfile -ExecutionPolicy unrestricted -Command "& {cls; Import-Module '.\psake\psake.psm1'; invoke-psake .\test.ps1 -framework 4.0 %*; if (($lastexitcode -ne 0) -and ($lastexitcode -ne $null)) {write-host "ERROR: $lastexitcode" -fore RED; exit $lastexitcode} }" 

I get a result:

Build Succeeded!

----------------------------------------------------------------------
Build Time Report
----------------------------------------------------------------------
Name   Duration
----   --------
test   00:00:02.4978145
Total: 00:00:02.5227254
ERROR: 1

I have a pull request that solves this issue, will be sending shortly

Make ExecuteTask a public function

Currently, In psake.psm1 the ExecuteTask function is a private function. I think it would be useful to be able to call this from your build script similar to how MSBuild allows you to invoke other targets using the CallTarget statement.

Proposal:
Make ExecuteTask function made public and rename it to Execute-Task to be consistent with the modules other public functions.

How should I use psake NuGet package?

I'd like to reference psake in my project through NuGet to be able to update it easily. However, I'd also like to have some kind of just-run-this-file-and-everything-will-build.cmd somewhere it can be easily found (i.e., in root dir of a project).

As for now, NuGet puts psake stuff into solution-dir\packages\psake.4.3.1.0\tools. The version part will obviously change, so how should my runner.cmd looks like?

UPD: I mean, there's a way to just use whatever version exists through simple logic (take whatever matched psake* and use it), but I wonder if there's a simpler way to do it.

Suggestion: Rake-like task list

I found psake and got very excited. I think its a very cool tool and answers some of my needs, but I really feel its lacking some items that would make it drastically more viable / easy to use. Take these suggestions with a grain of salt, it could just be my retentiveness. ;)

  • psake and my tasks should be in separate places. They should have no crossover / directory sharing. I realize nothing prevents one from doing this, its simply that the Wiki suggests placing task files there. In my project, I move my 3rd party libraries, tools, etc. to a completely separate folder away from my source code.
  • This could stand to have a better way to initialize the task system when running a task i.e. having this installed to a place like c:\Program Files\Common Files\Modules\psake\ and having that path added to the environment var for powershell's modules (http://msdn.microsoft.com/en-us/library/windows/desktop/dd878350(v=vs.85).aspx). Something as simple as a PowerShell script could do this function. MSI's etc, I dont see are necessary and would be overkill to do this simple task. (Although I do not know if PS is sandboxed from writting in Program Files)
  • It would be great if you could simply type "Invoke-Psake" or something along those lines within a directory, scour the entire tree for tasks based on some mechanism (many options here) and have the result returned to the console listing the tasks available. This would allow you to choose a task and run it, or alternatively use the task names returned to invoke the tasks one by one as needed, again using Invoke-Psake task name.

Again, just my 2 cents. Thank you so much for a great tool!

Build always succeeds when Set-PsDebug -Trace

When I have an error in a script I like to debug it using powershell's built in tracing. however, when using Set-PsDebug -Trace 2 (level 1 or 2) the build always succeeds, though it doesn't seem to run my tasks.

Build tester doesn't fail when nested builds fail

I'm just adding some tests to my fork so I can fix an issue where -whatif causes all sorts of problems but in doing so I think I've found an issue with the way the build tester works.

If a nested build fails I assume that the parent build should also fail? I have two files in my repo that show this isn't the case:

So I'm happy to fix this before I send a pull request but not sure if its a problem with the build tester

$psake.run_by_psake_build_tester = $true

or the part of psake.psm1 which ignores the nested scope due to the build tester

if (!$psake.run_by_psake_build_tester)

I don't think this should be global to all psake invocations but instead something that is pushed onto the context stack. That way only the top level invocation changes its error handling in response to being run under test.

Ability to silence module loading and build time report

I like using psake to make tasks like with rake. The one thing I don't like for small tasks if having the list of loaded modules and the build time report. I'm not sure it's possible to hide these messages, but it'd be really handy to have a switch or something in the psake-config.

Default task fails but specific tasks pass

I have a default.ps1 file and when calling psake ( alias ) without a task I get a path null error below. When I call with a task it works. After debugging this I found a -and that should be a -or. I'm submitting the issue and a pull request for this.

PS C:----\Source> psake
psake version 4.3.0
Copyright (c) 2010 James Kovacs

Error: 12/13/2013 11:36:47 AM:
At C:\Users\dliles\Documents\WindowsPowerShell\Modules\PSake\PSake.psm1:325 char:27 + Assert (test-path $buildF
ile -pathType Leaf) ($msgs.error_build_file_not ... + ~~~~~~~~~~ [<<==>>] Exception: Cannot b
ind argument to parameter 'Path' because it is an empty string.
PS C:----\Source>

Code that is incorrect
if ($buildFile -and !(test-path $buildFile -pathType Leaf) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) {
$taskList = $buildFile.Split(', ')
$buildFile = $psake.config_default.buildFileName
}

    # Execute the build file to set up the tasks and defaults
    Assert (test-path $buildFile -pathType Leaf) ($msgs.error_build_file_not_found -f $buildFile)

Should Be
if (($buildFile -or !(test-path $buildFile -pathType Leaf)) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) {
$taskList = $buildFile.Split(', ')
$buildFile = $psake.config_default.buildFileName
}

    # Execute the build file to set up the tasks and defaults
    Assert (test-path $buildFile -pathType Leaf) ($msgs.error_build_file_not_found -f $buildFile)

describe (or desc) function for describe the next task

This:

 task Foobar -depends Foo,Bar,Clear -description "This is my very very cool tesk task" {
 }

Is very long and not very readable. So i would like to suggest to add an describe or desc function which will provide a description for the next created task.

 desc "This is my very very cool tesk task"
 task Foobar -depends Foo,Bar,Clear {
 }

While typing this i get another idea:

 "This is my very very cool test task" |
 task Foobar -depends Foo,Bar,Clear {
 }

Could be work.

Any thoughts? I would work on a patch.

`Exec` is not friendly to valid exit codes not equal to 0

Just like in MSBuild the Exec task in psake is not friendly to valid exit codes not equal to 0. A practical example: for the popular tool robocopy.exe exit codes 1, 2, 3 are valid exit codes and codes greater than 3 indicate real errors.

MSBuild at least allows ignoring exit codes. That is only half a solution, actually. It also allows analysis of the exit code but the syntax is so convoluted that I never can remember it.

In the case of robocopy it would be nice if we can tell the build to fail if and only if an exit code is greater than 3.

The 4.2.0 version when invoked using the 'invoke-psake' does use the 'default.ps1' build file. Fails with exception.

"Test-Path : Cannot bind argument to parameter 'Path' because it is an empty string."

This appears to be a problem with the logic on the line below:

if ($buildFile -and !(test-path $buildFile -pathType Leaf) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) {

This never executes as $buildFile is $null. I've fixed temporarily by assigning a default value of $psake.config_default.buildFileName to the $buildFile.

Many psake build tests fail out of the box on 3.0

When running psake out of a fresh clone, most of the tests fail.

C:\Dev> git clone git://github.com/psake/psake.git
Cloning into psake...
remote: Counting objects: 761, done.
remote: Compressing objects: 100% (369/369), done.
remote: Total 761 (delta 435), reused 683 (delta 373)
Receiving objects: 100% (761/761), 667.62 KiB | 583 KiB/s, done.
Resolving deltas: 100% (435/435), done.
C:\Dev> cd psake
C:\Dev\psake [master]> .\psake-buildTester.ps1
Running psake build tests
.F..F....FFFFFFFFFFF.FF.
bad_PreAndPostActions_should_fail.ps1 (Passed)
calling_invoke-task_should_pass.ps1 (Failed)
circular_dependency_in_tasks_should_fail.ps1 (Passed)
default_task_with_action_should_fail.ps1 (Passed)
dotNet4_should_pass.ps1 (Failed)
duplicate_tasks_should_fail.ps1 (Passed)
explicitly_specified_32bit_build_should_pass.ps1 (Passed)
failing_postcondition_should_fail.ps1 (Passed)
missing_task_should_fail.ps1 (Passed)
multiline_blocks_should_pass.ps1 (Failed)
nested_builds_should_pass.ps1 (Failed)
running_aspnet_compiler_under_dotNet35_should_pass.ps1 (Failed)
simple_properties_and_tasks_should_pass.ps1 (Failed)
specifying_a_non_existant_buildfile_should_fail.ps1 (Passed)
tasksetup_should_pass.ps1 (Failed)
using_msbuild_should_pass.ps1 (Failed)
using_parameters_should_pass.ps1 (Failed)
using_postcondition_should_pass.ps1 (Failed)
using_PreAndPostActions_should_pass.ps1 (Failed)
using_precondition_should_pass.ps1 (Failed)
using_properties_should_pass.ps1 (Failed)
using_required_when_not_set_should_fail.ps1 (Passed)
using_required_when_set_should_pass.ps1 (Failed)
writing_psake_variables_should_pass.ps1 (Failed)

One or more of the build files failed

Get process id from exec {} block

When running Exec { msbuild ... } there are times when msbuild doesn't cleanly terminate. It would be useful to get the msbuild pid so that I can make sure that execution is indeed gone in my task where I am calling it. I can't just nuke all running instances of msbuild because there might be other builds currently running.

Exec doesn't check $lastexitcode anymore

I recently upgraded from 4.2.0.1 to 4.3, and just encountered a situation where I had test errors but psake reported "Build successful". I run nunit-console.exe by calling Exec, which previously checked $lastexitcode to determine if there was an error or not.

This behavior was removed in commit ee9dfef, but the commit message doesn't really give an clue as to why.

What is the recommended way to handle a non-zero exit code? Checking it manually?

Imported modules cannot invoke functions from other imported modules

Any module function that depends on functions from other imported modules error out saying that the dependent function does not exist. These modules work in the latest stable release as well as outside of psake. I was running the latest commit.

Any advice on how to fix this issue?

Framework function does not work

task Test {
Framework '2.0'
msbuild /version
Framework '3.5'
msbuild /version
Framework '4.0'
msbuild /version
}

all use msbuild 4.0 (my system default)

Upon further investigation, It seems like the framework might ONLY work when accepted as an invoke-psake parameter. I'm using psake for example to automate the creation of some nuget packages and need to run different compilers to generate different builds, being able to switch it up would be incredibly useful

Until it works properly the Framework function function should at least not be invokable from psake scripts

buildFile as taskList dose not work if psake.ps1 is in different dir then the default.ps1

The problem is this snipped in "psake.ps1":

if (-not(test-path $buildFile))
{
    $buildFile = (join-path $scriptPath $buildFile)
} 

This makes the buildFile absolute if it is not found. There are more then one solution to that.

  • Make taskList the default. This would be breaking, but its a better default since the most projects will only have one build file but multiple tasks.
  • Make the path only absolute if the absolute path exists. Not looked yet, this could be problematic in later processing.
  • Only make the path absolute if it ends with ps1
  • Get only the filename when buildFile is moved to taskList

I will send a patch, but would be discus the solution here first.

Set-StrictMode -Version Latest error in psake 4.3.1.0

If I set

Set-StrictMode -Version Latest

before running psake, then i get an error

"The variable '$buildToolsVersions' cannot be retrieved because it has not been set"

I suppose this is because of variable $buildToolsVersions declared inside of one block, and checked in another block.

Please adaptate psake to work with "Set-StrictMode -Version Latest" set before calling psake.

There is no license

I cannot find any license for psake. As I understand, this legally means that I can't use the code. I got this impression from here, here, and here.

I'd like to use this for my server builds, but I cannot open my company to possible legal holes.

Add support for Parallel Tasks (using PowerShell 3.0 Workflows as back-end)

Psake for now based on Powershell 2.0 and does not support parallel tasks at all.

Parallel tasks is very desired feature, making psake really first-class build system.
The only feature in PowerShell that support parallelism is workflows.
Workflows available since PowerShell 3.0.

So there only way I see to support parallel tasks is to migrating to PowerShell 3.0 and using workflows as back-end abstraction for parallel tasks.

Custom Task variables aren't in the correct scope.

I'm trying to write a declarative custom task. Normally, your tasks look like this

Task echo {
    Write-Host "hello, this is my task"
}

But, if you want to be declarative and separate the definition and execution of the task, you'll want something like this

Echo-Task hello { param($x)
    $x.message = "hello, this is my task"
}

Yeah, it's a little verbose for this trivial example, but it's powerful for more complicated tasks. And it's what's happening over in the Albacore library (Rake tasks for .NET & some custom tasks I've written). So, I have an implementation of the Echo task.

function Echo-Task([string]$name, [scriptblock]$def = $null) {
    $x = @{}
    & $def($x)

    $action = {
        Write-Host "$($x.message)"
    }

    Task $name $action @args
}

When I run this, I see the hashtable initialize, I can step through the $def block and see the hashtable properties initialized, the scriptblock is set, and the real psake Task is run. However, my message is not printed to the console! On further inspection, the variable $x has no value in the $action scriptblock.

I see on StackOverflow that there's a whole mess going on about scriptblock variable scoping. But, I don't control the execution of my scriptblock, psake does. I looked into the psake module at Invoke-Task and it's simply using the call operator

& $task.Action 

I see in another part of the module, Invoke-Psake, a note about dot-sourcing a scriptblock in the module scope or else.

# Simple dot sourcing will not work. We have to force the script block into our
# module's scope in order to initialize variables properly.
. $MyInvocation.MyCommand.Module $initialization

Does the call to the $action need to be modified to support this craziness?

Collored console output

I think about extending psake to colored console output like msbuild it have.

Are there any reason against that?

-docs Doesn't Show Tasks From Included Files

When -docs is passed to psake, Tasks defined in scripts loaded with the Include command are not lists.

Sample:
Paste this into a file named DocsIncludeTest.ps1:

Include .\DocIncludedTestIncluded.ps1

Task Default -Depends IncludedTask

And this into a file named DocIncludedTestIncluded.ps1:

Task IncludedTask {
    Write-Host 'doing included stuff'
}

Execute .\psake.ps1 -BuildFile .\DocsIncludeTest.ps1 -docs

The output is just the banner.

I've made a change to psake.psm1 for my own usage. Basically, the lines that load the included files (338 to 341) just need to happen before the if ($docs) check (line 330). This hasn't caused me any problems yet.

Sorry I haven't actually included a patch. git is still a new and foreign thing to me, and when I tried to create a patch, I had problems.

Running tests results in exception

PS C:\Users\gmauer\Documents\WindowsPowerShell\Modules\psake> .\psake-buildTester.ps1
Running psake build tests
.......Invalid specification syntax. Specs should end with _should_pass or _should_fail. executing_module_function_that_depends_on_another_module_should_work.ps1
At C:\Users\gmauer\Documents\WindowsPowerShell\Modules\psake\psake-buildTester.ps1:72 char:8
+         throw <<<<  "Invalid specification syntax. Specs should end with _should_pass or _should_fail. $fileName"
    + CategoryInfo          : OperationStopped: (Invalid specifi...should_work.ps1:String) [], RuntimeException
    + FullyQualifiedErrorId : Invalid specification syntax. Specs should end with _should_pass or _should_fail. executing_module_function_that_depends_on_another_module_should_w
   ork.ps1

Revert -docs back to table format and add -longdocs

The -docs parameter is designed to be a handy reference list of the available tasks. I work on a team of usually 2 to 5 people, and usually several team members know very little about the build scripts. Sometimes they ask me what commands to use, and I often tell them to use -docs to check because I don't always remember off-hand myself. Now, my scripts often have 10 or more tasks. This is easy to reach since they deal with configuration, compilation, database deployment, unit/integration tests, packaging, and even deployment to dev sites. Imagine me telling a UI developer to look at -docs and this is what he gets: (You can just scroll past without reading.)

Name        : Task0
Alias       :
Description :
Depends On  :
Default     :

Name        : Task1
Alias       :
Description :
Depends On  :
Default     :

Name        : Task2
Alias       :
Description :
Depends On  :
Default     :

Name        : Task3
Alias       :
Description :
Depends On  :
Default     :

Name        : Task4
Alias       :
Description :
Depends On  :
Default     :

Name        : Task5
Alias       :
Description :
Depends On  :
Default     :

Name        : Task6
Alias       :
Description :
Depends On  :
Default     :

Name        : Task7
Alias       :
Description :
Depends On  :
Default     :

Name        : Task8
Alias       :
Description :
Depends On  :
Default     :

Name        : Task9
Alias       :
Description :
Depends On  :
Default     :

I hope this simple example is enough to prove that the current implementation of -docs makes it utterly useless as a quick reference. That's only 10 tasks. Only the smallest of build scripts are going to have less than 5.

For this reason, I would like to propose two changes:

  1. Change -docs back to its original behavior of printing a compact table.
  2. Add a -longdocs parameter that prints out a long list like above. This would be allowed to appear with or without the -docs parameter.

I considered leaving -docs with its current functionality and adding something to give a table, but I decided to propose this instead because a second -docs-like parameter is more likely to be discovered by power users, which the long list is aimed at. I think it makes more sense for -docs to be the common users' implementation and for a second parameter to be geared towards power users.

I'm willing to work on this myself, but I'd like to get the requirements straight first. How does this proposal sound? Are there better ways of doing this?

How Do I Get Psake to Return Non-Zero Return Code on Build Failure

We can't figure out the proper way to get the newer versions of Psake tor return an error code when the build fails. We need this to happen in order to correctly integrate with our CI system (cruisecontrol.net, but I think it would be the same problem with any CI tool). All of the Wiki articles about integrating with CI tools are either way out of date or just don't make sense to us. We had to modify the end of the catch block in the "Invoke-psake" method as follows:

Before Modification:

    if (!$psake.run_by_psake_build_tester) {
        # if we are running in a nested scope (i.e. running a psake script from a psake script) then we need to re-throw the exception
        # so that the parent script will fail otherwise the parent script will report a successful build 
        $inNestedScope = ($psake.context.count -gt 1)
        if ( $inNestedScope ) {
            throw $_
        } else {
            Write-ColoredOutput $error_message -foregroundcolor Red
        }

    }

After Modification:

            throw $_

We could probably add back in the part about the build tester, I think the issue is with the nested scope, but we are using the tester so we stopped tweaking after we got correct failures.

Is psake just not meant to return the error all the way out? Is there some magic property to set to get this to happen? I've seen mention of magic properties in a few articles but they are all old and we couldn't find references to such properties in the actual code.

Parameter binding exception when using testpath and mkdir with default.ps1

This error occurs ONLY when you run psake without specifying the ps1 file so it defaults to default.ps1, (ex: psake nuget) if you specify the ps1 file the error does not occur (ex: psake default.ps1 nuget).

Steps to reproduce:

  1. Create a default.ps1 file in an empty directory with the following contents:
    Task Nuget {
    if ( ! (test-path 'nuget') ) { mkdir 'nuget' > $null }
    }
  2. Run psake nuget, it will NOT error out
  3. Verify the directory was created
  4. Run psake nuget again, this time it WILL error out
  5. Run psake default.ps1 nuget, and it WONT error out
  6. Delete the nuget directory and run psake nuget, and it WONT error out

Command type does not support user interaction

I'm attemping to call Invoke-Psake through Edge-ps and receive the following error.

The script has never required user interaction. I don't know

A command that prompts the user failed because the host program or the command type 
does not support user interaction.  Try a host program that supports user interaction, such 
as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-
related commands from command types that do not support user interaction, such as 
Windows PowerShell workflows.

Is there any way to get around this limitation to invoke psake from C#?

psake.ps1 throws 'Path is null' when it's run by TeamCity

I tried to set up build configuration in TeamCity using their PowerShell runner, and here's the output I got:

[Step 1/1] Starting: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy ByPass -File C:\TeamCity\buildAgent\work\85146bce395a8dd9\psake.ps1
[22:12:07][Step 1/1] in directory: C:\TeamCity\buildAgent\work\85146bce395a8dd9
[22:12:07][Step 1/1] Split-Path : Cannot bind argument to parameter 'Path' because it is null.
[22:12:07][Step 1/1] At C:\TeamCity\buildAgent\work\85146bce395a8dd9\psake.ps1:28 char:48
[22:12:07][Step 1/1] + [string]$scriptPath = $(Split-Path -parent $MyInvocation.MyCommand.path)
[22:12:07][Step 1/1] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

I tried to localize the problem and found out that the following command fails on my local machine as well with the same message:
powershell -File .\psake.ps1

No .NET Framework installation directory found

Hi, When running the samples, i get the following.

No .NET Framework installation directory found at \Microsoft.NET\Framework64\v3.5\

I also get this for .NET 4.0 on other projects - Running Win 7 x64.

Thanks

Tobi.

External modules with same cmdlet names as Psake (such as Resolve-Error), stomp out their Psake namesakes, resulting in unexpected behaviors

I'm just guessing here as to the root cause (imported module), but I'm getting an error without proper stacktrace information. I have seen other errors from Psake resolve correctly, so I'm not sure what makes this particular error different. It's purely speculation on my part that it's due to the module being imported -- but it's at least something to go on. I'll see if I can debug this if necessary.

5/15/2012 10:47:24 AM: An Error Occurred. See Error Details Below: 
----------------------------------------------------------------------
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.C
ommands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 11111111111111111111111111111111111111111111111111111111111111111111111111111111 Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 22222222222222222222222222222
222222222222222222222222222222222222222222222222222 Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 33333333333333333333333333333333333333333333333333333333333333333333333333333333 Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.Po
werShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 44444444444444444444444444444444444444444444444444444444444444444444444444444444 Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.Power
Shell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData----------------------------------------------------------------------
Script Variables
----------------------------------------------------------------------

Name                           Value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
----                           -----                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
_                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
args                           {}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
Error                          {}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
false                          False                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
input                          System.Management.Automation.Runspaces.PipelineReader`1+<GetReadEnumerator>d__0[System.Object]                                                                                                                                                                                                                                                                                                                                                                                                  
MaximumAliasCount              4096                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
MaximumDriveCount              4096                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
MaximumErrorCount              256                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
MaximumFunctionCount           4096                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
MaximumVariableCount           4096                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
msgs                           {error_no_framework_install_dir_found, error_task_name_does_not_exist, error_build_file_not_found, error_circular_reference...}                                                                                                                                                                                                                                                                                                                                                                 
MyInvocation                   System.Management.Automation.InvocationInfo                                                                                                                                                                                                                                                                                                                                                                                                                                                     
null                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
psake                          {run_by_psake_build_tester, version, build_script_dir, config_default...}                                                                                                                                                                                                                                                                                                                                                                                                                       
PSScriptRoot                   D:\JenkinsHome\workspace\FooBar9000\src\Packages\psake.4.1.0\tools                                                                                                                                                                                                                                                                                                                                                                                                                  
this                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
true                           True  

Error / Warning output is inconsistent with MSBuild, making it difficult to parse in build servers like Jenkins

We use the log parser plugin to readily drill down into build output and find errors generated by MSBuild.
https://wiki.jenkins-ci.org/display/JENKINS/Log+Parser+Plugin

To do this, we supply some regular expressions using a definition file that's written out by a Powershell bootstrapper.

$jenkinsMsBuildContent = @'
# Divide into sections based on project compile start
start /^------/

# Compiler Error
error /(?i)error [A-Z]+[0-9]+:/
error /MSBUILD : (?i)error :/
error /\(\d+(,\d+)?\): (?i)error [A-Za-z]*:/

# Compiler Warning
warning /(?i)warning [A-Z]+[0-9]+:/
'@
$jenkinsMsBuildContent | Out-File 'd:\JenkinsHome\VSParsingRules.txt' -Force -Encoding 'ASCII'

In any event, we could add some regexs to capture Psake output in the same way -- but I don't know that Psake output is really standardized. There is a header line like this that I could capture on...

4/27/2012 11:51:16 AM: An Error Occurred. See Error Details Below:

But it doesn't follow the same model of one line per error in a summary format like other build output does. Perhaps it should follow the same conventions established by MSBuild in that respect to make it easier for build systems to pick up the output?

Build task never fails

Not sure what i'm doing wrong here

task -name Build -description "builds outdated source files" -action {
    Exec {
            msbuild $srcFolder/$solutionName /t:Build 
    }
};

task -name Default -depends Build;

The build itself will show me errors, but it will always end with a Build Succeeded! message.

I'm using a ci-build.ps1 that looks something like this to invoke the build task

import-module Psake;
$psake.use_exit_on_error = $true;   
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
invoke-psake $scriptPath\build-Tasks.ps1 -parameters @{"config"="Release"} 
remove-module psake

any ideas here?

On systems with Turkish format setting psake doesn't run

This keeps happening even after the $currentThread fix already in place.

$psake.version = 4.2.0

Control Panel -> Region -> Format: [Select Turkish] -> restart

PSake bombs out with:

invoke-psake : The term 'invoke-psake' is not recognized as the name of a cmdlet, function, script file, or operable pr
ogram. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At ...\psake.ps1:46 char:1
+ invoke-psake $buildFile $taskList $framework $docs $parameters $properties $init ...
+ ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (invoke-psake:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Changing format back to [English (United States)](and restarting) fixes the problem.

Unwanted errors in $Error

This script

# load
Import-Module psake

# show docs
Invoke-psake default.ps1 -docs

# show errors there are two errors
$Error

Produces internally two errors:
<<<
Import-LocalizedData : Cannot find PowerShell data file 'psake.psd1' in directory 'C:\Users\rkuzmin\Documents\WindowsPowerShell\Modules\psake\en-US' or any parent
culture directories.
At C:\Users\rkuzmin\Documents\WindowsPowerShell\Modules\psake\psake.psm1:693 char:21

  • import-localizeddata <<<< -bindingvariable msgs -erroraction silentlycontinue
    • CategoryInfo : ObjectNotFound: (C:\Users\rkuzmi...n-US\psake.psd1:String) [Import-LocalizedData], PSInvalidOperationException
    • FullyQualifiedErrorId : ImportLocalizedData,Microsoft.PowerShell.Commands.ImportLocalizedData

Remove-Module : No modules were removed. Verify that the specification of modules to remove is correct and those modules exist in the runspace.
At C:\Users\rkuzmin\Documents\WindowsPowerShell\Modules\psake\psake.psm1:24 char:14

  • remove-module <<<< psake -erroraction silentlycontinue
    • CategoryInfo : ResourceUnavailable: (:) [Remove-Module], InvalidOperationException
    • FullyQualifiedErrorId : Modules_NoModulesRemoved,Microsoft.PowerShell.Commands.RemoveModuleCommand

=1=
What does the first error mean? There is no psake.psd1 anywhere (unless I miss something). Is this OK that psake does this job?

=2=
Is it possible to avoid psake errors like these? They pollute the $Error variable with information unlikely useful for a user, especially if a user analyses this variable for his task errors.

I'm trying to write a custom Task, but variables in my scriptblock aren't in the correct scope.

I'm trying to write a declarative custom task. Normally, your tasks look like this

Task echo {
    Write-Host "hello, this is my task"
}

But, if you want to be declarative and separate the declaration and execution of the task, you'll want something like this

Echo-Task hello { param($x)
    $x.message = "hello, this is my task"
}

Yeah, it's a little verbose for this trivial example, but it's powerful for more complicated tasks. And it's what's happening over in the [Albacore library][al](Rake tasks for .NET & some custom tasks I've written).

Should Psake have a more pluggable logging mechanism?

At present psake outputs it messages using Write-Output which makes them visible in the console as well as redirectable to a file (or any form of other STDOUT redirection).

This means that within your build process if you want to output a message that is visible alongside the psake output you need to use Write-Output too. However, this pollutes the pipeline, which effectively prevents you from doing any logging from within a function that needs to return a value (unless you want play around with extracting the returned value from amongst any log messages).

To avoid polluting the pipeline you can use Write-Host to display a message and whilst this is visible in the console, it won't appear alongside the psake output in any STDOUT redirection.

Equally, any custom logging framework you may be using inside of your powershell (e.g. log to a file, database etc.) will not 'see' any of the psake output, including any unhandled exceptions.

Am I missing something, or do others think there is case for extending psake to support a more pluggable logging mechanism?

properties override

Not sure how easy this would be to do, but today I discovered something unexpected regarding "-properties".

When I define two paths in my properties block like so:

properties {
    $base_dir      = "some\path"
    $src_dir        = "$base_dir\src"
}

...and I want to change base_dir via command line override, like so:

Invoke-psake .\script.ps1 -properties @{"base_dir"="a\nother\path"}

...then src_dir will still use the original value of base_dir ("some\path"). When I change base_dir via the command line I would expect that to affect all other properties that use the property.

My guess is that psake literally modifies the properties I pass via the command line, but by then all the other ones have already been initialized with the defaults.

Implementing this might be trickier than it sounds, but I do think it would be extremely useful. At the moment I work around it by re-building variables (mostly paths) before they are used in different tasks. I would love to be able to move them to a more global scope, like the properties.

A (naive?) idea off the top of my head would be:
When initialising the property block from the script (= the default values), always check if there is an override provided for the property at hand on the command line. If there is, use that instead of what it would default to in the script. Following initialisations would then use the command line value rather than the one from the script.

When I get some time I'll see if I can fork and try it myself, but I'm a bit of a powershell rookie.

Otherwise, while I'm at it: thanks for the great tool! Loving it.

Current path set to the path of the script instead of path invocation location.

For example when I execute:
Invoke-psake .....\RandomLocation\CommonScript.ps1

The working path is set to that script's location with no way to reference the location where the command was entered.

Reason why I believe this should work the other way around is due to the fact that you can easily find the current path of the script file by doing $MyInvocation.Command.Path (Or something similar, can't remember off top of my head.)

Force a task to run before other tasks without creating a dependency

This is not so much an issue as a question, although it could become a feature request. My apologies if this is the wrong place for it.

Consider these tasks:

Task Clean {
    # Deletes my output directory
}

Task CreateOutputDir {
    # Creates my output directory if it doesn't exist already
}

Task MakeSomeOutput1 -Depends CreateOutputDir {
    # Do something that creates some files in the output directory
}

Task MakeSomeOutput2 -Depends Clean,CreateOutputDir {
    # Do something that creates some files in the output directory
    # and fails if the output directory doesn't already exist
}

When I call psake with the task list MakeSomeOutput1,MakeSomeOutput2, my build fails. It fails because CreateOutputDir gets run before Clean because the dependencies are resolved in that order. I don't want MakeSomeOutput1 to trigger a Clean when run by itself, and simply creating the output directory explicitly in each task won't work since that would still erase the output of MakeSomeOutput1.

Is there a way to force the Clean to run first? Obviously, psake can't figure it out on its own. I'm certainly open to ideas on a better arrangement of tasks, as well.

Should accept non-string parameters

-parameters @{"skipBackup"=$true}
inside the script skipBackup is going to be a string, not a bool. This is really really confusing - especially when using these for preconditions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.