diff --git a/Scenarios.md b/Scenarios.md index 174e589d6c..2e4221705c 100644 --- a/Scenarios.md +++ b/Scenarios.md @@ -1,6 +1,6 @@ ## Chocolatey Usage Scenarios -### ChocolateyInstallCommand [ 28 Scenario(s), 229 Observation(s) ] +### ChocolateyInstallCommand [ 29 Scenario(s), 245 Observation(s) ] #### when force installing a package that depends on an unavailable newer version of an installed dependency forcing dependencies @@ -111,6 +111,25 @@ * should have inconclusive package result * should still have the package installed with the expected version of the package +#### when installing a package from a nupkg file + + * config should match package result name + * should contain a warning message that it installed successfully + * should create a shim for console in the bin directory + * should create a shim for graphical in the bin directory + * should have a console shim that is set for non gui access + * should have a graphical shim that is set for gui access + * should have a successful package result + * should have a version of one dot zero dot zero + * should install the expected version of the package + * should install the package in the lib directory + * should install where install location reports + * should not create a shim for ignored executable in the bin directory + * should not create a shim for mismatched case ignored executable in the bin directory + * should not create an extensions folder for the package + * should not have inconclusive package result + * should not have warning package result + #### when installing a package happy path * config should match package result name @@ -315,7 +334,7 @@ * should not have inconclusive package result * should not have warning package result -### ChocolateyUninstallCommand [ 12 Scenario(s), 83 Observation(s) ] +### ChocolateyUninstallCommand [ 12 Scenario(s), 84 Observation(s) ] #### when force uninstalling a package @@ -385,7 +404,8 @@ * should not have inconclusive package result * should not have warning package result * should not put the package in the lib bad directory - * should remove package from the lib directory + * should not remove package from the lib directory + * should still have the package file in the directory #### when uninstalling a package with a read and delete share locked file diff --git a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs index 3048452920..c15604f8bb 100644 --- a/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/InstallScenarios.cs @@ -2665,5 +2665,177 @@ public void should_have_an_error_package_result() errorFound.ShouldBeTrue(); } } + + [Concern(typeof(ChocolateyInstallCommand))] + public class when_installing_a_package_from_a_nupkg_file : ScenariosBase + { + private PackageResult packageResult; + + public override void Context() + { + base.Context(); + Configuration.PackageNames = Configuration.Input = "{0}\\installpackage.1.0.0.nupkg".format_with(Configuration.Sources); + } + + public override void Because() + { + Results = Service.install_run(Configuration); + packageResult = Results.FirstOrDefault().Value; + } + + [Fact] + public void should_install_where_install_location_reports() + { + Directory.Exists(packageResult.InstallLocation).ShouldBeTrue(); + } + + [Fact] + public void should_install_the_package_in_the_lib_directory() + { + var packageDir = Path.Combine(Scenario.get_top_level(), "lib", "installpackage"); + + Directory.Exists(packageDir).ShouldBeTrue(); + } + + [Fact] + public void should_install_the_expected_version_of_the_package() + { + var packageFile = Path.Combine(Scenario.get_top_level(), "lib", "installpackage", "installpackage" + Constants.PackageExtension); + var package = new OptimizedZipPackage(packageFile); + package.Version.Version.to_string().ShouldEqual("1.0.0.0"); + } + + [Fact] + public void should_create_a_shim_for_console_in_the_bin_directory() + { + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "console.exe"); + + File.Exists(shimfile).ShouldBeTrue(); + } + + [Fact] + public void should_create_a_shim_for_graphical_in_the_bin_directory() + { + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "graphical.exe"); + + File.Exists(shimfile).ShouldBeTrue(); + } + + [Fact] + public void should_not_create_a_shim_for_ignored_executable_in_the_bin_directory() + { + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "not.installed.exe"); + + File.Exists(shimfile).ShouldBeFalse(); + } + + [Fact] + public void should_not_create_a_shim_for_mismatched_case_ignored_executable_in_the_bin_directory() + { + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "casemismatch.exe"); + + File.Exists(shimfile).ShouldBeFalse(); + } + + [Fact] + public void should_not_create_an_extensions_folder_for_the_package() + { + var extensionsDirectory = Path.Combine(Scenario.get_top_level(), "extensions", "installpackage"); + + Directory.Exists(extensionsDirectory).ShouldBeFalse(); + } + + [Fact] + public void should_have_a_console_shim_that_is_set_for_non_gui_access() + { + var messages = new List(); + + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "console.exe"); + CommandExecutor.execute( + shimfile, + "--shimgen-noop", + 10, + stdOutAction: (s, e) => messages.Add(e.Data), + stdErrAction: (s, e) => messages.Add(e.Data) + ); + + var messageFound = false; + + foreach (var message in messages.or_empty_list_if_null()) + { + if (string.IsNullOrWhiteSpace(message)) continue; + if (message.Contains("is gui? False")) messageFound = true; + } + + messageFound.ShouldBeTrue("GUI false message not found"); + } + + [Fact] + public void should_have_a_graphical_shim_that_is_set_for_gui_access() + { + var messages = new List(); + + var shimfile = Path.Combine(Scenario.get_top_level(), "bin", "graphical.exe"); + CommandExecutor.execute( + shimfile, + "--shimgen-noop", + 10, + stdOutAction: (s, e) => messages.Add(e.Data), + stdErrAction: (s, e) => messages.Add(e.Data) + ); + + var messageFound = false; + + foreach (var message in messages.or_empty_list_if_null()) + { + if (string.IsNullOrWhiteSpace(message)) continue; + if (message.Contains("is gui? True")) messageFound = true; + } + + messageFound.ShouldBeTrue("GUI true message not found"); + } + + [Fact] + public void should_contain_a_warning_message_that_it_installed_successfully() + { + bool installedSuccessfully = false; + foreach (var message in MockLogger.MessagesFor(LogLevel.Warn).or_empty_list_if_null()) + { + if (message.Contains("1/1")) installedSuccessfully = true; + } + + installedSuccessfully.ShouldBeTrue(); + } + + [Fact] + public void should_have_a_successful_package_result() + { + packageResult.Success.ShouldBeTrue(); + } + + [Fact] + public void should_not_have_inconclusive_package_result() + { + packageResult.Inconclusive.ShouldBeFalse(); + } + + [Fact] + public void should_not_have_warning_package_result() + { + packageResult.Warning.ShouldBeFalse(); + } + + [Fact] + public void config_should_match_package_result_name() + { + packageResult.Name.ShouldEqual("installpackage"); + } + + [Fact] + public void should_have_a_version_of_one_dot_zero_dot_zero() + { + packageResult.Version.ShouldEqual("1.0.0"); + } + } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 0f0dcebb9e..8f68aee7f9 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -257,21 +257,28 @@ public ConcurrentDictionary install_run(ChocolateyConfigu { this.Log().Debug("Updating source and package name to handle *.nupkg or *.nuspec file."); packageNames.Clear(); - packageNames.Add(_fileSystem.get_file_name_without_extension(packageName)); + config.Sources = _fileSystem.get_directory_name(_fileSystem.get_full_path(packageName)); if (packageName.EndsWith(Constants.ManifestExtension)) { + packageNames.Add(_fileSystem.get_file_name_without_extension(packageName)); + this.Log().Debug("Building nuspec file prior to install."); config.Input = packageName; // build package pack_run(config); } + else + { + var packageFile = new OptimizedZipPackage(_fileSystem.get_full_path(packageName)); + packageNames.Add(packageFile.Id); + } } } // this is when someone points the source directly at a nupkg - // e.g. -s c:\somelocation\somewhere\packagename.nupkg + // e.g. -source c:\somelocation\somewhere\packagename.nupkg if (config.Sources.to_string().EndsWith(Constants.PackageExtension)) { config.Sources = _fileSystem.get_directory_name(_fileSystem.get_full_path(config.Sources));