Skip to content

Commit

Permalink
Merge pull request #62 from imanushin/feature/support-nuget-lookup-fr…
Browse files Browse the repository at this point in the history
…om-direct-path

Feature/support nuget lookup from direct path
  • Loading branch information
gluck authored Aug 27, 2018
2 parents 4c5a114 + ad9de17 commit 7d00f4f
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/bin
/.idea
*.iml
out
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# gradle-nuget-plugin changelog

## 2.17
### Added
* Ability to download nuget executable from the custom location (this can be used to download nuget.exe from local maven server)
* Ability to use previously downloaded nuget from custom location (this is useful when CI already downloaded nuget.exe)
* Upgrade gradle used to the newest version

## 2.16
### Added
* Added nuget sources task ([#58](https://github.com/Ullink/gradle-nuget-plugin/pull/58))
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,26 @@ buildscript {
}
dependencies {
classpath "com.ullink.gradle:gradle-nuget-plugin:2.16"
classpath "com.ullink.gradle:gradle-nuget-plugin:2.17"
}
}
apply plugin: 'nuget'
nuget {
// nuget.exe version to use, defaults to 4.4.0
// there are three different mutually excluded options for Nuget binary downloading:
// first: define nuget version for download.
// available versions can be found [here](https://dist.nuget.org/index.html)
version = '4.4.0'
// second - set nuget location, which will be used for download:
nugetExePath = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
// third: define nuget executable file, which is already downloaded previously:
nugetExePath = "C:\\Tools\\Nuget\\nuget.exe"
}
nugetSpec {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
76 changes: 62 additions & 14 deletions src/main/groovy/com/ullink/BaseNuGet.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@ package com.ullink

import org.gradle.api.tasks.Exec

import java.nio.file.Paths

import static org.apache.tools.ant.taskdefs.condition.Os.*

public class BaseNuGet extends Exec {
private static final String NUGET_EXE = 'NuGet.exe'

String verbosity

String nugetExePath

public BaseNuGet() {
}

private File getNugetHome(){
private File getNugetHome() {
def env = System.getenv()
def nugetHome = env['NUGET_HOME']
if(nugetHome != null)
if (nugetHome != null) {
return new File(nugetHome)
else
return new File(new File(new File(project.gradle.gradleUserHomeDir, 'caches'), 'nuget'), project.extensions.nuget.version)
} else {
def nugetCacheFolder = Paths.get(
project.gradle.gradleUserHomeDir.absolutePath,
'caches',
'nuget',
project.extensions.nuget.version.toString())

return nugetCacheFolder.toFile()
}
}

protected BaseNuGet(String command) {
Expand All @@ -28,16 +39,7 @@ public class BaseNuGet extends Exec {

@Override
void exec() {
def folder = getNugetHome()
def localNuget = new File(folder, NUGET_EXE)
if (!localNuget.exists()) {
if (!folder.isDirectory())
folder.mkdirs()
def exeName = project.extensions.nuget.version < '3.4.4' ? 'nuget.exe' : 'NuGet.exe'
def nugetUrl = "https://dist.nuget.org/win-x86-commandline/v${project.extensions.nuget.version}/${exeName}"
project.logger.debug "Downloading NuGet from $nugetUrl ..."
new URL(nugetUrl).withInputStream { i -> localNuget.withOutputStream{ it << i } }
}
File localNuget = getNugetExeLocalPath()

project.logger.debug "Using NuGet from path $localNuget.path"
if (isFamily(FAMILY_WINDOWS)) {
Expand All @@ -53,6 +55,52 @@ public class BaseNuGet extends Exec {
super.exec()
}

private File getNugetExeLocalPath() {
File localNuget

if (nugetExePath != null && !nugetExePath.empty && !nugetExePath.startsWith("http")) {
localNuget = new File(nugetExePath)

if (localNuget.exists()) {
return localNuget
}

throw new IllegalStateException("Unable to find nuget by path $nugetExePath (please check property 'nugetExePath')")
}

def folder = getNugetHome()
localNuget = new File(folder, NUGET_EXE)

if (!localNuget.exists()) {
if (!folder.isDirectory())
folder.mkdirs()

def nugetUrl = getNugetDownloadLink()

project.logger.info "Downloading NuGet from $nugetUrl ..."

new URL(nugetUrl).withInputStream {
inputStream ->
localNuget.withOutputStream { outputStream ->
outputStream << inputStream
}
}
}
localNuget
}

private String getNugetDownloadLink() {
if (nugetExePath != null && !nugetExePath.empty && nugetExePath.startsWith("http")) {
project.logger.debug("Nuget url path is resolved from property 'nugetExePath'")

return nugetExePath
}

def exeName = project.extensions.nuget.version < '3.4.4' ? 'nuget.exe' : 'NuGet.exe'

return "https://dist.nuget.org/win-x86-commandline/v${project.extensions.nuget.version}/${exeName}"
}

private String getNugetVerbosity() {
if (logger.debugEnabled) return 'detailed'
if (logger.infoEnabled) return 'normal'
Expand Down
211 changes: 211 additions & 0 deletions src/test/groovy/com/ullink/NuGetDownloadTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package com.ullink

import org.apache.commons.io.FileUtils
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

import java.nio.file.Paths
import java.util.zip.CRC32

@RunWith(JUnit4.class)
class NuGetDownloadTest extends GroovyTestCase {

private File cachesFolder
private File tempFolder

// this file fill simulate nuget.exe, which was installed locally
// this will be small file
private File simulatedNugetExecutablePath

private Project project

@Before
void init() {

project = ProjectBuilder.builder().build()

cachesFolder = Paths.get(
project.gradle.gradleUserHomeDir.absolutePath,
'caches',
'nuget').toFile()

tempFolder = Paths.get(
project.gradle.gradleUserHomeDir.absolutePath,
'temp').toFile()

simulatedNugetExecutablePath = Paths.get(
tempFolder.absolutePath,
'nuget.exe').toFile()

if (cachesFolder.exists()) {
cachesFolder.deleteDir()
}

if (!tempFolder.exists()) {
tempFolder.mkdir()
}

project.apply plugin: 'nuget'
}

@After
void cleanup() {
if (tempFolder != null && tempFolder.exists()) {
tempFolder.deleteDir()
}
}

@Test
void shouldBeAbleToDownloadNugetWithoutAnyParameters() {
// When
executeSomeNugetTask()

// Then
Assert.assertTrue(nugetExecutableExistsInCache())
}

@Test
void shouldThrowErrorOnInvalidHttpPath() {
// When
project.nugetPack {
nugetExePath = "http://localhost:99999"
}

// Then
def error = shouldFail {
executeSomeNugetTask()
}

Assert.assertFalse(nugetExecutableExistsInCache())
}

/**
* Idea of this test:
* 1. Download nuget.exe to the some location. This simulates situation, when nuget.exe was already installed on CI
* 2. Ask plugin just to use existing nuget.exe file from the predefined location
* 3. Verify that:
* * Task was executed without exceptions (e.g. some nuget file was used)
* * Nuget caches folder does not have nuget file (e.g. task used some other nuget file)
*/
@Test
void shouldBeAbleToCopyPreviouslyDownloadedNugetFile() {
// Given
downloadNugetExeToTemp("https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe")

// When
project.nugetPack {
nugetExePath = simulatedNugetExecutablePath.absolutePath
}

// Then
executeSomeNugetTask()

def cachedNugetFile = ensureSingleNuGetExeExists()

Assert.assertNull(cachedNugetFile)
}

/**
* Idea of this test:
* 1. Ask plugin to download nuget.exe from the custom location
* 2. Download the same file manually
* 3. Compare checksums of files
*/
@Test
void shouldDownloadNugetFromCustomUrl() {
// Given
def customUrl = "https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe"

// When
project.nugetPack {
nugetExePath = customUrl
}

// Then
executeSomeNugetTask()

def cachedNugetFile = ensureSingleNuGetExeExists()

Assert.assertNotNull(cachedNugetFile)

downloadNugetExeToTemp("https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe")

assertFileAreIdential(cachedNugetFile, simulatedNugetExecutablePath)
}

private static void assertFileAreIdential(File expected, File actual){

def expectedChecksum = FileUtils.checksum(expected, new CRC32()).value
def actualChecksum = FileUtils.checksum(actual, new CRC32()).value

Assert.assertEquals(expectedChecksum, actualChecksum)
}

private void downloadNugetExeToTemp(String remoteUrl){

def nonStandardNugetUrl = new URL(remoteUrl)

FileUtils.copyURLToFile(nonStandardNugetUrl, simulatedNugetExecutablePath)

}

private Boolean nugetExecutableExistsInCache() {
return ensureSingleNuGetExeExists() != null
}

private File ensureSingleNuGetExeExists() {
if (!cachesFolder.exists()) {
return null
}

String[] filePatters = ["exe"]

def allExecutables = FileUtils.listFiles(cachesFolder, filePatters, true)

def allNugetExecutables = allExecutables.findAll {
"nuget.exe".equalsIgnoreCase(it.name)
}

if (allNugetExecutables.size() == 1) {
return allNugetExecutables[0]
}

if (allNugetExecutables.empty) {
return null
}

throw new IllegalStateException("Too many nuget executables were downloaded: ${allExecutables.join()}")
}

private void executeSomeNugetTask() {
File nuspec = new File(project.tasks.nugetPack.temporaryDir, 'foo.nuspec')
nuspec.text = '''<?xml version='1.0'?>
<package xmlns='http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd'>
<metadata>
<id>foo</id>
<authors>Nobody</authors>
<version>1.2.3</version>
<description>fooDescription</description>
</metadata>
<files>
<file src='foo.txt' />
</files>
</package>'''

File fooFile = new File(project.tasks.nugetPack.temporaryDir, 'foo.txt')
fooFile.text = "Bar"

project.nugetPack {
basePath = project.tasks.nugetPack.temporaryDir
nuspecFile = nuspec
}

project.tasks.nugetPack.execute()
}
}

0 comments on commit 7d00f4f

Please sign in to comment.