Example #1
0
        public async Task PushCommand_AbsolutePathSource()
        {
            using (TestDirectory workingDir = TestDirectory.Create())
            {
                // Arrange (create a test package)
                DirectoryInfo packagePushDest = new DirectoryInfo(Path.Combine(workingDir, "packagePushDest"));
                packagePushDest.Create();

                List <PackageSource> packageSources = new List <PackageSource>();
                packageSources.Add(new PackageSource(packagePushDest.FullName));

                FileInfo packageInfo = SimpleTestPackageUtility.CreateFullPackage(workingDir, "test", "1.0.0");

                // Act
                await PushRunner.Run(
                    Settings.LoadDefaultSettings(null, null, null),
                    new TestPackageSourceProvider(packageSources),
                    packageInfo.FullName,
                    packagePushDest.FullName,
                    null,  // api key
                    null,  // symbols source
                    null,  // symbols api key
                    0,     // timeout
                    false, // disable buffering
                    false, // no symbols
                    new TestLogger());

                // Assert
                string destFile = Path.Combine(packagePushDest.FullName, packageInfo.Name);
                Assert.Equal(true, File.Exists(destFile));
            }
        }
Example #2
0
        public override async Task ExecuteCommandAsync()
        {
            string packagePath = Arguments[0];
            string apiKeyValue = null;

            if (!string.IsNullOrEmpty(ApiKey))
            {
                apiKeyValue = ApiKey;
            }
            else if (Arguments.Count > 1 && !string.IsNullOrEmpty(Arguments[1]))
            {
                apiKeyValue = Arguments[1];
            }

            try
            {
                await PushRunner.Run(
                    Settings,
                    SourceProvider,
                    new[] { packagePath },
                    Source,
                    apiKeyValue,
                    SymbolSource,
                    SymbolApiKey,
                    Timeout,
                    DisableBuffering,
                    NoSymbols,
                    NoServiceEndpoint,
                    SkipDuplicate,
                    Console);
            }
            catch (TaskCanceledException ex)
            {
                string timeoutMessage = LocalizedResourceManager.GetString(nameof(NuGetResources.PushCommandTimeoutError));
                throw new AggregateException(ex, new Exception(timeoutMessage));
            }
            catch (Exception ex)
            {
                if (ex is HttpRequestException && ex.InnerException is WebException)
                {
                    throw ex.InnerException;
                }

                throw;
            }
        }
Example #3
0
        public async Task PushCommand_AbsolutePathSourceAsync()
        {
            using (var workingDir = TestDirectory.Create())
            {
                // Arrange (create a test package)
                var packagePushDest = new DirectoryInfo(Path.Combine(workingDir, "packagePushDest"));
                packagePushDest.Create();

                var packageSources = new List <PackageSource>
                {
                    new PackageSource(packagePushDest.FullName)
                };

                var packageInfoCollection = new[]
                {
                    await SimpleTestPackageUtility.CreateFullPackageAsync(workingDir, "test1", "1.0.0"),
                    await SimpleTestPackageUtility.CreateFullPackageAsync(workingDir, "test2", "1.0.0")
                };

                // Act
                await PushRunner.Run(
                    Settings.LoadDefaultSettings(null, null, null),
                    new TestPackageSourceProvider(packageSources),
                    new[] { packageInfoCollection[0].FullName, packageInfoCollection[1].FullName },
                    packagePushDest.FullName,
                    null,  // api key
                    null,  // symbols source
                    null,  // symbols api key
                    0,     // timeout
                    false, // disable buffering
                    false, // no symbols,
                    false, // enable server endpoint
                    false, // no skip duplicate
                    new TestLogger());

                // Assert
                foreach (var packageInfo in packageInfoCollection)
                {
                    var destFile = Path.Combine(packagePushDest.FullName, packageInfo.Name);
                    Assert.True(File.Exists(destFile));
                }
            }
        }
Example #4
0
        public override async Task ExecuteCommandAsync()
        {
            string packagePath    = Arguments[0];
            string sourcePath     = Source;
            string apiKeyValue    = ApiKey;
            int    timeoutSeconds = Timeout;

            if (string.IsNullOrEmpty(apiKeyValue) && Arguments.Count > 1)
            {
                apiKeyValue = Arguments[1];
            }

            try
            {
                await PushRunner.Run(
                    Settings,
                    SourceProvider,
                    packagePath,
                    Source,
                    apiKeyValue,
                    Timeout,
                    DisableBuffering,
                    NoSymbols,
                    Console);
            }
            catch (TaskCanceledException ex)
            {
                string timeoutMessage = LocalizedResourceManager.GetString(nameof(NuGetResources.PushCommandTimeoutError));
                throw new AggregateException(ex, new Exception(timeoutMessage));
            }
            catch (Exception ex)
            {
                if (ex is HttpRequestException && ex.InnerException is WebException)
                {
                    throw ex.InnerException;
                }

                throw;
            }
        }
Example #5
0
        protected override void ProcessRecord()
        {
            _path = string.IsNullOrEmpty(_path) ? _literalPath : _path;

            // Get the .psd1 file or .ps1 file
            // Returns the name of the file or the name of the directory, depending on path
            var    pkgFileOrDir = new DirectoryInfo(_path);
            string moduleManifestOrScriptPath;

            if (isScript)
            {
                moduleManifestOrScriptPath = pkgFileOrDir.FullName;
                pkgName = pkgFileOrDir.Name.Remove(pkgFileOrDir.Name.Length - 4);
            }
            else
            {
                moduleManifestOrScriptPath = System.IO.Path.Combine(_path, pkgFileOrDir.Name + ".psd1");
                // Validate that there's a module manifest
                if (!File.Exists(moduleManifestOrScriptPath))
                {
                    var message = String.Format("No file with a .psd1 extension was found in {0}.  Please specify a path to a valid modulemanifest.", moduleManifestOrScriptPath);
                    var ex      = new ArgumentException(message);
                    var moduleManifestNotFound = new ErrorRecord(ex, "moduleManifestNotFound", ErrorCategory.ObjectNotFound, null);

                    this.ThrowTerminatingError(moduleManifestNotFound);
                }
                pkgName = pkgFileOrDir.Name;
            }

            FileInfo moduleFileInfo;

            moduleFileInfo = new FileInfo(moduleManifestOrScriptPath);
            // if there's no specified destination path to publish the nupkg, we'll just create a temp folder and delete it later
            string outputDir = !string.IsNullOrEmpty(_destinationPath) ? _destinationPath : System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            // if user does not specify that they want to use a nuspec they've created, we'll create a nuspec
            var dependencies = new Hashtable();

            if (string.IsNullOrEmpty(_nuspec))
            {
                _nuspec = createNuspec(outputDir, moduleFileInfo);
            }
            else
            {
                // Read the nuspec passed in to pull out the dependency information
                XDocument doc = XDocument.Load(_nuspec);

                // ex: <version>2.2.1</version>
                var versionNode = doc.Descendants("version");
                NuGetVersion.TryParse(versionNode.FirstOrDefault().Value, out NuGetVersion version);

                if (version == null)
                {
                    var message         = "Version is not specified in the .nuspec provided. Please provide a valid version in the .nuspec.";
                    var ex              = new ArgumentException(message);
                    var versionNotFound = new ErrorRecord(ex, "versionNotFound", ErrorCategory.NotSpecified, null);

                    this.ThrowTerminatingError(versionNotFound);
                }

                // ex: <dependency id="Carbon" version="2.9.2" />
                var dependencyNode = doc.Descendants("dependency");
                foreach (var dep in dependencyNode)
                {
                    dependencies.Add(dep.Attribute("id"), dep.Attribute("version"));
                }
            }

            // find repository
            var r             = new RespositorySettings();
            var repositoryUrl = r.Read(new[] { _repository });

            if (!repositoryUrl.Any())
            {
                var message            = String.Format("The resource repository '{0}' is not a registered. Please run 'Register-PSResourceRepository' in order to publish to this repository.", _repository);
                var ex                 = new ArgumentException(message);
                var repositoryNotFound = new ErrorRecord(ex, "repositoryNotFound", ErrorCategory.ObjectNotFound, null);

                this.ThrowTerminatingError(repositoryNotFound);
            }

            if (!_skipDependenciesCheck)
            {
                // Check to see that all dependencies are in the repository
                var findHelper = new FindHelper();

                foreach (var dependency in dependencies.Keys)
                {
                    // Need to make individual calls since we're look for exact version numbers or ranges.
                    var depName    = new[] { (string)dependency };
                    var depVersion = (string)dependencies[dependency];
                    var type       = new[] { "module", "script" };
                    var repository = new[] { _repository };

                    // Search for and return the dependency if it's in the repository.
                    var dependencyFound = findHelper.beginFindHelper(depName, type, depVersion, true, null, null, repository, _credential, false, false);

                    if (!dependencyFound.Any())
                    {
                        var message            = String.Format("Dependency {0} was not found in repository {1}.  Make sure the dependency is published to the repository before publishing this module.", depName, _repository);
                        var ex                 = new ArgumentException(message); // System.ArgumentException vs PSArgumentException
                        var dependencyNotFound = new ErrorRecord(ex, "DependencyNotFound", ErrorCategory.ObjectNotFound, null);

                        this.ThrowTerminatingError(dependencyNotFound);
                    }
                }
            }

            if (isScript)
            {
                File.Copy(_path, System.IO.Path.Combine(outputDir, pkgName + ".ps1"), true);
            }
            else
            {
                // Create subdirectory structure in temp folder
                foreach (string dir in System.IO.Directory.GetDirectories(_path, "*", System.IO.SearchOption.AllDirectories))
                {
                    var dirName = dir.Substring(_path.Length).Trim(PathSeparators);
                    System.IO.Directory.CreateDirectory(System.IO.Path.Combine(outputDir, dirName));
                }
                // Copy files over to temp folder
                foreach (string fileNamePath in System.IO.Directory.GetFiles(_path, "*", System.IO.SearchOption.AllDirectories))
                {
                    var fileName = fileNamePath.Substring(_path.Length).Trim(PathSeparators);
                    System.IO.File.Copy(fileNamePath, System.IO.Path.Combine(outputDir, fileName));
                }
            }

            var outputDirectory = System.IO.Path.Combine(outputDir, "nupkg");
            // Pack the module or script into a nupkg given a nuspec.
            var builder = new PackageBuilder();
            var runner  = new PackCommandRunner(
                new PackArgs
            {
                CurrentDirectory = outputDir,
                OutputDirectory  = outputDirectory,
                Path             = _nuspec,
                Exclude          = _exclude,
                Symbols          = false,
                Logger           = NullLogger.Instance
            },
                MSBuildProjectFactory.ProjectCreator,
                builder);

            runner.BuildPackage();


            // Push the nupkg to the appropriate repository
            // Pkg version is parsed from .ps1 file or .psd1 file
            var fullNupkgPath = System.IO.Path.Combine(outputDirectory, pkgName + "." + pkgVersion.ToNormalizedString() + ".nupkg");

            var repoURL         = repositoryUrl.First().Properties["Url"].Value.ToString();
            var publishLocation = repoURL.EndsWith("/v2", StringComparison.OrdinalIgnoreCase) ? repoURL + "/package" : repoURL;

            var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null, null, null);

            NuGet.Common.ILogger log = new NuGetLogger();
            PushRunner.Run(
                Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null),
                new PackageSourceProvider(settings),
                fullNupkgPath,
                publishLocation,
                _APIKey, // api key
                null,    // symbols source
                null,    // symbols api key
                0,       // timeout
                false,   // disable buffering
                false,   // no symbols
                         // Skip duplicate: if a package and version already exists, skip it and continue with the next package in the push, if any.
                false,   // no skip duplicate
                false,   // enable server endpoint
                log).GetAwaiter().GetResult();
        }
Example #6
0
        public static void Register(CommandLineApplication app, Func <ILogger> getLogger)
        {
            app.Command("push", push =>
            {
                push.Description = Strings.Push_Description;
                push.HelpOption(XPlatUtility.HelpOption);

                push.Option(
                    CommandConstants.ForceEnglishOutputOption,
                    Strings.ForceEnglishOutput_Description,
                    CommandOptionType.NoValue);

                var source = push.Option(
                    "-s|--source <source>",
                    Strings.Source_Description,
                    CommandOptionType.SingleValue);

                var symbolSource = push.Option(
                    "-ss|--symbol-source <source>",
                    Strings.SymbolSource_Description,
                    CommandOptionType.SingleValue);

                var timeout = push.Option(
                    "-t|--timeout <timeout>",
                    Strings.Push_Timeout_Description,
                    CommandOptionType.SingleValue);

                var apikey = push.Option(
                    "-k|--api-key <apiKey>",
                    Strings.ApiKey_Description,
                    CommandOptionType.SingleValue);

                var symbolApiKey = push.Option(
                    "-sk|--symbol-api-key <apiKey>",
                    Strings.SymbolApiKey_Description,
                    CommandOptionType.SingleValue);

                var disableBuffering = push.Option(
                    "-d|--disable-buffering",
                    Strings.DisableBuffering_Description,
                    CommandOptionType.SingleValue);

                var noSymbols = push.Option(
                    "-n|--no-symbols",
                    Strings.NoSymbols_Description,
                    CommandOptionType.SingleValue);

                var arguments = push.Argument(
                    "[root]",
                    Strings.Push_Package_ApiKey_Description,
                    multipleValues: true);

                var noServiceEndpointDescription = push.Option(
                    "--no-service-endpoint",
                    Strings.NoServiceEndpoint_Description,
                    CommandOptionType.NoValue);

                var interactive = push.Option(
                    "--interactive",
                    Strings.NuGetXplatCommand_Interactive,
                    CommandOptionType.NoValue);

                push.OnExecute(async() =>
                {
                    if (arguments.Values.Count < 1)
                    {
                        throw new ArgumentException(Strings.Push_MissingArguments);
                    }

                    string packagePath         = arguments.Values[0];
                    string sourcePath          = source.Value();
                    string apiKeyValue         = apikey.Value();
                    string symbolSourcePath    = symbolSource.Value();
                    string symbolApiKeyValue   = symbolApiKey.Value();
                    bool disableBufferingValue = disableBuffering.HasValue();
                    bool noSymbolsValue        = noSymbols.HasValue();
                    bool noServiceEndpoint     = noServiceEndpointDescription.HasValue();
                    int timeoutSeconds         = 0;

                    if (timeout.HasValue() && !int.TryParse(timeout.Value(), out timeoutSeconds))
                    {
                        throw new ArgumentException(Strings.Push_InvalidTimeout);
                    }

                    var sourceProvider = new PackageSourceProvider(XPlatUtility.CreateDefaultSettings());

                    try
                    {
                        DefaultCredentialServiceUtility.SetupDefaultCredentialService(getLogger(), !interactive.HasValue());

                        await PushRunner.Run(
                            sourceProvider.Settings,
                            sourceProvider,
                            packagePath,
                            sourcePath,
                            apiKeyValue,
                            symbolSourcePath,
                            symbolApiKeyValue,
                            timeoutSeconds,
                            disableBufferingValue,
                            noSymbolsValue,
                            noServiceEndpoint,
                            getLogger());
                    }
                    catch (TaskCanceledException ex)
                    {
                        throw new AggregateException(ex, new Exception(Strings.Push_Timeout_Error));
                    }

                    return(0);
                });
            });
        }
Example #7
0
        private static async Task PerformPushToSingleSourceAsync(
            ISettings settings,
            String packagePath,
            PackageSourceProvider psp,
            AsyncLazy <PackageIdentity> identity,
            Lazy <NuGetv3LocalRepository[]> allRepositories,
            NuGet.Common.ILogger logger,
            PushSourceInfo sourceItem,
            Int32 retryTimeoutForDirectoryDeletionFail,
            CancellationToken token
            )
        {
            var skipOverwrite               = sourceItem.SkipOverwriteLocalFeed.ParseAsBooleanSafe();
            var skipClearRepositories       = sourceItem.SkipClearingLocalRepositories.ParseAsBooleanSafe();
            var skipOfflineFeedOptimization = sourceItem.SkipOfflineFeedOptimization.ParseAsBooleanSafe();
            var apiKey            = sourceItem.ApiKey;
            var symbolSource      = sourceItem.SymbolSource;
            var symbolApiKey      = sourceItem.SymbolApiKey;
            var noServiceEndPoint = sourceItem.NoServiceEndPoint.ParseAsBooleanSafe();

            var source  = sourceItem.ItemSpec;
            var isLocal = IsLocalFeed(psp, source, out var localPath);

            if (isLocal && !skipOverwrite)
            {
                await DeleteDirAsync(retryTimeoutForDirectoryDeletionFail, OfflineFeedUtility.GetPackageDirectory(await identity, localPath), token);
            }

            if (isLocal && !skipOfflineFeedOptimization)
            {
                // The default v2 repo detection algorithm for PushRunner (PackageUpdateResource.IsV2LocalRepository) always returns true for empty folders, so let's use the OfflineFeedUtility here right away (which will assume v3 repository)
                await OfflineFeedUtility.AddPackageToSource(
                    new OfflineFeedAddContext(
                        packagePath,
                        localPath,
                        logger,
                        true,
                        false,
                        false,
                        new PackageExtractionContext(
                            PackageSaveMode.Defaultv3,
                            XmlDocFileSaveMode.None,
                            ClientPolicyContext.GetClientPolicy(settings, logger),
                            logger
                            )
                        ),
                    token
                    );
            }
            else
            {
                var timeoutString = sourceItem.PushTimeout;
                if (String.IsNullOrEmpty(timeoutString) || !Int32.TryParse(timeoutString, out var timeout))
                {
                    timeout = 1000;
                }

                try
                {
                    await PushRunner.Run(
                        settings,
                        psp,
                        packagePath,
                        source,
                        apiKey,
                        symbolSource,
                        symbolApiKey,
                        timeout,
                        false,
                        String.IsNullOrEmpty(symbolSource),
                        noServiceEndPoint,
                        logger
                        );
                }
                catch (HttpRequestException e) when
                    (e.Message.Contains("already exists. The server is configured to not allow overwriting packages that already exist."))
                {
                    // Nuget.Server returns this message when attempting to overwrite a package.
                    await Console.Out.WriteLineAsync($"Package already exists on source {source}, not updated.");
                }
            }

            if (!skipClearRepositories)
            {
                var id = await identity;
                foreach (var repo in allRepositories.Value)
                {
                    await DeleteDirAsync(retryTimeoutForDirectoryDeletionFail, repo.PathResolver.GetInstallPath(id.Id, id.Version), token);
                }
            }
        }