How do I run a Rake task every time a file is save

2019-05-21 06:28发布

How do I run a rake script automatically every time I save a file in Visual Studio? I can create a batch file that wraps the command. And I'd like to trigger it on CTRL + S. But, Visual Studio 2012 doesn't have macros.

JP Boodhoo has done it in many of his screen casts, but hasn't shared the implementation.


FYI, my rakefile looks like this

require 'albacore'

desc 'Build Solution'
msbuild :Build do |msb| 
  msb.properties :configuration => :Release 
  msb.targets :Clean, :Build 
  msb.solution = 'ProjoBot.sln' 
end 

desc 'Run Unit Tests' 
mspec :Test do |mspec| 
  mspec.command = 'Lib/Tools/MSpec/mspec-clr4.exe' 
  mspec.assemblies 'Src/Tests/ProjoBot.UnitSpecifications/bin/Release/ProjoBot.UnitSpecifications.dll'
end 

task :default => [:Build, :Test]

2条回答
Lonely孤独者°
2楼-- · 2019-05-21 07:02

There may be some options that integrate with the command line that are ignorant of Visual Studio.

The Ruby/Guard Way

I was playing with the Guard gem last night. You basically install guard and the Guard rake plugin.

gem install guard
gem install guard-rake

You can create a Guard "template", a Guardfile with a plain Rake task in it

guard init rake

You can edit it to watch .cs files in the source directory, for example. (and

guard 'rake', :task => 'default', :run_on_start => false do
  watch(%r{^source/.+\.cs$})
end

Then start Guard

guard

You may need to use -i to turn off this "interactive" mode, which may generate errors on Windows!

guard -i

Guard runs like a little local server, showing logs

12:07:08 - INFO - Guard uses TerminalTitle to send notifications.
12:07:08 - INFO - Starting guard-rake default
12:07:08 - INFO - Guard is now watching at 'D:/temp'
[1] guard(main)>

And if you force a file change (I'm going to touch a fake file I set up in my test directory), you'll get the output of your rake task!

12:07:08 - INFO - Guard uses TerminalTitle to send notifications.
12:07:08 - INFO - Starting guard-rake default
12:07:08 - INFO - Guard is now watching at 'D:/temp'
12:07:54 - INFO - running default
building!...
[1] guard(main)>

The PowerShell Way

There's nothing fancy out there that wraps up filesystem polling triggered actions, but that doesn't mean you can't build your own! I wrote a .\guard.ps1 file that sits in my solution root. It has a FileSystemWatcher and waits for changes in a loop.

$here = Split-Path $MyInvocation.MyCommand.Definition

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "$here\source"
$watcher.IncludeSubdirectories = $true

while($true) {
  # timeout here lets the console process kill commands and such
  $result = $watcher.WaitForChanged('All', 3000)

  if($result.TimedOut) {
    continue
  }

  # this is where you'd put your rake command
  Write-Host "$($result.ChangeType):: $($result.Name)"

  # and a delay here is good for the CPU :)
  Start-Sleep -Seconds 3
}

You can see it working and printing when you touch or create (New-Item <name> -Type File) files. But, we can also execute rake very simply

rake

PowerShell will just go ahead and execute that as a native command. You could get fancy and make this script look and feel more like Guard (ok, not a lot more, but a little!)

param(
  [string] $path = (Split-Path $MyInvocation.MyCommand.Definition),
  [string] $task = 'default'
)

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $path
$watcher.IncludeSubdirectories = $true

while($true) {
  $result = $watcher.WaitForChanged('All', 3000)

  if($result.TimedOut) {
    continue
  }

  rake $task

  Start-Sleep -Seconds 3
}

And you'd execute it like this

.\guard.ps1 -Path "$pwd\source" -Task 'build'
查看更多
不美不萌又怎样
3楼-- · 2019-05-21 07:12

I used the External Tools to run a batch file that executes the default Rake task.

@ECHO OFF
rake

I assigned the shortcut key CTRL + S to the tool, so that, when I save, the rake task is triggered! I hope this helps someone looking to do the same thing.

查看更多
登录 后发表回答