public async Task GitPullFromRepositoryAsync(string repositoryPath, string localDir, string branch, CancellationToken cancel = default) { string gitUrl = this.Settings.GitLabBaseUrl._CombineUrl(repositoryPath + ".git").ToString(); gitUrl = gitUrl._ReplaceStr("https://", $"https://*****:*****@"); await Lfs.CreateDirectoryAsync(localDir); // localDir ディレクトリに .git ディレクトリは存在するか? string dotgitDir = localDir._CombinePath(".git"); bool init = false; StrDictionary <string> envVars = new StrDictionary <string>(); // empty config string emptyCfgPath = Env.MyLocalTempDir._CombinePath("empty.txt"); using (await Lock1.LockWithAwait(cancel)) { if (await Lfs.IsFileExistsAsync(emptyCfgPath, cancel) == false) { await Lfs.WriteStringToFileAsync(emptyCfgPath, "\n\n", cancel : cancel); } } envVars.Add("GIT_CONFIG_GLOBAL", emptyCfgPath); envVars.Add("GIT_CONFIG_SYSTEM", emptyCfgPath); if (await Lfs.IsDirectoryExistsAsync(dotgitDir, cancel)) { try { // update を試みる await EasyExec.ExecAsync(this.GitExe, $"pull origin {branch}", localDir, cancel : cancel, additionalEnvVars : envVars); } catch (Exception ex) { ex._Error(); init = true; } } else { init = true; } if (init) { // 初期化する await Lfs.DeleteDirectoryAsync(localDir, true, cancel : cancel, forcefulUseInternalRecursiveDelete : true); // git clone をする await EasyExec.ExecAsync(this.GitExe, $"clone {gitUrl} {localDir}", cancel : cancel, additionalEnvVars : envVars); // update を試みる await EasyExec.ExecAsync(this.GitExe, $"pull origin {branch}", localDir, cancel : cancel, additionalEnvVars : envVars); } }
// Git リポジトリの自動ダウンロード async Task Loop2_MainteUsersAsync(CancellationToken cancel = default) { long lastHookTick = -1; while (cancel.IsCancellationRequested == false) { try { await Lfs.CreateDirectoryAsync(this.Settings.GitMirrorDataRootDir); await Lfs.CreateDirectoryAsync(this.Settings.GitWebDataRootDir); } catch { } try { // Git リポジトリを列挙 var projects = await this.GitLabClient.EnumProjectsAsync(cancel); ConcurrentHashSet <string> dirNames = new ConcurrentHashSet <string>(StrCmpi); // メモ: last_activity_at の値を信用してはならない。これは GitLab がキャッシュしているので、なかなか更新されない。 var targetProjects = projects.Where(p => p.empty_repo == false && p.path_with_namespace._IsFilled() && p.default_branch._IsFilled() && p.visibility._IsDiffi("private")).OrderByDescending(x => x.last_activity_at).ThenBy(x => x.path_with_namespace, StrCmpi); await TaskUtil.ForEachAsync(8, targetProjects, async (proj, index, cancel) => { cancel.ThrowIfCancellationRequested(); try { string dirname = proj.GenerateDirName(); dirNames.Add(dirname); string gitRoot = this.Settings.GitMirrorDataRootDir._CombinePath(dirname); string webRoot = this.Settings.GitWebDataRootDir._CombinePath(dirname); await this.GitLabClient.GitPullFromRepositoryAsync(proj.path_with_namespace !, gitRoot, proj.default_branch !, cancel); await this.SyncGitLocalRepositoryDirToWebRootDirAsync(gitRoot, webRoot, cancel); } catch (Exception ex) { ex._Error(); } }, cancel); // GitLab 上に存在せず local に存在する gitRoot を列挙して削除する var existingLocalGitDirs = await Lfs.EnumDirectoryAsync(this.Settings.GitMirrorDataRootDir, cancel : cancel); foreach (var d in existingLocalGitDirs.Where(x => x.IsDirectory && dirNames.Contains(x.Name) == false)) { cancel.ThrowIfCancellationRequested(); try { await Lfs.DeleteDirectoryAsync(d.FullPath, true, cancel, true); } catch { } } // GitLab 上に存在せず local に存在する webRoot を列挙して削除する var existingLocalWebDirs = await Lfs.EnumDirectoryAsync(this.Settings.GitWebDataRootDir, cancel : cancel); foreach (var d in existingLocalWebDirs.Where(x => x.IsDirectory && dirNames.Contains(x.Name) == false)) { cancel.ThrowIfCancellationRequested(); try { await Lfs.DeleteFileAsync(d.FullPath._CombinePath(Consts.FileNames.LogBrowserSecureJson), cancel : cancel); } catch { } } } catch (Exception ex) { ex._Error(); } await TaskUtil.AwaitWithPollAsync(this.Settings.ForceRepositoryUpdateIntervalMsecs, 500, () => { long currentHookTick = this.HookFiredTick; if (lastHookTick != currentHookTick) { lastHookTick = currentHookTick; return(true); } return(false); }, cancel, true); } }