Skip to content

Instantly share code, notes, and snippets.

@JulianBirch JulianBirch/lein.ps1 forked from rosado/lein.ps1
Created May 9, 2010

What would you like to do?
#requires -version 2
# NB lein -? will give help for the powershell script
# lein help will give command help for Leiningen
[Parameter(Mandatory=$true, Position = 0, HelpMessage = "The command to pass to Leiningen")]
[Parameter(HelpMessage = "The version of Clojure to run. Needs to be compatible with the version of Leiningen or strange things can happen.")]
[string]$clojureVersion = "1.1.0", # e.g. 1.2.0-master-20100430.160229-59
[Parameter(HelpMessage = "The location of the Clojure jar. Don't use this unless you're compiling Clojure from trunk.")]
[string]$clojureJar, # e.g. "D:\julian\Documents\Projects\oss\circumspec\lib\clojure\1.2.0-master-20100430.160229-59.jar"
[Parameter(HelpMessage = "The version of Leiningen. 1.1.0 is the currently stable version.")]
[string]$leinVersion = "1.1.0", # e.g. 1.2.0
[Parameter(HelpMessage = "The location of Leiningen standalone jar. Don't use this unless you're compiling Leiningen from trunk. Also, make sure it points at an uberjar, not a regular jar.")]
[string]$leinJar, # e.g. D:\Julian\Documents\Projects\oss\leiningen\leiningen-standalone.jar
[Parameter(HelpMessage = "Where to download Leiningen from if you're doing a self-install. Make sure this value is compatible with leinJar and leinVersion or you'll never unpick the mess.")]
[string]$leinUrl, # e.g.
[Parameter(HelpMessage = "Completely overrides Leiningen and runs an arbitrary Clojure command. Don't use it unless you know what you're doing.")]
[Parameter(ValueFromRemainingArguments = $true)]$args
(Get-Host).PrivateData.VerboseForegroundColor = "Yellow" # This is pretty badly behaved. Basic users will like it, but advanced users may want to comment this out.
# Functions
function coalesce {
(@($args | ?{$_}) + $null)[0]
function join($separator, $items) {
[String]::Join($separator, $items)
function get-libs(){
if(test-path "lib"){
join ";" ((ls lib -include *.jar -recur) |% { $_.FullName })
function maven-location($directory, $product, $version, $extra) {
# $format = "{0}`\.m2`\repository`\{1}`\{2}`\{2}`\{1}-{2}{3}.jar";
# return [String]::Format($format, $env:UserProfile, $product, $version, $extra)
return "$env:UserProfile`\.m2`\repository`\$directory`\$product`\$version`\$product-$version$extra.jar";
function calculateClassPath($command) {
$libs = (get-libs)
# If we are not running from a checkout
if((-not (test-path $leinJar)) -and ($command -ne "self-install")){
write-error "Leiningen is not installed. Please run `"lein self-install`"."
exit 1
} # classes;test
if((test-path "classes\leiningen\core.class") -or (("compile", "deps") -contains $command)){
$result = "$leinJar;$libs"
} else {
$result = "src;classes;$leinJar;$libs"
if(("test", "repl") -contains $command) {
# tests should be runnable from repl
$testDir = (get-item -erroraction SilentlyContinue "test").FullName
$result= $testDir + ";" + $result
return $result
function execute-leiningen($command, [Parameter(ValueFromRemainingArguments = $true)]$args) {
$classPath = calculateClassPath $command
write-verbose "Taking Clojure $clojureVersion from $clojureJar"
write-verbose "Taking Leiningen $leinVersion from $leinJar"
$usingClassPath = (join "`n" ($classPath.Split(";")))
write-verbose "Using class path: `n$usingClassPath`n--End Class Path--"
if ($clojureCommand -eq "") {
if ($command -eq "repl") {
java -cp "$clojureJar;$classPath" clojure.main $args
$args = @($command) + @($args)
$escapedArgs = $args |% { $allArgs = "" } { $allArgs += "\`"$_\`" " } { $allArgs }
$clojureCommand = "(use 'leiningen.core) (-main $escapedArgs)"
write-verbose "Clojure command: $clojureCommand"
echo "java ""-Xbootclasspath/a:$clojureJar"" -cp ""$classPath"" clojure.main -e ""$clojureCommand""" > leinps1.log
java "-Xbootclasspath/a:$clojureJar" -cp "$classPath" clojure.main -e "$clojureCommand"
# Argument Defaults
$clojureJar = coalesce $clojureJar $env:clojureJar (maven-location "org`\clojure" "clojure" $clojureVersion)
$leinJar = coalesce $leinJar $env:leinJar (maven-location "leiningen" "leiningen" $leinVersion "-standalone")
$leinUrl = coalesce $leinUrl "$leinVersion-standalone.jar"
# Classes directory needs to exist before the JVM is launched apparently
if(-not (test-path "classes")){
[void](mkdir classes)
if (("compile", "jar", "uberjar") -contains $command){
# Deps need to run before the JVM launches for tasks that need them
if(-not (get-libs)) {
write-verbose "Obtaining dependencies"
execute-leiningen deps skip-dev
} elseif ($command -eq "self-install"){
write-verbose "Downloading Leiningen from $leinUrl"
$jarPath = split-path $leinJar
if(-not (test-path $jarPath)){
mkdir $jarPath
(new-object System.Net.WebClient).DownloadFile($leinUrl, $leinJar)
exit 0
execute-leiningen $command $args
# Credits and Notes:
# Coalesce by Keith Dalby
# Help with parameters by Keith Hill
# Heavily based on Roland Sadowski's original lein.ps1, but merged with concepts from Phil Hagelberg's lein.bat
# Anything left might be original :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.