public static async Task <RepositoryImportResult> ImportAsync(Project project,
                                                                      AppConfiguration appConfiguration,
                                                                      IRepositoryAuthenticationInfo authInfo,
                                                                      ReadOnlyCollection <IRepositoryImportStrategy> strategies,
                                                                      CustomLogger runnerLogger,
                                                                      string commitId = null)
        {
            if (authInfo != null)
            {
                if (await authInfo.Validate() == false)
                {
                    runnerLogger.Information($"Validation for {nameof(authInfo)} did not pass.");

                    return(new RepositoryImportResult(string.Empty, true));
                }
            }

            var strategy = strategies.FirstOrDefault(x => x.Type == project.RepositoryType);

            if (strategy == null)
            {
                runnerLogger.Error($"Unknown Source Code Import type: {project.RepositoryType}");
                return(default);
        public Task <RepositoryImportResult> ImportAsync(Project project, AppConfiguration appConfiguration,
                                                         IRepositoryAuthenticationInfo authInfo,
                                                         CustomLogger runnerLogger,
                                                         string commitId = null)
        {
            return(Task.Run(() =>
            {
                // Try to get the auth data.
                var info = authInfo as AuthInfo;
                if (info == null)
                {
                    return new RepositoryImportResult(string.Empty, true);
                }

                // Setup storage directory.
                var folderName = $"{project.Name}_{DateTime.UtcNow.Ticks}";
                var path = Path.Combine(appConfiguration.BaseDirectory, folderName);

                try
                {
                    // Create the path before we start.
                    Directory.CreateDirectory(path);

                    // Clone the repository first.
                    var cloneOptions = new CloneOptions
                    {
                        CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials
                        {
                            Username = info.Username,
                            Password = info.Password
                        }
                    };

                    var cloneResult = Repository.Clone(project.RepositoryUrl, path, cloneOptions);
                    if (string.IsNullOrEmpty(cloneResult))
                    {
                        return new RepositoryImportResult(string.Empty, true);
                    }

                    // Checkout the branch.
                    using (var repo = new Repository(path))
                    {
                        var branch = repo.Branches[project.BranchName ?? "main"];

                        if (branch == null)
                        {
                            new RepositoryImportResult(string.Empty, true);
                        }

                        runnerLogger.Information("Checking out...");

                        Branch currentBranch;

                        if (commitId != null)
                        {
                            var localCommit = repo.Lookup <Commit>(new ObjectId(commitId));
                            if (localCommit == null)
                            {
                                runnerLogger.Error("Could not find branch.");
                                return new RepositoryImportResult(null, true);
                            }

                            currentBranch = Commands.Checkout(repo, localCommit);
                        }
                        else
                        {
                            currentBranch = Commands.Checkout(repo, branch);
                        }

                        runnerLogger.Information($"Check out complete. Result = {currentBranch != null}");

                        if (currentBranch != null)
                        {
                            return new RepositoryImportResult(path, false);
                        }
                        else
                        {
                            return new RepositoryImportResult(path, true);
                        }
                    }
                }
                catch (Exception exp)
                {
                    runnerLogger.Error(exp);

                    return new RepositoryImportResult(string.Empty, true);
                }
            }));
        }
        public Task <List <RepositoryCommit> > GetLastCommitsAsync(Project entity, AppConfiguration appConfiguration, IRepositoryAuthenticationInfo authInfo,
                                                                   CustomLogger runnerLogger,
                                                                   int count)
        {
            return(Task.Run(async() =>
            {
                var importResult = await ImportAsync(entity, appConfiguration, authInfo, runnerLogger);
                if (importResult.HasErrors)
                {
                    return null;
                }

                try
                {
                    List <RepositoryCommit> result = new List <RepositoryCommit>(0);

                    using (var repo = new Repository(importResult.CheckOutDirectory))
                    {
                        result = repo.Commits
                                 .Take(count)
                                 .Select(x => new RepositoryCommit(x.Id.Sha, x.Message, x.Author.When.UtcDateTime, $"{x.Author.Name} - {x.Author.Email}"))
                                 .ToList();
                    }

                    // Clean up. We no longer need the pository.
                    try
                    {
                        Directory.Delete(importResult.CheckOutDirectory, true);
                    }
                    catch (Exception exp)
                    {
                        runnerLogger.Error(exp);
                    }

                    return result;
                }
                catch (Exception exp)
                {
                    runnerLogger.Error(exp);

                    return null;
                }
            }));
        }
        public static async Task <RepositoryImportResult> ImportAsync(string projectName, string sourceRepoUrl, SourceCodeRepositoryType repoType, AppConfiguration appConfiguration, IRepositoryAuthenticationInfo authInfo,
                                                                      ReadOnlyCollection <IRepositoryImportStrategy> strategies)
        {
            if (authInfo != null)
            {
                if (await authInfo.Validate())
                {
                    Log.Information($"Validation for {nameof(authInfo)} did not pass.");

                    return(new RepositoryImportResult(string.Empty, true));
                }
            }

            var strategy = strategies.FirstOrDefault(x => x.Type == repoType);

            if (strategy == null)
            {
                Log.Error($"Unknown Source Code Import type: {repoType}");
                return(default);
        public Task <RepositoryImportResult> ImportAsync(Project entity, AppConfiguration appConfiguration, IRepositoryAuthenticationInfo authInfo, CustomLogger runnerLogger, string commitId = null)
        {
            return(Task.Run(() =>
            {
                var folderName = $"{entity.Name}_{DateTime.UtcNow.Ticks}";
                var path = Path.Combine(appConfiguration.BaseDirectory, folderName);

                var info = authInfo as AuthInfo;
                if (info == null)
                {
                    return new RepositoryImportResult(string.Empty, true);
                }

                try
                {
                    Directory.CreateDirectory(path);

                    using (var client = new SharpSvn.SvnClient())
                    {
                        client.Authentication.DefaultCredentials = new NetworkCredential(info.Username, info.Password);

                        runnerLogger.Information("Checking out...");

                        bool result = false;

                        if (commitId == null)
                        {
                            result = client.CheckOut(new SharpSvn.SvnUriTarget(entity.RepositoryUrl), path);
                        }
                        else
                        {
                            result = client.CheckOut(new SharpSvn.SvnUriTarget(entity.RepositoryUrl), path, new SharpSvn.SvnCheckOutArgs
                            {
                                Revision = new SharpSvn.SvnRevision(int.Parse(commitId))
                            });
                        }

                        runnerLogger.Information($"Check out complete. Result = {result}");
                    }

                    runnerLogger.Information(string.Empty);

                    return new RepositoryImportResult(path, false);
                }
                catch (Exception exp)
                {
                    runnerLogger.Error(exp);

                    return new RepositoryImportResult(string.Empty, true);
                }
            }));
        }
        public Task <List <RepositoryCommit> > GetLastCommitsAsync(Project entity, AppConfiguration appConfiguration, IRepositoryAuthenticationInfo authInfo, CustomLogger runnerLogger, int count)
        {
            return(Task.Run(async() =>
            {
                var info = authInfo as AuthInfo;
                if (info == null)
                {
                    return null;
                }

                try
                {
                    var checkoutResult = await ImportAsync(entity, appConfiguration, authInfo, runnerLogger);
                    if (checkoutResult.HasErrors)
                    {
                        return null;
                    }

                    List <RepositoryCommit> result = null;
                    using (var client = new SharpSvn.SvnClient())
                    {
                        //client.Authentication.DefaultCredentials = new NetworkCredential(info.Username, info.Password);

                        if (client.GetLog(checkoutResult.CheckOutDirectory, new SharpSvn.SvnLogArgs()
                        {
                            Limit = count
                        }, out var items))
                        {
                            result = items
                                     .Select(x => new RepositoryCommit(x.Revision.ToString(), x.LogMessage, x.Time.ToUniversalTime(), $"{x.Author}"))
                                     .ToList();
                        }
                    }

                    try
                    {
                        // Clean up the directory.
                        Directory.Delete(checkoutResult.CheckOutDirectory, recursive: true);
                    }
                    catch (Exception exp)
                    {
                        runnerLogger.Error(exp);
                    }

                    return result;
                }
                catch (Exception exp)
                {
                    runnerLogger.Error(exp);

                    return null;
                }
            }));
        }