Example #1
0
        private async Task UpdateAndCommitAsync(string package, IPackagePatch patch)
        {
            var overview = await _repository.GetPackageAsync(package).ConfigureAwait(false);

            if (overview == null)
            {
                throw new PackageNotFoundException(package);
            }

            var updatedPatch = new PackagePatch()
            {
                PublishedVersions = patch.PublishedVersions,
                DeletedVersions   = patch.DeletedVersions,
                UpdatedDistTags   = patch.UpdatedDistTags,
                DeletedDistTags   = patch.DeletedDistTags,

                // Ensure that we're only updating allowed fields on the Manifest by cloning the patch and inverting the updates
                UpdatedVersions = patch.UpdatedVersions.Select(version => {
                    var matching = overview.Versions.SingleOrDefault(v => v.Id == version.Id)
                                   ?? throw new PackageVersionNotFoundException(version.Id);

                    // Treat empty strings as equivalent to null
                    matching.Manifest.Deprecated = string.IsNullOrEmpty(version.Manifest.Deprecated) ? null : version.Manifest.Deprecated;
                    return(matching);
                }).ToList()
            };

            await _repository.CommitAsync(package, updatedPatch).ConfigureAwait(false);
        }
    }
        private static string GetResults(IPackagePatch patch)
        {
            var results = new[] {
                Tuple.Create(patch.PublishedVersions.Count, "published"),
                Tuple.Create(patch.UpdatedVersions.Count, "updated"),
                Tuple.Create(patch.DeletedVersions.Count, "unpublished")
            };

            return(string.Join(", ", results.Where(t => t.Item1 > 0).Select(t => $"{t.Item1} {t.Item2}")));
        }
Example #3
0
 public Task CommitAsync(string package, IPackagePatch patch)
 {
     return(patch.UpdatedVersions == null || patch.UpdatedVersions.Count == 0
         ? _repository.CommitAsync(package, patch)
         : UpdateAndCommitAsync(package, patch));
 }
Example #4
0
        public async Task CommitAsync(string package, IPackagePatch patch)
        {
            using (var connection = await _connectionProvider.GetConnectionAsync().ConfigureAwait(false))
                using (var transaction = connection.BeginTransaction()) {
                    var tasks = new List <Task>();

                    // Publish versions
                    if (patch.PublishedVersions?.Count > 0)
                    {
                        var packages = new List <PackageVersionEntity>();
                        var tarballs = new List <TarballEntity>();

                        foreach (var version in patch.PublishedVersions)
                        {
                            packages.Add(ToEntity(version));
                            tarballs.Add(ToEntity(version.Tarball));
                        }

                        tasks.Add(connection.ExecuteAsync(CreatePackageVersionQuery, packages, transaction));
                        tasks.Add(connection.ExecuteAsync(CreateTarballQuery, tarballs, transaction));
                    }

                    // Update versions
                    if (patch.UpdatedVersions?.Count > 0)
                    {
                        var versions = patch.UpdatedVersions.Select(ToEntity);
                        tasks.Add(connection.ExecuteAsync(UpdatePackageVersionQuery, versions, transaction));
                    }

                    //  Delete versions
                    if (patch.DeletedVersions?.Count > 0)
                    {
                        var versions = patch.DeletedVersions.Select(id => new PackageVersionEntity()
                        {
                            Package   = id.Name,
                            Version   = id.Version,
                            Published = false,
                            Manifest  = null // This is COALESCED in the UPDATE so it won't actually clobber the manifest
                        });

                        tasks.Add(connection.ExecuteAsync(UpdatePackageVersionQuery, versions, transaction));
                    }

                    // Update/create dist tags
                    if (patch.UpdatedDistTags?.Count > 0)
                    {
                        var tags = patch.UpdatedDistTags.Select(kvp => new DistTagEntity()
                        {
                            Package = package,
                            Tag     = kvp.Key,
                            Version = kvp.Value
                        });

                        tasks.Add(connection.ExecuteAsync(CreateDistTagQuery, tags, transaction));
                    }

                    // Delete dist tags
                    if (patch.DeletedDistTags?.Count > 0)
                    {
                        var param = new { Package = package, Tags = patch.DeletedDistTags };
                        tasks.Add(connection.ExecuteAsync(DeleteDistTagsQuery, param, transaction));
                    }

                    try {
                        await Task.WhenAll(tasks).ConfigureAwait(false);

                        transaction.Commit();
                    }
                    catch (SqliteException ex) {
                        if (ex.SqliteErrorCode != ErrorSqliteConstraint || ex.SqliteExtendedErrorCode != ErrorSqliteConstraintUnique)
                        {
                            throw;
                        }

                        var identifier = patch.PublishedVersions?.Count == 1 ? patch.PublishedVersions[0].Id : null;
                        throw new DuplicatePackageVersionException(identifier, ex);
                    }
                }
        }