private TempDirectory(string path, TempRoot root) { NullableDebug.Assert(path != null); NullableDebug.Assert(root != null); _path = path; _root = root; }
public Reader(string gitDirectory, string commonDirectory, GitEnvironment environment, Func <string, TextReader>?fileOpener = null) { NullableDebug.Assert(environment != null); _environment = environment; _gitDirectoryPosix = PathUtils.ToPosixDirectoryPath(gitDirectory); _commonDirectory = commonDirectory; _fileOpener = fileOpener ?? File.OpenText; }
internal GitIgnore(PatternGroup?root, string workingDirectory, bool ignoreCase) { NullableDebug.Assert(PathUtils.IsAbsolute(workingDirectory)); IgnoreCase = ignoreCase; WorkingDirectory = PathUtils.ToPosixDirectoryPath(workingDirectory); _workingDirectoryNoSlash = PathUtils.TrimTrailingSlash(WorkingDirectory); Root = root; }
public PatternGroup(PatternGroup?parent, string containingDirectory, ImmutableArray <Pattern> patterns) { NullableDebug.Assert(PathUtils.IsPosixPath(containingDirectory)); NullableDebug.Assert(PathUtils.HasTrailingSlash(containingDirectory)); Parent = parent; ContainingDirectory = containingDirectory; Patterns = patterns; }
internal static Uri?NormalizeUrl(GitRepository repository, string url) { // Git (v2.23.0) treats local relative URLs as relative to the working directory. // This doesn't work when a relative URL is used in a config file locatede in a main .git directory // but is resolved from a worktree that has a different working directory. // Currently we implement the same behavior as git. NullableDebug.Assert(repository.WorkingDirectory != null); return(NormalizeUrl(ApplyInsteadOfUrlMapping(repository.Config, url), root: repository.WorkingDirectory)); }
internal GitRepositoryLocation(string gitDirectory, string commonDirectory, string?workingDirectory) { NullableDebug.Assert(PathUtils.IsNormalized(gitDirectory)); NullableDebug.Assert(PathUtils.IsNormalized(commonDirectory)); NullableDebug.Assert(workingDirectory == null || PathUtils.IsNormalized(workingDirectory)); GitDirectory = gitDirectory; CommonDirectory = commonDirectory; WorkingDirectory = workingDirectory; }
public GitVariableName(string sectionName, string subsectionName, string variableName) { NullableDebug.Assert(sectionName != null); NullableDebug.Assert(subsectionName != null); NullableDebug.Assert(variableName != null); SectionName = sectionName; SubsectionName = subsectionName; VariableName = variableName; }
private protected override void Execute(GitRepository repository) { NullableDebug.Assert(repository.WorkingDirectory != null); RepositoryId = repository.GitDirectory; WorkingDirectory = repository.WorkingDirectory; Url = GitOperations.GetRepositoryUrl(repository, RemoteName, Log.LogWarning); Roots = GitOperations.GetSourceRoots(repository, RemoteName, Log.LogWarning); RevisionId = repository.GetHeadCommitSha(); }
internal GitSubmodule(string name, string workingDirectoryRelativePath, string workingDirectoryFullPath, string?url, string?headCommitSha) { NullableDebug.Assert(name != null); NullableDebug.Assert(workingDirectoryRelativePath != null); NullableDebug.Assert(workingDirectoryFullPath != null); Name = name; WorkingDirectoryRelativePath = workingDirectoryRelativePath; WorkingDirectoryFullPath = workingDirectoryFullPath; Url = url; HeadCommitSha = headCommitSha; }
public static bool TryParseHostedSsh(Uri uri, [NotNullWhen(true)] out string?account, [NotNullWhen(true)] out string?repositoryPath, [NotNullWhen(true)] out string?repositoryName) { NullableDebug.Assert(uri != null); account = repositoryPath = repositoryName = null; // {"DefaultCollection"|""}/{repositoryPath}/"_ssh"/{"_full"|"_optimized"}/{repositoryName} if (!UriUtilities.TrySplitRelativeUrl(uri.GetPath(), out var parts) || parts.Length == 0) { return(false); } // Check for v3 url format if (parts[0] == "v3" && parts.Length >= 3 && TryParsePath(parts, 2, type: null, out repositoryPath, out repositoryName) && repositoryPath != "") { // ssh://{user}@{domain}:{port}/v3/{account}/{repositoryPath}/{'_full'|'_optimized'|''}/{repositoryName} account = parts[1]; } else { // ssh v1/v2 url formats // ssh://{account}@vs-ssh.visualstudio.com/ account = uri.UserInfo; int index = 0; if (StringComparer.OrdinalIgnoreCase.Equals(parts[0], "DefaultCollection")) { index++; } if (!TryParsePath(parts, index, "_ssh", out repositoryPath, out repositoryName)) { // Failed to parse path return(false); } } if (account.Length == 0) { return(false); } return(true); }
internal static DirectoryNode BuildDirectoryTree(GitRepository repository, Func <GitEnvironment, string, GitRepository?> repositoryFactory) { NullableDebug.Assert(repository.WorkingDirectory != null); var treeRoot = new DirectoryNode(name: "", new List <DirectoryNode>()); AddTreeNode(treeRoot, repository.WorkingDirectory, new Lazy <GitIgnore.Matcher?>(() => repository.Ignore.CreateMatcher())); foreach (var submodule in repository.GetSubmodules()) { var submoduleWorkingDirectory = submodule.WorkingDirectoryFullPath; AddTreeNode(treeRoot, submoduleWorkingDirectory, new Lazy <GitIgnore.Matcher?>(() => repositoryFactory(repository.Environment, submoduleWorkingDirectory)?.Ignore.CreateMatcher())); } return(treeRoot); }
private static string?GetRepositoryUrl(GitRepository repository, string?remoteName, int recursionDepth, Action <string, object?[]>?logWarning = null) { NullableDebug.Assert(repository.WorkingDirectory != null); var remoteUrl = GetRemoteUrl(repository, ref remoteName, logWarning); if (remoteUrl == null) { return(null); } var uri = NormalizeUrl(repository, remoteUrl); if (uri == null) { logWarning?.Invoke(Resources.InvalidRepositoryRemoteUrl, new[] { remoteName, remoteUrl }); return(null); } return(ResolveUrl(uri, repository.Environment, remoteName, recursionDepth, logWarning)); }
public GitConfig(ImmutableDictionary <GitVariableName, ImmutableArray <string> > variables) { NullableDebug.Assert(variables != null); Variables = variables; }
public static ITaskItem[] GetSourceRoots(GitRepository repository, string?remoteName, Action <string, object?[]> logWarning) { // Not supported for repositories without a working directory. NullableDebug.Assert(repository.WorkingDirectory != null); var result = new List <TaskItem>(); var repoRoot = repository.WorkingDirectory.EndWithSeparator(); var revisionId = repository.GetHeadCommitSha(); if (revisionId != null) { // Don't report a warning since it has already been reported by GetRepositoryUrl task. string?repositoryUrl = GetRepositoryUrl(repository, remoteName, logWarning: null); // Item metadata are stored msbuild-escaped. GetMetadata unescapes, SetMetadata stores the value as specified. // Escape msbuild special characters so that URL escapes in the URL are preserved when the URL is read by GetMetadata. var item = new TaskItem(Evaluation.ProjectCollection.Escape(repoRoot)); item.SetMetadata(Names.SourceRoot.SourceControl, SourceControlName); item.SetMetadata(Names.SourceRoot.ScmRepositoryUrl, Evaluation.ProjectCollection.Escape(repositoryUrl)); item.SetMetadata(Names.SourceRoot.RevisionId, revisionId); result.Add(item); } else { logWarning(Resources.RepositoryHasNoCommit, Array.Empty <object>()); } foreach (var submodule in repository.GetSubmodules()) { var commitSha = submodule.HeadCommitSha; if (commitSha == null) { logWarning(Resources.SourceCodeWontBeAvailableViaSourceLink, new[] { string.Format(Resources.SubmoduleWithoutCommit, new[] { submodule.Name }) }); continue; } // submodule.<name>.url specifies where to find the submodule. // This variable is calculated based on the entry in .gitmodules by git submodule init and will be present for initialized submodules. // Uninitialized modules don't have source that should be considered during the build. // Relative URLs are relative to the repository directory. // See https://git-scm.com/docs/gitsubmodules. var submoduleConfigUrl = repository.Config.GetVariableValue(SubmoduleSectionName, submodule.Name, UrlVariableName); if (submoduleConfigUrl == null) { continue; } var submoduleUri = NormalizeUrl(repository, submoduleConfigUrl); if (submoduleUri == null) { logWarning(Resources.SourceCodeWontBeAvailableViaSourceLink, new[] { string.Format(Resources.InvalidSubmoduleUrl, submodule.Name, submoduleConfigUrl) }); continue; } var submoduleUrl = ResolveUrl(submoduleUri, repository.Environment, remoteName, recursionDepth: 0, logWarning); if (submoduleUrl == null) { logWarning(Resources.SourceCodeWontBeAvailableViaSourceLink, new[] { string.Format(Resources.InvalidSubmoduleUrl, submodule.Name, submoduleConfigUrl) }); continue; } // Item metadata are stored msbuild-escaped. GetMetadata unescapes, SetMetadata stores the value as specified. // Escape msbuild special characters so that URL escapes and non-ascii characters in the URL and paths are // preserved when read by GetMetadata. var item = new TaskItem(Evaluation.ProjectCollection.Escape(submodule.WorkingDirectoryFullPath.EndWithSeparator())); item.SetMetadata(Names.SourceRoot.SourceControl, SourceControlName); item.SetMetadata(Names.SourceRoot.ScmRepositoryUrl, Evaluation.ProjectCollection.Escape(submoduleUrl)); item.SetMetadata(Names.SourceRoot.RevisionId, commitSha); item.SetMetadata(Names.SourceRoot.ContainingRoot, Evaluation.ProjectCollection.Escape(repoRoot)); item.SetMetadata(Names.SourceRoot.NestedRoot, Evaluation.ProjectCollection.Escape(submodule.WorkingDirectoryRelativePath.EndWithSeparator('/'))); result.Add(item); } foreach (var diagnostic in repository.GetSubmoduleDiagnostics()) { logWarning(Resources.SourceCodeWontBeAvailableViaSourceLink, new[] { diagnostic }); } return(result.ToArray()); }