/// <inheritdoc /> public override void Initialize() { string cacheUri; if (FileSystemLocal.IsLocalPath(Uri)) { Uri = Regex.Replace(Uri, @"[\\/]\.git/?$", string.Empty); repositoryDirectory = Uri; cacheUri = Path.GetFullPath(Uri); } else { var cacheVcsDir = Config.Get(Settings.CacheVcsDir); if (!CacheFileSystem.IsUsable(cacheVcsDir)) { throw new RuntimeException("DriverGit requires a usable cache directory, and it looks like you set it to be disabled."); } if (Regex.IsMatch("^ssh://[^@]+@[^:]+:[^0-9]+", Uri)) { throw new InvalidArgumentException($"The source URL {Uri} is invalid, ssh URLs should have a port number after \":\".{Environment.NewLine}Use ssh://[email protected]:22/path or just [email protected]:path if you do not want to provide a password or custom port."); } Git.CleanEnvironment(); var fileSystem = new FileSystemLocal($"{cacheVcsDir}/{CacheFileSystem.FormatCacheFolder(Uri)}/"); var git = new Git(IO, Config, Process, fileSystem); repositoryDirectory = fileSystem.Root; if (!git.SyncMirror(Uri, repositoryDirectory)) { IO.WriteError($"<error>Failed to update {Uri}, package information from this repository may be outdated</error>"); } cacheUri = Uri; } GetTags(); GetBranches(); cache = new CacheFileSystem($"{Config.Get(Settings.CacheRepoDir)}/{CacheFileSystem.FormatCacheFolder(cacheUri)}", IO); }
/// <inheritdoc /> protected override void DoInstall(IPackage package, string cwd, string uri) { Git.CleanEnvironment(); cwd = NormalizePath(cwd); var cachePath = Config.Get(Settings.CacheVcsDir) + $"/{CacheFileSystem.FormatCacheFolder(uri)}/"; var reference = package.GetSourceReference(); var flag = Platform.IsWindows ? "/D " : string.Empty; // --dissociate option is only available since git 2.3.0-rc0 var gitVersion = git.GetVersion(); var message = $"Cloning {GetShortHash(reference)}"; var command = $"git clone --no-checkout %uri% %path% && cd {flag}%path% && git remote add bucket %uri% && git fetch bucket"; if (!string.IsNullOrEmpty(gitVersion) && Comparator.GreaterThanOrEqual(gitVersion, "2.3.0-rc0") && CacheFileSystem.IsUsable(cachePath)) { IO.WriteError(string.Empty, true, Verbosities.Debug); IO.WriteError($" Cloning to cache at {ProcessExecutor.Escape(cachePath)}", true, Verbosities.Debug); try { git.FetchReferenceOrSyncMirror(uri, reference, cachePath); if (FileSystem.Exists(cachePath, FileSystemOptions.Directory)) { command = "git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath%" + $" && cd {flag}%path%" + " && git remote set-url origin %uri% && git remote add bucket %uri%"; message = $"Cloning {GetShortHash(reference)} from cache."; } } catch (RuntimeException) { // ignore runtime exception because this is an optimization solution. } } IO.WriteError(message); string CommandCallable(string authUri) { var template = command; template = template.Replace("%uri%", ProcessExecutor.Escape(authUri)); template = template.Replace("%path%", ProcessExecutor.Escape(cwd)); template = template.Replace("%cachePath%", ProcessExecutor.Escape(cachePath)); return(template); } git.ExecuteCommand(CommandCallable, uri, cwd, true); if (uri != package.GetSourceUri()) { UpdateOriginUri(package.GetSourceUri(), cwd); } else { SetPushUri(uri, cwd); } ExecuteUpdate(cwd, reference, package); }