public override Task <object> ExecuteAsync(CancellationToken cancellationToken)
            {
                this.SetProgress(cancellationToken, "ensuring target directory exists");
                DirectoryEx.Create(this.TargetRootPath);

                int index = 0;

                if (this.DeleteExtra)
                {
                    this.SetProgress(cancellationToken, "checking existing files");
                    var remoteFileList = DirectoryEx.GetFileSystemInfos(this.TargetRootPath, MaskingContext.IncludeAll);

                    foreach (var file in remoteFileList)
                    {
                        index++;
                        this.SetProgress(cancellationToken, "checking existing files", 100 * index / remoteFileList.Count);

                        var relativeName = file.FullName.Substring(this.TargetRootPath.Length).Replace('\\', '/').Trim('/');
                        if (file is SlimDirectoryInfo)
                        {
                            if (!this.ExpectedDirectories.Contains(relativeName))
                            {
                                this.LogDebug("Deleting extra directory: " + relativeName);
                                DirectoryEx.Delete(file.FullName);
                            }
                        }
                        else
                        {
                            if (!this.ExpectedFiles.Contains(relativeName))
                            {
                                this.LogDebug($"Deleting extra file: " + relativeName);
                                FileEx.Delete(file.FullName);
                            }
                        }
                    }
                }

                index = 0;
                foreach (var relativeName in this.ExpectedDirectories)
                {
                    index++;
                    this.SetProgress(cancellationToken, "ensuring target subdirectories exist", 100 * index / this.ExpectedDirectories.Length);

                    DirectoryEx.Create(PathEx.Combine(Path.DirectorySeparatorChar, this.TargetRootPath, relativeName));
                }

                index = 0;
                foreach (var relativeName in this.ExpectedFiles)
                {
                    var sourcePath = PathEx.Combine(PathEx.Combine(Path.DirectorySeparatorChar, this.TempDirectoryName, "package"), relativeName);
                    var targetPath = PathEx.Combine(Path.DirectorySeparatorChar, this.TargetRootPath, relativeName);

                    index++;
                    this.SetProgress(cancellationToken, "moving files to target directory", 100 * index / this.ExpectedFiles.Length);

                    FileEx.Move(sourcePath, targetPath, true);
                }

                return(InedoLib.NullTask);
            }
Exemple #2
0
        protected override Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context)
        {
            var sourcePath = context.ResolvePath(this.SourceDirectory);

            this.LogInformation($"Finding matching files in {sourcePath}...");
            if (!DirectoryEx.Exists(sourcePath))
            {
                this.LogError($"Directory {sourcePath} does not exist.");
                return(Complete);
            }

            var mask    = new MaskingContext(this.Includes, this.Excludes);
            var matches = DirectoryEx.GetFileSystemInfos(sourcePath, mask)
                          .OfType <SlimFileInfo>()
                          .Where(f => f.FullName.EndsWith(".sql", StringComparison.OrdinalIgnoreCase))
                          .ToList();

            if (matches.Count == 0)
            {
                this.LogError($"No matching .sql files were found in {sourcePath}.");
                return(Complete);
            }

            var outputFileName = context.ResolvePath(this.OutputFile);

            DirectoryEx.Create(PathEx.GetDirectoryName(outputFileName));

            using (var buffer = new TemporaryStream())
            {
                using (var zip = new ZipArchive(buffer, ZipArchiveMode.Create, true))
                {
                    foreach (var f in matches)
                    {
                        var entryName = getEntryName(f.FullName);
                        this.LogDebug($"Adding {entryName}...");
                        zip.CreateEntryFromFile(f.FullName, entryName, CompressionLevel.Optimal);
                    }
                }

                buffer.Position = 0;

                using (var outputStream = FileEx.Open(outputFileName, FileMode.Create, FileAccess.Write, FileShare.None, FileOptions.SequentialScan))
                {
                    using (var inedoSqlStream = typeof(BundleSqlScriptsOperation).Assembly.GetManifestResourceStream("Inedo.Extensions.SqlServer.Operations.inedosql.exe"))
                    {
                        inedoSqlStream.CopyTo(outputStream);
                    }

                    buffer.CopyTo(outputStream);
                }
            }

            this.LogInformation($"{outputFileName} created.");
            return(Complete);

            string getEntryName(string fullName) => fullName.Substring(0, sourcePath.Length).TrimStart('\\', '/').Replace('\\', '/');
        }
        public override Task <IEnumerable <string> > EnumerateRemoteBranchesAsync()
        {
            try
            {
                this.BeginOperation();

                this.log.LogDebug("Enumerating remote branches...");

                if (!Repository.IsValid(this.repository.LocalRepositoryPath))
                {
                    this.log.LogDebug($"Repository not found at '{this.repository.LocalRepositoryPath}'...");
                    if (DirectoryEx.Exists(this.repository.LocalRepositoryPath))
                    {
                        var contents = DirectoryEx.GetFileSystemInfos(this.repository.LocalRepositoryPath, MaskingContext.Default);
                        if (contents.Count > 0)
                        {
                            throw new InvalidOperationException("Specified local repository path is invalid.");
                        }
                    }

                    var refs = Repository.ListRemoteReferences(this.repository.RemoteRepositoryUrl, this.CredentialsHandler);

                    var trimmedRefs = (from r in refs
                                       where r.CanonicalName.StartsWith("refs/heads/")
                                       let trimmed = r.CanonicalName.Substring("refs/heads/".Length)
                                                     select trimmed).ToList();

                    return(Task.FromResult(trimmedRefs.AsEnumerable()));
                }
                else
                {
                    this.log.LogDebug($"Repository found at '{this.repository.LocalRepositoryPath}'...");
                    using (var repository = new Repository(this.repository.LocalRepositoryPath))
                    {
                        var origin = repository.Network.Remotes["origin"];
                        this.log.LogDebug($"Using remote: origin, '{origin.Name}'.");
                        var refs = repository.Network.ListReferences(origin);

                        var trimmedRefs = (from r in refs
                                           where r.CanonicalName.StartsWith("refs/heads/")
                                           let trimmed = r.CanonicalName.Substring("refs/heads/".Length)
                                                         select trimmed).ToList();

                        return(Task.FromResult(trimmedRefs.AsEnumerable()));
                    }
                }
            }
            catch (Exception ex)
            {
                // gitsharp exceptions are not always serializable
                throw new ExecutionFailureException(ex.Message);
            }
            finally
            {
                this.EndOperation();
            }
        }
        protected override Repository OpenRepository()
        {
            if (DirectoryEx.Exists(this.LocalRepositoryPath))
            {
                if (Repository.IsValid(this.LocalRepositoryPath))
                {
                    var repository = new Repository(this.LocalRepositoryPath);

                    if (!string.IsNullOrEmpty(this.RemoteRepositoryUrl))
                    {
                        Commands.Fetch(repository, "origin", Enumerable.Empty <string>(),
                                       new FetchOptions {
                            CredentialsProvider = CredentialsHandler
                        }, null);
                        if (repository.Refs["refs/heads/" + this.BranchName] == null)
                        {
                            //Must use an ObjectId to create a DirectReference (SymbolicReferences will cause an error when committing)
                            var objId = new ObjectId(repository.Refs["refs/remotes/origin/" + this.BranchName].TargetIdentifier);
                            repository.Refs.Add("refs/heads/" + this.BranchName, objId);
                        }
                        repository.Refs.UpdateTarget("refs/heads/" + this.BranchName, "refs/remotes/origin/" + this.BranchName);
                    }

                    return(repository);
                }

                if (DirectoryEx.GetFileSystemInfos(this.LocalRepositoryPath, MaskingContext.Default).Any())
                {
                    throw new InvalidOperationException("The specified local repository path does not appear to be a Git repository but already contains files or directories.");
                }
            }
            else
            {
                DirectoryEx.Create(this.LocalRepositoryPath);
            }

            if (!string.IsNullOrEmpty(this.RemoteRepositoryUrl))
            {
                Repository.Clone(
                    this.RemoteRepositoryUrl,
                    this.LocalRepositoryPath,
                    new CloneOptions
                {
                    CredentialsProvider = this.CredentialsHandler,
                    IsBare = true
                }
                    );
            }
            else
            {
                Repository.Init(this.LocalRepositoryPath, true);
            }

            return(new Repository(this.LocalRepositoryPath));
        }
        public override Task <IEnumerable <RemoteBranchInfo> > EnumerateRemoteBranchesAsync()
        {
            bool endOperation = false;

            try
            {
                this.log.LogDebug("Enumerating remote branches...");

                if (!this.repository.HasLocalRepository || !Repository.IsValid(this.repository.LocalRepositoryPath))
                {
                    if (this.repository.HasLocalRepository)
                    {
                        this.log.LogDebug($"Repository not found at '{this.repository.LocalRepositoryPath}'...");
                    }

                    if (this.repository.HasLocalRepository && DirectoryEx.Exists(this.repository.LocalRepositoryPath))
                    {
                        var contents = DirectoryEx.GetFileSystemInfos(this.repository.LocalRepositoryPath, MaskingContext.Default);
                        if (contents.Count > 0)
                        {
                            throw new InvalidOperationException("Specified local repository path is invalid.");
                        }
                    }

                    var refs = Repository.ListRemoteReferences(this.repository.RemoteRepositoryUrl, this.CredentialsHandler);
                    return(Task.FromResult(getBranches(refs)));
                }
                else
                {
                    this.BeginOperation();
                    endOperation = true;

                    this.log.LogDebug($"Repository found at '{this.repository.LocalRepositoryPath}'...");
                    using (var repository = new Repository(this.repository.LocalRepositoryPath))
                    {
                        var origin = repository.Network.Remotes["origin"];
                        this.log.LogDebug($"Using remote: origin, '{origin.Name}'.");
                        var refs = repository.Network.ListReferences(origin);
                        return(Task.FromResult(getBranches(refs)));
                    }
                }
            }
            catch (Exception ex)
            {
                // gitsharp exceptions are not always serializable
                throw new ExecutionFailureException(ex.Message);
            }
            finally
            {
                if (endOperation)
                {
                    this.EndOperation();
                }
            }

            IEnumerable <RemoteBranchInfo> getBranches(IEnumerable <Reference> refs)
            {
                var branches = new HashSet <RemoteBranchInfo>();

                foreach (var r in refs)
                {
                    var direct = r.ResolveToDirectReference();
                    if (direct.CanonicalName.StartsWith("refs/heads/"))
                    {
                        branches.Add(new RemoteBranchInfo(direct.CanonicalName.Substring("refs/heads/".Length), direct.TargetIdentifier));
                    }
                }

                return(branches.ToArray());
            }
        }
        protected override Task <object> RemoteExecuteAsync(IRemoteOperationExecutionContext context)
        {
            if (this.ReadOnly ?? this.Hidden ?? this.System == null)
            {
                this.LogWarning("No file attributes have been specified.");
                return(Complete);
            }

            var mask       = new MaskingContext(this.Includes, this.Excludes);
            var sourcePath = context.ResolvePath(this.SourceDirectory);

            this.LogInformation($"Getting list of files in {sourcePath} matching {mask}...");
            var matches = DirectoryEx.GetFileSystemInfos(sourcePath, mask)
                          .OfType <SlimFileInfo>()
                          .ToList();

            if (matches.Count == 0)
            {
                this.LogWarning("No files match the specified mask.");
                return(Complete);
            }

            FileAttributes attributesToChange = 0;

            if (this.ReadOnly.HasValue)
            {
                attributesToChange |= FileAttributes.ReadOnly;
            }
            if (this.Hidden.HasValue)
            {
                attributesToChange |= FileAttributes.Hidden;
            }
            if (this.System.HasValue)
            {
                attributesToChange |= FileAttributes.System;
            }

            FileAttributes attributeValues = 0;

            if (this.ReadOnly.GetValueOrDefault())
            {
                attributeValues |= FileAttributes.ReadOnly;
            }
            if (this.Hidden.GetValueOrDefault())
            {
                attributeValues |= FileAttributes.Hidden;
            }
            if (this.System.GetValueOrDefault())
            {
                attributeValues |= FileAttributes.System;
            }

            if (this.VerboseLogging)
            {
                this.LogDebug("Attributes to change: " + attributesToChange);
                this.LogDebug("Attribute values: " + attributeValues);
            }

            this.LogDebug($"Found {matches.Count} matching files.");
            this.LogInformation("Applying attributes...");
            foreach (var file in matches)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                var attributes = file.Attributes;

                if (((attributes & attributesToChange) ^ attributeValues) != 0)
                {
                    attributes &= ~attributesToChange;
                    attributes |= attributeValues;
                    if (this.VerboseLogging)
                    {
                        this.LogDebug("Changing " + file.FullName + "...");
                    }
                    FileEx.SetAttributes(file.FullName, attributes);
                }
            }

            this.LogInformation("Attributes applied.");

            return(Complete);
        }