Пример #1
0
        public void Convert_CreateToManyFromGenericStrategyWithReverseRelation_Successful()
        {
            // Arrange
            container.Bind(typeof(IGenericStrategyProvider <,>)).To(typeof(GenericStrategyProvider <,>));
            container.Bind <IConvertRegistrations <SourceRoot, TargetRoot, IForTest> >().To <CreateToManyFromGenericStrategyWithReverseRelationRegistrations>();
            container.Bind <IConvertRegistrations <SourceDerivedLeaf, TargetDerivedLeaf, IForTest> >().To <DerivedLeafToTargetDerivedLeafConvertRegistrations>();
            container.Bind <ICreateByBaseAsCriterionStrategy <SourceBaseLeaf, TargetBaseLeaf> >().To <GenericCreateByBaseAsCriterionStrategy <SourceBaseLeaf, SourceDerivedLeaf, TargetBaseLeaf, TargetDerivedLeaf, TargetDerivedLeaf> >();
            container.Bind <ISourceConvertStrategy <SourceBaseLeaf, TargetBaseLeaf, IForTest> >().To <GenericSourceConvertStrategy <SourceBaseLeaf, TargetBaseLeaf, IForTest, SourceDerivedLeaf, TargetDerivedLeaf> >();

            var converter = GetConverter <SourceRoot, TargetRoot>();

            var sourceRoot = new SourceRoot();

            sourceRoot.Leafs.Add(new SourceDerivedLeaf()
            {
                Root = sourceRoot
            });
            sourceRoot.Leafs.Add(new SourceDerivedLeaf()
            {
                Root = sourceRoot
            });

            var targetRoot = new TargetRoot();

            // Act
            var processings = new List <IBaseAdditionalProcessing>();

            converter.Convert(sourceRoot, targetRoot, processings);

            // Assert
            targetRoot.TargetLeafs.Count.Should().Be(sourceRoot.Leafs.Count);
        }
        public void PostProcessing_ExecutesPostprocessing()
        {
            var testCandidate = new ConvertHelper();

            var source = new SourceRoot();
            var target = new TargetRoot();

            var postprocShouldExecute = new Mock <IConvertPostProcessing <SourceRoot, TargetRoot> >();
            var postprocShouldNotExecuteBecauseWrongSource         = new Mock <IConvertPostProcessing <SourceTreeLeaf, TargetRoot> >();
            var postprocShouldNotExecuteBecauseWrongProcessingType = new Mock <IConvertPreProcessing <SourceRoot, TargetRoot> >();

            postprocShouldExecute.Setup(x => x.DoPostProcessing(source, target));
            postprocShouldNotExecuteBecauseWrongSource.Setup(x => x.DoPostProcessing(It.IsAny <SourceTreeLeaf>(), target));
            postprocShouldNotExecuteBecauseWrongProcessingType.Setup(x => x.DoPreProcessing(source, target));

            var postprocessings = new List <IBaseAdditionalProcessing>
            {
                postprocShouldExecute.Object,
                postprocShouldNotExecuteBecauseWrongSource.Object,
                postprocShouldNotExecuteBecauseWrongProcessingType.Object,
            };

            testCandidate.DoConvertPostProcessing(source, target, postprocessings);

            postprocShouldExecute.Verify(x => x.DoPostProcessing(source, target), Times.Once);
            postprocShouldNotExecuteBecauseWrongSource.Verify(x => x.DoPostProcessing(It.IsAny <SourceTreeLeaf>(), target), Times.Never);
            postprocShouldNotExecuteBecauseWrongProcessingType.Verify(x => x.DoPreProcessing(source, target), Times.Never);
        }
Пример #3
0
        public void Convert_RegisterCreateToOneWithRelationAndTarget_Successful()
        {
            // Arrange
            container.Bind <IConvertRegistrations <SourceRoot, TargetRoot, IForTest> >().To <CreateToOneWithRelationAndTargetRegistrations>();
            container.Bind <IConvertRegistrations <IdDto, TargetTree, IForTest> >().To <CopyIdDtoToTargetTreeRegistrations>();

            var converter = GetConverter <SourceRoot, TargetRoot>();

            var sourceRoot = new SourceRoot()
            {
                Tree = new SourceTree(),
            };
            var targetRoot = new TargetRoot()
            {
                Id = Guid.NewGuid(),
            };

            // Act
            var processings = new List <IBaseAdditionalProcessing>();

            converter.Convert(sourceRoot, targetRoot, processings);

            // Assert
            targetRoot.TargetTree.Should().NotBeNull();
            targetRoot.TargetTree.RelationOnTarget.Should().Be(targetRoot.RelationOnTarget);
            targetRoot.TargetTree.TemporalDataOriginId.Should().Be(targetRoot.Id);
        }
Пример #4
0
        private static void AssertRoot(SourceRoot sourceRoot, TargetRoot targetRoot)
        {
            targetRoot.OriginRoot.Should().Be(sourceRoot);
            targetRoot.Name.Should().Be(sourceRoot.Name);
            targetRoot.RootId.Should().Be(sourceRoot.Id);
            targetRoot.Id.Should().Be(sourceRoot.Id);
            targetRoot.TargetId.Should().Be(sourceRoot.Id);
            targetRoot.NumberSourceDefault.Should().NotBe(sourceRoot.NumberSourceDefault);
            targetRoot.NumberSourceNotDefault.Should().Be(sourceRoot.NumberSourceNotDefault);
            targetRoot.NumberTargetDefault.Should().Be(sourceRoot.NumberTargetDefault);
            targetRoot.NumberTargetNotDefault.Should().NotBe(sourceRoot.NumberTargetNotDefault);
            targetRoot.NumberSourceLookedUp.Should().Be(sourceRoot.NumberSourceNotDefault);
            targetRoot.NumberSourceNotLookedUp.Should().Be(sourceRoot.NumberSourceNotDefault);

            // ToDo: Check is this a bug? see https://github.com/bbtsoftware/BBT.StructureTools/issues/65.
            // targetRoot.NumberLimitNotApplied.Should().Be(sourceRoot.NumberSourceDefault);
            targetRoot.NumberLimitApplied.Should().NotBe(sourceRoot.NumberSourceNotDefault);
            targetRoot.EnumValue.Should().Be(sourceRoot.EnumValue.Target);
            targetRoot.FilteredHist.Should().Be(sourceRoot.Tree.ExpectedFilteredHist);
            ((TargetDerivedLeaf)targetRoot.TargetLeaf).OriginId.Should().Be(((SourceDerivedLeaf)sourceRoot.Leaf).Id);

            targetRoot.TargetMasterData.OriginId.Should().Be(sourceRoot.ExpectedFilteredMasterData.Id);
            targetRoot.TargetMasterData.IsDefault.Should().Be(sourceRoot.ExpectedFilteredMasterData.IsDefault);
            targetRoot.FilteredMasterDataId.Should().Be(sourceRoot.ExpectedFilteredMasterData.Id);

            AssertTree(sourceRoot, targetRoot);
        }
Пример #5
0
        public void Convert_RegisterCreateToOneWithRelation_Successful()
        {
            // Arrange
            container.Bind <IConvertRegistrations <SourceRoot, TargetRoot, IForTest> >().To <CreateToOneWithRelationRegistrations>();
            container.Bind <IConvertRegistrations <SourceTree, TargetTree, IForTest> >().To <CopyTreeAttributeRegistrations>();
            container.Bind(typeof(ICreateTargetImplConvertTargetHelperFactory <, , ,>)).To(typeof(CreateTargetImplConvertTargetHelperFactory <, , ,>));
            container.Bind(typeof(ICreateTargetImplConvertTargetHelper <, , , ,>)).To(typeof(CreateTargetImplConvertTargetHelper <, , , ,>));

            var converter = GetConverter <SourceRoot, TargetRoot>();

            var sourceRoot = new SourceRoot()
            {
                Tree = new SourceTree(),
            };
            var targetRoot = new TargetRoot();

            // Act
            var processings = new List <IBaseAdditionalProcessing>();

            converter.Convert(sourceRoot, targetRoot, processings);

            // Assert
            targetRoot.TargetTree.Should().NotBeNull();
            targetRoot.TargetTree.RelationOnTarget.Should().Be(targetRoot.RelationOnTarget);
        }
        public void Intercept_WithEmptyist_Succeeds()
        {
            var testCandidate  = new ConvertHelper();
            var preprocessings = new List <IBaseAdditionalProcessing>();

            var source = new SourceRoot();

            testCandidate.ContinueConvertProcess <SourceRoot, TargetRoot>(source, preprocessings);
        }
        public void PostProcessing_WithEmptyist_Succeeds()
        {
            var testCandidate  = new ConvertHelper();
            var preprocessings = new List <IBaseAdditionalProcessing>();

            var source = new SourceRoot();
            var target = new TargetRoot();

            testCandidate.DoConvertPostProcessing(source, target, preprocessings);
        }
Пример #8
0
        private void ExecuteImpl()
        {
            // skip SourceRoot that already has SourceLinkUrl set, or its SourceControl is not "git":
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) ||
                !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            var repoUrl = SourceRoot.GetMetadata(Names.SourceRoot.RepositoryUrl);

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError(Resources.ValueOfWithIdentityIsInvalid, Names.SourceRoot.RepositoryUrlFullName, SourceRoot.ItemSpec, repoUrl);
                return;
            }

            var mappings   = GetUrlMappings().ToArray();
            var contentUri = GetMatchingContentUri(mappings, repoUri.Host);

            if (contentUri == null)
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            bool IsHexDigit(char c)
            => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';

            string revisionId = SourceRoot.GetMetadata(Names.SourceRoot.RevisionId);

            if (revisionId == null || revisionId.Length != 40 || !revisionId.All(IsHexDigit))
            {
                Log.LogError(Resources.ValueOfWithIdentityIsNotValidCommitHash, Names.SourceRoot.RevisionIdFullName, SourceRoot.ItemSpec, revisionId);
                return;
            }

            var relativeUrl = repoUri.LocalPath.TrimEnd('/');

            // The URL may or may not end with '.git', but raw.githubusercontent.com does not accept '.git' suffix:
            const string gitUrlSuffix = ".git";

            if (relativeUrl.EndsWith(gitUrlSuffix))
            {
                relativeUrl = relativeUrl.Substring(0, relativeUrl.Length - gitUrlSuffix.Length);
            }

            SourceLinkUrl = new Uri(contentUri, relativeUrl).ToString() + "/" + revisionId + "/*";
        }
        public override bool Execute()
        {
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata("SourceLinkUrl")) ||
                !string.Equals(SourceRoot.GetMetadata("SourceControl"), "tfvc", StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = "N/A";
                return(true);
            }

            var collectionUrl = SourceRoot.GetMetadata("CollectionUrl");

            if (!Uri.TryCreate(collectionUrl, UriKind.Absolute, out var collectionUri))
            {
                Log.LogError($"SourceRoot.CollectionUrl of '{SourceRoot.ItemSpec}' is invalid: '{collectionUrl}'");
                return(false);
            }

            // 'D' format: "effb7e66-f922-4dc9-a4dc-9bd5d3b01582"
            var projectIdStr = SourceRoot.GetMetadata("ProjectId");

            if (!Guid.TryParseExact(projectIdStr, "D", out var projectId))
            {
                Log.LogError($"SourceRoot.ProjectId of '{SourceRoot.ItemSpec}' is invalid: '{projectIdStr}'");
                return(false);
            }

            string revisionIdStr = SourceRoot.GetMetadata("RevisionId");

            if (revisionIdStr == null || !uint.TryParse(revisionIdStr, out var revisionId))
            {
                Log.LogError($"SourceRoot.RevisionId of '{SourceRoot.ItemSpec}' is not a valid changeset number: '{revisionIdStr}'");
                return(false);
            }

            string serverPath = SourceRoot.GetMetadata("ServerPath");

            if (serverPath == null || !serverPath.StartsWith("$", StringComparison.Ordinal))
            {
                Log.LogError($"SourceRoot.ServerPath of '{SourceRoot.ItemSpec}' is not a valid server path: '{revisionIdStr}'");
                return(false);
            }

            var escapedServerPath = string.Join("/", serverPath.Split('/').Select(Uri.EscapeDataString));

            SourceLinkUrl = new Uri(collectionUri, projectId.ToString("D")).ToString() +
                            "/_versionControl?version=" + revisionId + "&path=" + escapedServerPath + "/*";

            return(true);
        }
Пример #10
0
        private string GetSourceLinkQuery()
        {
            bool IsHexDigit(char c)
            => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';

            string revisionId = SourceRoot.GetMetadata(Names.SourceRoot.RevisionId);

            if (revisionId == null || revisionId.Length != 40 || !revisionId.All(IsHexDigit))
            {
                Log.LogError(Resources.ValueOfWithIdentityIsNotValidCommitHash, Names.SourceRoot.RevisionIdFullName, SourceRoot.ItemSpec, revisionId);
                return(null);
            }

            return($"api-version=1.0&versionType=commit&version={revisionId}&path=/*");
        }
Пример #11
0
        public override bool Execute()
        {
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata("SourceLinkUrl")) ||
                !string.Equals(SourceRoot.GetMetadata("SourceControl"), "git", StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = "N/A";
                return(true);
            }

            var repoUrl = SourceRoot.GetMetadata("RepositoryUrl");

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError($"SourceRoot.RepositoryUrl of '{SourceRoot.ItemSpec}' is invalid: '{repoUrl}'");
                return(false);
            }

            if (!repoUri.Host.Equals("github.com", StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = "N/A";
                return(true);
            }

            bool IsHexDigit(char c)
            => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';

            string revisionId = SourceRoot.GetMetadata("RevisionId");

            if (revisionId == null || revisionId.Length != 40 || !revisionId.All(IsHexDigit))
            {
                Log.LogError($"SourceRoot.RevisionId of '{SourceRoot.ItemSpec}' is not a valid commit hash: '{revisionId}'");
                return(false);
            }

            var relativeUrl = repoUri.LocalPath.TrimEnd('/');

            // The URL may or may not end with '.git', but raw.githubusercontent.com does not accept '.git' suffix:
            const string gitUrlSuffix = ".git";

            if (relativeUrl.EndsWith(gitUrlSuffix))
            {
                relativeUrl = relativeUrl.Substring(0, relativeUrl.Length - gitUrlSuffix.Length);
            }

            SourceLinkUrl = new Uri(s_rawGitHub, relativeUrl).ToString() + "/" + revisionId + "/*";
            return(true);
        }
Пример #12
0
        private void ExecuteImpl()
        {
            // skip SourceRoot that already has SourceLinkUrl set, or its SourceControl is not "git":
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) ||
                !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            var gitUrl = SourceRoot.GetMetadata(Names.SourceRoot.RepositoryUrl);

            if (string.IsNullOrEmpty(gitUrl))
            {
                SourceLinkUrl = NotApplicableValue;
                Log.LogWarning(CommonResources.UnableToDetermineRepositoryUrl);
                return;
            }

            if (!Uri.TryCreate(gitUrl, UriKind.Absolute, out var gitUri))
            {
                Log.LogError(CommonResources.ValueOfWithIdentityIsInvalid, Names.SourceRoot.RepositoryUrlFullName, SourceRoot.ItemSpec, gitUrl);
                return;
            }

            var mappings = GetUrlMappings(gitUri).ToArray();

            if (Log.HasLoggedErrors)
            {
                return;
            }

            if (mappings.Length == 0)
            {
                Log.LogError(CommonResources.AtLeastOneRepositoryHostIsRequired, HostsItemGroupName, ProviderDisplayName);
                return;
            }

            var contentUri = GetMatchingContentUri(mappings, gitUri, out var hostItem);

            if (contentUri == null)
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }
Пример #13
0
        private static void AssertTree(SourceRoot sourceRoot, TargetRoot targetRoot)
        {
            var sourceTree = sourceRoot.Tree;
            var targetTree = targetRoot.TargetTree;

            targetRoot.TargetTreeId.Should().Be(targetTree.Id);
            targetRoot.OriginTreeId.Should().Be(sourceTree.Id);
            targetRoot.TreeId.Should().Be(sourceTree.Id);
            targetTree.TargetRoot.Should().Be(targetRoot);
            targetTree.OriginTree.Should().Be(sourceRoot.Tree);
            targetTree.TreeName.Should().Be(sourceTree.TreeName);
            targetTree.MasterDataId.Should().Be(sourceTree.MasterData.Id);
            targetTree.TemporalDataOriginId.Should().Be(sourceTree.ExpectedFilteredHist.Id);
            targetTree.BaseDataId.Should().Be(sourceTree.BaseDataId);

            AssertTreeLeafs(sourceTree, targetTree);
            AssertTreeHistLeafs(sourceTree, targetTree);
        }
Пример #14
0
        public override bool Execute()
        {
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) ||
                !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = NotApplicableValue;
                return(true);
            }

            var repoUrl = SourceRoot.GetMetadata(Names.SourceRoot.RepositoryUrl);

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError(Resources.ValueOfOWithIdentityIsInvalid, Names.SourceRoot.RepositoryUrlFullName, SourceRoot.ItemSpec, repoUrl);
                return(false);
            }

            var map = TryGetStandardUriMap();

            if (map != null && map.TryGetValue(repoUri, out var mappedUri))
            {
                repoUri = mappedUri;
            }

            string domain = string.IsNullOrEmpty(Domain) ? DefaultDomain : Domain;

            if (!TryParseRepositoryUrl(repoUri, domain, out var projectName, out var repositoryName))
            {
                SourceLinkUrl = NotApplicableValue;
                return(true);
            }

            var query = GetSourceLinkQuery();

            if (query == null)
            {
                return(false);
            }

            SourceLinkUrl = $"{repoUri.Scheme}://{repoUri.Authority}/{projectName}/_apis/git/repositories/{repositoryName}/items?" + query;
            return(true);
        }
Пример #15
0
        public void Dispose()
        {
            // if we have a writer, output the JSON object now
            if (m_writer != null)
            {
                // if we want to add the cross-site script injection protection string,
                // do it now at the top of the file as it's own line
                if (SafeHeader)
                {
                    m_writer.WriteLine(")]}'");
                }

                // start the JSON object
                m_writer.WriteLine("{");

                WriteProperty("version", 3);
                WriteProperty("file", MakeRelative(m_minifiedPath, m_mapPath));

                // line number comes in zero-based, so add one to get the line count
                // lineCount is deprecated in the sourcemap specification, so stop outputting it
                //WriteProperty("lineCount", m_maxMinifiedLine + 1);

                WriteProperty("mappings", GenerateMappings(m_sourceFileList, m_nameList));

                // if we have a source root, add the property now
                if (!SourceRoot.IsNullOrWhiteSpace())
                {
                    WriteProperty("sourceRoot", SourceRoot);
                }

                WriteProperty("sources", m_sourceFileList);
                WriteProperty("names", m_nameList);

                // close the JSON object
                m_writer.WriteLine();
                m_writer.WriteLine("}");

                ((IDisposable)m_writer).Dispose();
                m_writer = null;
            }
        }
Пример #16
0
        public Source SelectSource(string cat)
        {
            string category = cat;
            string country  = "";

            List <Source> sourceList = null;

            HttpClient client = GetClient();

            //If no category is specified, a source for general news is returned
            HttpResponseMessage response = client.GetAsync($"?category={category}&country={country}&language=de&apiKey={apiKey}").Result;

            if (response.IsSuccessStatusCode)
            {
                SourceRoot root = response.Content.ReadAsAsync <SourceRoot>().Result;
                sourceList = root.Sources;
            }
            Source source = sourceList.FirstOrDefault();

            return(source);
        }
Пример #17
0
        public override bool Execute()
        {
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata("SourceLinkUrl")) ||
                !string.Equals(SourceRoot.GetMetadata("SourceControl"), "git", StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = "N/A";
                return(true);
            }

            var repoUrl = SourceRoot.GetMetadata("RepositoryUrl");

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError($"SourceRoot.RepositoryUrl of '{SourceRoot.ItemSpec}' is invalid: '{repoUrl}'");
                return(false);
            }

            if (!TryParseRepositoryUrl(repoUri, out var projectName, out var repositoryName))
            {
                SourceLinkUrl = "N/A";
                return(true);
            }

            bool IsHexDigit(char c)
            => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';

            string revisionId = SourceRoot.GetMetadata("RevisionId");

            if (revisionId == null || revisionId.Length != 40 || !revisionId.All(IsHexDigit))
            {
                Log.LogError($"SourceRoot.RevisionId of '{SourceRoot.ItemSpec}' is not a valid commit hash: '{revisionId}'");
                return(false);
            }

            SourceLinkUrl = $"{repoUri.Scheme}://{repoUri.Host}/{projectName}/_apis/git/repositories/{repositoryName}/items?api-version=1.0&versionType=commit&version={revisionId}&path=/*";
            return(true);
        }
Пример #18
0
 public override string ToString() => $@"{{""version"":""{Version}"",""sources"":{Sources.ToJsonArray()},""names"":{Names.ToJsonArray()},""mappings"":""{Mappings}""{File.TextOrEmpty($@",""file"":""{File}""")}{SourceRoot.TextOrEmpty($@",""sourceRoot"":""{SourceRoot}""")}{SourcesContent.TextOrEmpty($@",""sourcesContent"":{SourcesContent.ToJsonArray()}")}}}";
Пример #19
0
        private void ExecuteImpl()
        {
            // skip SourceRoot that already has SourceLinkUrl set, or its SourceControl is not "git":
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) ||
                !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            var repoUrl = SourceRoot.GetMetadata(Names.SourceRoot.RepositoryUrl);

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError(Resources.ValueOfWithIdentityIsInvalid, Names.SourceRoot.RepositoryUrlFullName, SourceRoot.ItemSpec, repoUrl);
                return;
            }

            var map = TryGetStandardUriMap();

            if (map != null && map.TryGetValue(repoUri, out var mappedUri))
            {
                repoUri = mappedUri;
            }

            string domain;

            if (string.IsNullOrEmpty(Domain))
            {
                domain = DefaultDomain;
            }
            else
            {
                bool isHostUri(Uri uri) => uri.PathAndQuery == "/" && uri.UserInfo == "";

                domain = Domain;
                if (!Uri.TryCreate("http://" + domain, UriKind.Absolute, out var domainUri) || !isHostUri(domainUri))
                {
                    Log.LogError(Resources.ValuePassedToTaskParameterNotValidDomainName, nameof(Domain), domain);
                    return;
                }
            }

            if (!TryParseRepositoryUrl(repoUri, domain, out var projectName, out var repositoryName, out var collectionName))
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            var query = GetSourceLinkQuery();

            if (query == null)
            {
                return;
            }

            // Although VSTS does not have non-default collections, TFS does.
            // This package can be used for both VSTS and TFS.
            string collectionPath = (collectionName == null || StringComparer.OrdinalIgnoreCase.Equals(collectionName, "DefaultCollection")) ? "" : "/" + collectionName;

            SourceLinkUrl = $"{repoUri.Scheme}://{repoUri.Authority}{collectionPath}/{projectName}/_apis/git/repositories/{repositoryName}/items?" + query;
        }
Пример #20
0
        public TestEnv(
            string name,
            string rootPath,
            bool enableLazyOutputMaterialization = false,
            int maxRelativeOutputDirectoryLength = 260,
            List <IMount> mounts = null,
            PathTable pathTable  = null)
        {
            Contract.Requires(name != null);
            Contract.Requires(!string.IsNullOrEmpty(rootPath));

            LoggingContext = new LoggingContext("TestLogger." + name);
            PathTable      = pathTable ?? new PathTable();

            PipDataBuilderPool = new ObjectPool <PipDataBuilder>(() => new PipDataBuilder(PathTable.StringTable), _ => { });

            // The tests that use TestEnv need to be modernized to take a filesystem
            var fileSystem = new PassThroughFileSystem(PathTable);

            Context = EngineContext.CreateNew(CancellationToken.None, PathTable, fileSystem);

            // Add some well-known paths with fixed casing to the Context.PathTable
            AbsolutePath.Create(Context.PathTable, rootPath.ToLowerInvariant());
            var root = AbsolutePath.Create(Context.PathTable, rootPath);

            var configuration = ConfigHelpers.CreateDefaultForXml(Context.PathTable, root);

            configuration.Layout.SourceDirectory = root.Combine(PathTable, PathAtom.Create(PathTable.StringTable, "src")); // These tests have non-standard src folder
            configuration.Engine.MaxRelativeOutputDirectoryLength   = maxRelativeOutputDirectoryLength;
            configuration.Schedule.EnableLazyOutputMaterialization  = enableLazyOutputMaterialization;
            configuration.Schedule.UnsafeDisableGraphPostValidation = false;
            configuration.Schedule.ComputePipStaticFingerprints     = true;
            configuration.Sandbox.FileAccessIgnoreCodeCoverage      = true;

            BuildXLEngine.PopulateFileSystemCapabilities(configuration, configuration, Context.PathTable, LoggingContext);
            BuildXLEngine.PopulateLoggingAndLayoutConfiguration(configuration, Context.PathTable, bxlExeLocation: null, inTestMode: true);
            BuildXLEngine.PopulateAndValidateConfiguration(configuration, configuration, Context.PathTable, LoggingContext);

            Configuration = configuration;

            var mountsTable = MountsTable.CreateAndRegister(LoggingContext, Context, Configuration, null);

            if (mounts != null)
            {
                foreach (var mount in mounts)
                {
                    mountsTable.AddResolvedMount(mount);
                }
            }

            AbsolutePath specFile = SourceRoot.CreateRelative(Context.PathTable, "TestSpecFile.dsc");

            var graph = TestSchedulerFactory.CreateEmptyPipGraph(Context, configuration, mountsTable.MountPathExpander);

            PipTable = graph.PipTable;
            PipGraph = graph;

            var locationData = new LocationData(specFile, 0, 0);
            var modulePip    = ModulePip.CreateForTesting(Context.StringTable, specFile);

            PipGraph.AddModule(modulePip);
            PipGraph.AddSpecFile(new SpecFilePip(FileArtifact.CreateSourceFile(specFile), locationData, modulePip.Module));

            PipConstructionHelper = PipConstructionHelper.CreateForTesting(
                Context,
                ObjectRoot,
                redirectedRoot: Configuration.Layout.RedirectedDirectory,
                pipGraph: PipGraph,
                moduleName: modulePip.Identity.ToString(Context.StringTable),
                symbol: name,
                specPath: specFile);

            Paths = new Paths(PathTable);

            mountsTable.CompleteInitialization();
        }
Пример #21
0
        private void ExecuteImpl()
        {
            // skip SourceRoot that already has SourceLinkUrl set, or its SourceControl is not "git":
            if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) ||
                !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase))
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            var repoUrl = SourceRoot.GetMetadata(Names.SourceRoot.RepositoryUrl);

            if (!Uri.TryCreate(repoUrl, UriKind.Absolute, out var repoUri))
            {
                Log.LogError(CommonResources.ValueOfWithIdentityIsInvalid, Names.SourceRoot.RepositoryUrlFullName, SourceRoot.ItemSpec, repoUrl);
                return;
            }

            var mappings = GetUrlMappings().ToArray();

            if (Log.HasLoggedErrors)
            {
                return;
            }

            if (mappings.Length == 0)
            {
                Log.LogError(CommonResources.AtLeastOneRepositoryHostIsRequired, HostsItemGroupName, ProviderDisplayName);
                return;
            }

            var contentUri = GetMatchingContentUri(mappings, repoUri);

            if (contentUri == null)
            {
                SourceLinkUrl = NotApplicableValue;
                return;
            }

            bool IsHexDigit(char c)
            => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';

            string revisionId = SourceRoot.GetMetadata(Names.SourceRoot.RevisionId);

            if (revisionId == null || revisionId.Length != 40 || !revisionId.All(IsHexDigit))
            {
                Log.LogError(CommonResources.ValueOfWithIdentityIsNotValidCommitHash, Names.SourceRoot.RevisionIdFullName, SourceRoot.ItemSpec, revisionId);
                return;
            }

            var relativeUrl = repoUri.LocalPath.TrimEnd('/');

            // The URL may or may not end with '.git' (case-sensitive), but content URLs do not include '.git' suffix:
            const string gitUrlSuffix = ".git";

            if (relativeUrl.EndsWith(gitUrlSuffix, StringComparison.Ordinal))
            {
                relativeUrl = relativeUrl.Substring(0, relativeUrl.Length - gitUrlSuffix.Length);
            }

            SourceLinkUrl = BuildSourceLinkUrl(contentUri.ToString(), relativeUrl, revisionId);
        }