コード例 #1
0
 /// <summary>
 /// Return the sequence of methods to call while building the target object.
 /// </summary>
 /// <param name="context">Current build context.</param>
 /// <returns>Sequence of methods to call.</returns>
 public IEnumerable <SelectedMethod> SelectMethods(IBuilderContext context)
 {
     foreach (Pair <MethodInfo, IEnumerable <InjectionParameterValue> > method in methods)
     {
         Type                   typeToBuild = BuildKey.GetType(context.BuildKey);
         SelectedMethod         selectedMethod;
         ReflectionHelper       typeReflector   = new ReflectionHelper(method.First.DeclaringType);
         MethodReflectionHelper methodReflector = new MethodReflectionHelper(method.First);
         if (!methodReflector.MethodHasOpenGenericParameters && !typeReflector.IsOpenGeneric)
         {
             selectedMethod = new SelectedMethod(method.First);
         }
         else
         {
             Type[] closedMethodParameterTypes =
                 methodReflector.GetClosedParameterTypes(typeToBuild.GetGenericArguments());
             selectedMethod = new SelectedMethod(
                 typeToBuild.GetMethod(method.First.Name, closedMethodParameterTypes));
         }
         SpecifiedMemberSelectorHelper.AddParameterResolvers(
             typeToBuild,
             context.PersistentPolicies,
             method.Second,
             selectedMethod);
         yield return(selectedMethod);
     }
 }
コード例 #2
0
        public IEnumerable <SelectedProperty> SelectProperties(IBuilderContext context)
        {
            var t             = BuildKey.GetType(context.BuildKey);
            var propertyNames = new HashSet <string>();

            foreach (SelectedProperty prop in specifiedPropertiesPolicy.SelectProperties(context))
            {
                if (!propertyNames.Contains(prop.Property.Name))
                {
                    propertyNames.Add(prop.Property.Name);
                    yield return(prop);
                }
            }
            foreach (SelectedProperty prop in defaultProlicy.SelectProperties(context))
            {
                if (!propertyNames.Contains(prop.Property.Name))
                {
                    yield return(prop);
                }
            }

            foreach (PropertyInfo prop in t.GetProperties(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance))
            {
                if (prop.GetIndexParameters().Length == 0 &&
                    prop.CanWrite && !ShoudBeIgnored(prop) &&
                    !propertyNames.Contains(prop.Name) &&
                    !prop.PropertyType.IsValueType &&
                    CanBeResolved(prop))
                {
                    yield return(CreateSelectedProperty(context, prop));
                }
            }
        }
コード例 #3
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Checks if the cache contains stored outputs for a given builder with any dependency fingerprint
 /// </summary>
 /// <param name="builder">Builder key</param>
 /// <returns>Returns <c>true</c> if there are stored outputs for the given builder.</returns>
 public bool ContainsAny(BuildKey builder)
 {
     lock (cache)
     {
         return cache.ContainsKey(builder);
     }
 }
コード例 #4
0
            static void ExtractMetaToCache(
                List <ChangeInfo> changes,
                Dictionary <string, ChangeInfo> cache)
            {
                HashSet <string> indexedKeys = BuildIndexedKeys(changes);

                for (int i = changes.Count - 1; i >= 0; i--)
                {
                    ChangeInfo currentChange = changes[i];

                    if (!MetaPath.IsMetaPath(currentChange.Path))
                    {
                        continue;
                    }

                    string realPath = MetaPath.GetPathFromMetaPath(currentChange.Path);

                    if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
                                                  currentChange.ChangeTypes, realPath)))
                    {
                        continue;
                    }

                    // found foo.c and foo.c.meta
                    // with the same chage types - move .meta to cache
                    cache.Add(BuildKey.ForChange(currentChange), currentChange);
                    changes.RemoveAt(i);
                }
            }
コード例 #5
0
        private static IInstanceInterceptionPolicy FindInterceptorPolicy(IBuilderContext context, out Type typeToIntercept)
        {
            typeToIntercept = null;

            Type currentType  = BuildKey.GetType(context.BuildKey);
            Type originalType = BuildKey.GetType(context.OriginalBuildKey);

            // First, try for a match against the current build key
            IInstanceInterceptionPolicy policy;

            policy = context.Policies.Get <IInstanceInterceptionPolicy>(context.BuildKey, false) ??
                     context.Policies.Get <IInstanceInterceptionPolicy>(currentType, false);
            if (policy != null)
            {
                typeToIntercept = currentType;
                return(policy);
            }

            // Next, try the original build key

            policy = context.Policies.Get <IInstanceInterceptionPolicy>(context.OriginalBuildKey, false) ??
                     context.Policies.Get <IInstanceInterceptionPolicy>(originalType, false);

            if (policy != null)
            {
                typeToIntercept = originalType;
            }

            return(policy);
        }
コード例 #6
0
ファイル: CachedBuilder.cs プロジェクト: zvrana/bari
        /// <summary>
        /// Runs this builder
        /// </summary>
        /// <param name="context"> </param>
        /// <returns>Returns a set of generated files, in suite relative paths</returns>
        public ISet<TargetRelativePath> Run(IBuildContext context)
        {
            var currentFingerprint = wrappedBuilder.Dependencies.CreateFingerprint();
            var buildKey = new BuildKey(wrappedBuilder.GetType(), wrappedBuilder.Uid);

            cache.LockForBuilder(buildKey);
            try
            {
                if (cache.Contains(buildKey, currentFingerprint))
                {
                    log.DebugFormat("Restoring cached build outputs for {0}", buildKey);
                    return cache.Restore(buildKey, targetDir);
                }
                else
                {
                    log.DebugFormat("Running builder {0}", buildKey);
                    var files = wrappedBuilder.Run(context);

                    log.DebugFormat("Storing build outputs of {0}", buildKey);
                    cache.Store(buildKey, currentFingerprint, files, targetDir);
                    return files;
                }
            }
            finally
            {
                cache.UnlockForBuilder(buildKey);
            }
        }
コード例 #7
0
ファイル: FunctionQueueUtil.cs プロジェクト: riarenas/runfo
 public async Task QueueTriageBuildAsync(BuildKey buildKey)
 {
     var buildMessage = new BuildMessage(buildKey);
     var text         = JsonConvert.SerializeObject(buildMessage);
     var queue        = new QueueClient(_connectionString, QueueNameTriageBuild);
     await queue.SendMessageEncodedAsync(text).ConfigureAwait(false);
 }
コード例 #8
0
        public void CanChangeTypeOfTypeBuildKey()
        {
            Type t  = typeof(string);
            Type t2 = (Type)BuildKey.ReplaceType(t, typeof(int));

            Assert.AreEqual(typeof(int), t2);
        }
コード例 #9
0
        public SelectedConstructor SelectConstructor(IBuilderContext context)
        {
            var target      = BuildKey.GetType(context.BuildKey);
            var typeTracker = context.Policies.Get <TypeTrackerPolicy>(context.BuildKey).TypeTracker;
            var constructor = SelectConstructor(target, typeTracker);

            if (constructor == null)
            {
                return(null);
            }

            // Unity includes a policy used when explicitly configuring injection.  Here we borrow
            // it to specify the constructor we want to user.  Normally the user specifies a specific
            // constructor and the policies for filling its parameters, here we do it automatically.
            var parameters = new List <InjectionParameterValue>();

            foreach (var parameter in constructor.GetParameters())
            {
                parameters.Add(new TypeToBeResolved(
                                   parameter.ParameterType,
                                   parameterResolver.GetResolver(parameter)));
            }

            return(new SpecifiedConstructorSelectorPolicy(constructor, parameters.ToArray())
                   .SelectConstructor(context));
        }
コード例 #10
0
 /// <summary>
 /// Called during the chain of responsibility for a build operation. The
 /// PreBuildUp method is called when the chain is being executed in the
 /// forward direction.
 /// </summary>
 /// <param name="context">Context of the build operation.</param>
 public override void PreBuildUp(IBuilderContext context)
 {
     if (context.Existing == null)
     {
         context.Existing = Activator.CreateInstance(BuildKey.GetType(context.BuildKey));
     }
 }
コード例 #11
0
        public void BuildKeyMethodsWrapTypeObjects()
        {
            Type t  = typeof(string);
            Type t2 = BuildKey.GetType(t);

            Assert.AreEqual(t, t2);
        }
コード例 #12
0
ファイル: BuildRetryUtil.cs プロジェクト: riarenas/runfo
        public async Task ProcessBuildAsync(BuildKey buildKey)
        {
            var modelBuildAttempts = await TriageContextUtil
                                     .GetModelBuildAttemptsQuery(buildKey)
                                     .Include(x => x.ModelBuild)
                                     .ToListAsync()
                                     .ConfigureAwait(false);

            var modelBuild = modelBuildAttempts.FirstOrDefault()?.ModelBuild;

            if (modelBuild is null)
            {
                // This happens when we have no data on the build at all
                Logger.LogWarning($"No model for the build {buildKey}");
                return;
            }

            var failed = modelBuild.BuildResult == BuildResult.Failed || modelBuild.BuildResult == BuildResult.Canceled;

            if (!failed)
            {
                Logger.LogWarning($"Build did not fail so no retry is needed");
                return;
            }

            await RetryOsxDeprovisionAsync(modelBuild, modelBuildAttempts);
        }
コード例 #13
0
ファイル: BuildKeytests.cs プロジェクト: jaredpar/jenkins
 public void JobNameInFolder()
 {
     var jobId = JobId.ParseName("job/cat/job/dog");
     var buildId = new BuildId(42, jobId);
     var buildKey = new BuildKey(buildId);
     Assert.False(AzureUtil.IsIllegalKey(buildKey.Key));
 }
コード例 #14
0
            static void ExtractMetaToCache(
                MergeChangesCategory category,
                Dictionary <string, MergeChangeInfo> cache)
            {
                List <MergeChangeInfo> changes = category.GetChanges();

                HashSet <string> indexedKeys = BuildIndexedKeys(
                    changes);

                for (int i = changes.Count - 1; i >= 0; i--)
                {
                    MergeChangeInfo currentChange = changes[i];

                    string path = currentChange.GetPath();

                    if (!MetaPath.IsMetaPath(path))
                    {
                        continue;
                    }

                    string realPath = MetaPath.GetPathFromMetaPath(path);

                    if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
                                                  currentChange.CategoryType, realPath)))
                    {
                        continue;
                    }

                    // found foo.c and foo.c.meta - move .meta to cache
                    cache.Add(BuildKey.ForChange(currentChange), currentChange);
                    changes.RemoveAt(i);
                }
            }
コード例 #15
0
ファイル: MemoryBuildCache.cs プロジェクト: zvrana/bari
        /// <summary>
        /// Store build outputs in the cache by reading them from the file system
        /// </summary>
        /// <param name="builder">Builder key (first part of the key)</param>
        /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param>
        /// <param name="outputs">Target-relative path of the build outputs to be cached</param>
        /// <param name="targetRoot">File system abstraction of the root target directory</param>
        public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable<TargetRelativePath> outputs, IFileSystemDirectory targetRoot)
        {
            MemoryCacheItem item = GetOrCreate(builder);            

            var map = new ConcurrentDictionary<TargetRelativePath, byte[]>();

            Parallel.ForEach(outputs, outputPath =>
                {
                    if (targetRoot.Exists(outputPath))
                    {
                        using (var stream = targetRoot.ReadBinaryFile(outputPath))
                        {
                            var buf = new byte[stream.Length];
                            stream.Read(buf, 0, buf.Length);

                            map.TryAdd(outputPath, buf);
                        }
                    }
                    else
                    {
                        map.TryAdd(outputPath, null);
                    }
                });
            
            item.Update(fingerprint, map);
        }
コード例 #16
0
ファイル: BuildKeytests.cs プロジェクト: jaredpar/jenkins
 public void Simple()
 {
     var jobId = JobId.ParseName("dog");
     var buildId = new BuildId(42, jobId);
     var buildKey = new BuildKey(buildId);
     Assert.False(AzureUtil.IsIllegalKey(buildKey.Key));
     Assert.Equal("42-dog", buildKey.Key);
 }
コード例 #17
0
ファイル: TriageContextUtil.cs プロジェクト: riarenas/runfo
        public IQueryable <ModelTestRun> GetModelTestRunQuery(BuildKey buildKey, int testRunId)
        {
            var buildId = GetModelBuildId(buildKey);

            return(Context
                   .ModelTestRuns
                   .Where(x => x.ModelBuildId == buildId && x.TestRunId == testRunId));
        }
コード例 #18
0
        public void JobNameInFolder()
        {
            var jobId    = JobId.ParseName("job/cat/job/dog");
            var buildId  = new BuildId(42, jobId);
            var buildKey = new BuildKey(buildId);

            Assert.False(AzureUtil.IsIllegalKey(buildKey.Key));
        }
コード例 #19
0
            public override void PreBuildUp(IBuilderContext context)
            {
                Type type;

                if (context.Existing == null && BuildKey.TryGetType(context.BuildKey, out type))
                {
                    context.Existing = Activator.CreateInstance(type);
                }
            }
コード例 #20
0
        public void Simple()
        {
            var jobId    = JobId.ParseName("dog");
            var buildId  = new BuildId(42, jobId);
            var buildKey = new BuildKey(buildId);

            Assert.False(AzureUtil.IsIllegalKey(buildKey.Key));
            Assert.Equal("42-dog", buildKey.Key);
        }
コード例 #21
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PreBuildUp method is called when the chain is being executed in the
        /// forward direction.
        /// </summary>
        /// <remarks>In this class, PreBuildUp is responsible for figuring out if the
        /// class is proxiable, and if so, replacing it with a proxy class.</remarks>
        /// <param name="context">Context of the build operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            if (context.Existing != null)
            {
                return;
            }

            Type typeToBuild;

            if (!BuildKey.TryGetType(context.BuildKey, out typeToBuild))
            {
                return;
            }

            ITypeInterceptionPolicy interceptionPolicy = GetInterceptionPolicy(context);

            if (interceptionPolicy == null)
            {
                return;
            }

            if (!interceptionPolicy.Interceptor.CanIntercept(typeToBuild))
            {
                return;
            }

            lock (lockObj)
            {
                if (interceptionPolicy.ProxyType == null)
                {
                    Type typeToIntercept = typeToBuild;
                    if (typeToIntercept.IsGenericType)
                    {
                        typeToIntercept = typeToIntercept.GetGenericTypeDefinition();
                    }

                    interceptionPolicy.ProxyType = interceptionPolicy.Interceptor.CreateProxyType(typeToIntercept);
                }
            }

            Type interceptingType = interceptionPolicy.ProxyType;

            if (interceptingType.IsGenericTypeDefinition)
            {
                interceptingType = interceptingType.MakeGenericType(typeToBuild.GetGenericArguments());
            }

            SelectedConstructor        currentConstructor = GetCurrentConstructor(context);
            SelectedConstructor        newConstructor     = FindNewConstructor(currentConstructor, interceptingType);
            IConstructorSelectorPolicy newSelector        = new ConstructorWithResolverKeysSelectorPolicy(newConstructor);

            context.Policies.Set(newSelector, context.BuildKey);
        }
コード例 #22
0
        private async Task <string> GetReportForHelixAsync(ModelTrackingIssue modelTrackingIssue, int limit)
        {
            Debug.Assert(modelTrackingIssue.TrackingKind == TrackingKind.HelixLogs);
            var matches = await Context
                          .ModelTrackingIssueMatches
                          .Where(x => x.ModelTrackingIssueId == modelTrackingIssue.Id)
                          .OrderByDescending(x => x.ModelBuildAttempt.ModelBuild.BuildNumber)
                          .Take(limit)
                          .Select(x => new
            {
                AzureOrganization       = x.ModelBuildAttempt.ModelBuild.AzureOrganization,
                AzureProject            = x.ModelBuildAttempt.ModelBuild.AzureProject,
                DefinitionId            = x.ModelBuildAttempt.ModelBuild.DefinitionId,
                DefinitionName          = x.ModelBuildAttempt.ModelBuild.DefinitionName,
                GitHubOrganization      = x.ModelBuildAttempt.ModelBuild.GitHubOrganization,
                GitHubRepository        = x.ModelBuildAttempt.ModelBuild.GitHubRepository,
                GitHubPullRequestNumber = x.ModelBuildAttempt.ModelBuild.PullRequestNumber,
                GitHubTargetBranch      = x.ModelBuildAttempt.ModelBuild.GitHubTargetBranch,
                BuildNumber             = x.ModelBuildAttempt.ModelBuild.BuildNumber,
                HelixLogKind            = x.HelixLogKind,
                HelixLogUri             = x.HelixLogUri,
            })
                          .ToListAsync().ConfigureAwait(false);

            var map = new Dictionary <BuildKey, (BuildInfo BuildInfo, HelixLogInfo?HelixLogInfo)>();
            var set = new HashSet <HelixLogKind>();

            foreach (var item in matches)
            {
                var key = new BuildKey(item.AzureOrganization, item.AzureProject, item.BuildNumber);
                if (!map.TryGetValue(key, out var tuple))
                {
                    var buildInfo = new BuildInfo(
                        key.Organization,
                        key.Project,
                        key.Number,
                        new GitHubBuildInfo(item.GitHubOrganization, item.GitHubRepository, item.GitHubPullRequestNumber, item.GitHubTargetBranch));
                    tuple = (buildInfo, null);
                }

                set.Add(item.HelixLogKind);
                tuple.HelixLogInfo = tuple.HelixLogInfo is { } log
                    ? log.SetUri(item.HelixLogKind, item.HelixLogUri)
                    : new HelixLogInfo(item.HelixLogKind, item.HelixLogUri);

                map[key] = tuple;
            }

            var reportBuilder = new ReportBuilder();

            return(reportBuilder.BuildSearchHelix(
                       map.Values.OrderByDescending(x => x.BuildInfo.Number),
                       set.ToArray(),
                       markdown: true));
        }
コード例 #23
0
ファイル: UnityDiffTree.cs プロジェクト: BaseDorp/TankGame
            internal ClientDiffInfo GetExistingMeta(ClientDiffInfo diff)
            {
                ClientDiffInfo result;

                if (!mCache.TryGetValue(BuildKey.ForMetaDiff(diff), out result))
                {
                    return(null);
                }

                return(result);
            }
コード例 #24
0
        private static ITypeInterceptionPolicy GetInterceptionPolicy(IBuilderContext context)
        {
            ITypeInterceptionPolicy policy;

            policy = context.Policies.Get <ITypeInterceptionPolicy>(context.BuildKey, false);
            if (policy == null)
            {
                policy = context.Policies.Get <ITypeInterceptionPolicy>(BuildKey.GetType(context.BuildKey), false);
            }
            return(policy);
        }
コード例 #25
0
            internal MergeChangeInfo GetExistingMeta(MergeChangeInfo change)
            {
                MergeChangeInfo result;

                if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
                {
                    return(null);
                }

                return(result);
            }
コード例 #26
0
        /// <summary>
        /// Construct a build plan.
        /// </summary>
        /// <param name="context">The current build context.</param>
        /// <param name="buildKey">The current build key.</param>
        /// <returns>The created build plan.</returns>
        public IBuildPlanPolicy CreatePlan(IBuilderContext context, object buildKey)
        {
            DynamicBuildPlanGenerationContext generatorContext =
                new DynamicBuildPlanGenerationContext(
                    BuildKey.GetType(buildKey));

            IBuilderContext planContext = GetContext(context, buildKey, generatorContext);

            planContext.Strategies.ExecuteBuildUp(planContext);

            return(new DynamicMethodBuildPlan(generatorContext.GetBuildMethod()));
        }
コード例 #27
0
        private static void AddPublicationsToPolicy(object buildKey, EventBrokerInfoPolicy policy)
        {
            var t = BuildKey.GetType(buildKey);

            foreach (var eventInfo in t.GetEvents())
            {
                var attrs = (PublishesAttribute[])eventInfo.GetCustomAttributes(typeof(PublishesAttribute), true);
                foreach (var attr in attrs)
                {
                    policy.AddPublication(attr.EventName, eventInfo);
                }
            }
        }
コード例 #28
0
        public async Task TriageAsync(BuildKey buildKey, int modelTrackingIssueId)
        {
            var attempts = await TriageContextUtil
                           .GetModelBuildAttemptsQuery(buildKey)
                           .Include(x => x.ModelBuild)
                           .ToListAsync()
                           .ConfigureAwait(false);

            foreach (var attempt in attempts)
            {
                await TriageAsync(attempt.GetBuildAttemptKey(), modelTrackingIssueId).ConfigureAwait(false);
            }
        }
コード例 #29
0
        private static void AddSubscriptionsToPolicy(object buildKey, EventBrokerInfoPolicy policy)
        {
            var t = BuildKey.GetType(buildKey);

            foreach (var method in t.GetMethods())
            {
                var attrs = (SubscribesToAttribute[])method.GetCustomAttributes(typeof(SubscribesToAttribute), true);
                foreach (var attr in attrs)
                {
                    policy.AddSubscription(attr.EventName, method);
                }
            }
        }
コード例 #30
0
        /// <summary>
        /// Creates an instance of the build plan's type by creating a WCF channel that implements it
        /// </summary>
        /// <param name="context">Context used to build up the object.</param>
        public void BuildUp(IBuilderContext context)
        {
            if (context.Existing == null)
            {
                IChannelManager channelManager = context.Lifetime.OfType <IChannelManager>().Single();

                if (BuildKey.GetType(context.BuildKey).IsAssignableFrom(_ServiceInterfaceType) == false)
                {
                    throw new Exception("A WcfProxyBuildPlanPolicy has been paired with an incorrect BuildKey. Its build key type is not assignable from the service interface type.");
                }

                context.Existing = channelManager.CreateChannel(_ServiceInterfaceType, _ChannelFactoryFactory);
            }
        }
コード例 #31
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint
 /// 
 /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using
 /// the <see cref="IBuildCache.LockForBuilder"/> method.</para>
 /// </summary>
 /// <param name="builder">Builder key</param>
 /// <param name="fingerprint">Current dependency fingerprint</param>
 /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns>
 public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint)
 {
     lock (cache)
     {
         MemoryCacheItem item;
         if (cache.TryGetValue(builder, out item))
         {
             return item.MatchesFingerprint(fingerprint);
         }
         else
         {
             return false;
         }
     }
 }
コード例 #32
0
        public void SetUp()
        {
            cache = new MemoryBuildCache();
            T     = new BuildKey(typeof(IBuilder), "test");
            root  = new TestFileSystemDirectory("root");

            fingerprint      = new Mock <IDependencyFingerprint>();
            otherFingerprint = new Mock <IDependencyFingerprint>();

            fingerprint.Setup(f => f.Equals(fingerprint.Object)).Returns(true);
            fingerprint.Setup(f => f.Equals(otherFingerprint.Object)).Returns(false);

            otherFingerprint.Setup(f => f.Equals(fingerprint.Object)).Returns(false);
            otherFingerprint.Setup(f => f.Equals(otherFingerprint.Object)).Returns(true);
        }
コード例 #33
0
ファイル: MemoryBuildCacheTest.cs プロジェクト: zvrana/bari
        public void SetUp()
        {
            cache = new MemoryBuildCache();
            T = new BuildKey(typeof(IBuilder), "test");
            root = new TestFileSystemDirectory("root");           

            fingerprint = new Mock<IDependencyFingerprint>();
            otherFingerprint = new Mock<IDependencyFingerprint>();

            fingerprint.Setup(f => f.Equals(fingerprint.Object)).Returns(true);
            fingerprint.Setup(f => f.Equals(otherFingerprint.Object)).Returns(false);

            otherFingerprint.Setup(f => f.Equals(fingerprint.Object)).Returns(false);
            otherFingerprint.Setup(f => f.Equals(otherFingerprint.Object)).Returns(true);
        }
コード例 #34
0
ファイル: FileBuildCache.cs プロジェクト: zvrana/bari
        /// <summary>
        /// Store build outputs in the cache by reading them from the file system
        /// </summary>
        /// <param name="builder">Builder key (first part of the key)</param>
        /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param>
        /// <param name="outputs">Target-relative path of the build outputs to be cached</param>
        /// <param name="targetRoot">File system abstraction of the root target directory</param>
        public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable<TargetRelativePath> outputs, IFileSystemDirectory targetRoot)
        {
            var lck = GetOrCreateLock(builder);
            lck.EnterWriteLock();
            try
            {
                var cacheDir = cacheRoot.GetChildDirectory(GetCacheDirectoryName(builder), createIfMissing: true);

                SaveDependencyFingerprint(fingerprint, cacheDir);
                SaveOutputs(outputs, targetRoot, cacheDir);
            }
            finally
            {
                lck.ExitWriteLock();
            }
        }
コード例 #35
0
ファイル: UnityDiffTree.cs プロジェクト: BaseDorp/TankGame
            HashSet <string> BuildIndexedKeys(List <ClientDiffInfo> diffs)
            {
                HashSet <string> result = new HashSet <string>();

                foreach (ClientDiffInfo diff in diffs)
                {
                    if (MetaPath.IsMetaPath(diff.DiffWithMount.Difference.Path))
                    {
                        continue;
                    }

                    result.Add(BuildKey.ForDiff(diff));
                }

                return(result);
            }
コード例 #36
0
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");
            Type typeToBuild = BuildKey.GetType(context.BuildKey);

            if (typeToBuild.IsArray && typeToBuild.GetArrayRank() == 1)
            {
                Type elementType = typeToBuild.GetElementType();

                MethodInfo resolverMethod = genericResolveArrayMethod.MakeGenericMethod(elementType);

                ArrayResolver resolver = (ArrayResolver)Delegate.CreateDelegate(typeof(ArrayResolver), resolverMethod);

                context.Existing      = resolver(context);
                context.BuildComplete = true;
            }
        }
コード例 #37
0
            static HashSet <string> BuildIndexedKeys(
                List <MergeChangeInfo> changes)
            {
                HashSet <string> result = new HashSet <string>();

                foreach (MergeChangeInfo change in changes)
                {
                    if (MetaPath.IsMetaPath(change.GetPath()))
                    {
                        continue;
                    }

                    result.Add(BuildKey.ForChange(change));
                }

                return(result);
            }
コード例 #38
0
        public IEnumerable <SelectedProperty> SelectProperties(IBuilderContext context)
        {
            var target      = BuildKey.GetType(context.BuildKey);
            var typeTracker = context.Policies.Get <TypeTrackerPolicy>(context.BuildKey).TypeTracker;

            // Unity includes a policy used when explicitly configuring injection.  Here we borrow
            // it to specify the properties we want to fill.  Normally the user specifies specific
            // properties and the policies for filling them, here we do it automatically.
            var policy = new SpecifiedPropertiesSelectorPolicy();

            foreach (var property in target.GetProperties())
            {
                // Ignore indexed properties
                if (property.GetIndexParameters().Length > 0)
                {
                    continue;
                }

                // Ignore read only properties
                if (!property.CanWrite)
                {
                    continue;
                }

                // Ignore properties we can't fill anyway
                if (!typeTracker.HasDependency(property.PropertyType))
                {
                    continue;
                }

                // Ignore properties that would create obvious circular dependencies.  It is still
                // possible to create one if you have multiple classes referring to each other though.
                if (property.PropertyType == property.DeclaringType ||
                    property.DeclaringType.IsAssignableFrom(property.PropertyType))
                {
                    continue;
                }

                policy.AddPropertyAndValue(property, new TypeToBeResolved(
                                               property.PropertyType,
                                               GetResolver(property)));
            }

            return(policy.SelectProperties(context));
        }
コード例 #39
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
        /// <summary>
        /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint
        /// 
        /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using
        /// the <see cref="IBuildCache.LockForBuilder"/> method.</para>
        /// </summary>
        /// <param name="builder">Builder key</param>
        /// <param name="fingerprint">Current dependency fingerprint</param>
        /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns>
        public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint)
        {
            var lck = GetOrCreateLock(builder);
            lck.EnterReadLock();
            try
            {
                var dirName = GetCacheDirectoryName(builder);
                if (cacheRoot.Value.ChildDirectories.Contains(dirName))
                {
                    var cacheDir = cacheRoot.Value.GetChildDirectory(dirName);
                    if (cacheDir.Files.Contains(DepsFileName))
                    {
                        using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName))
                        using (var memStream = new MemoryStream())
                        {
                            fingerprint.Save(protocolSerializer, memStream);

                            if (depsStream.Length != memStream.Length)
                                return false;

                            var buf1 = memStream.ToArray();
                            var buf2 = new byte[depsStream.Length];
                            depsStream.Read(buf2, 0, (int) depsStream.Length);

                            for (int i = 0; i < buf1.Length; i++)
                                if (buf1[i] != buf2[i])
                                    return false;

                            return true;
                        }
                    }
                }

                return false;
            }
            finally
            {
                lck.ExitReadLock();
            }
        }
コード例 #40
0
ファイル: CachedBuilder.cs プロジェクト: vigoo/bari
        /// <summary>
        /// Runs this builder
        /// </summary>
        /// <param name="context"> </param>
        /// <returns>Returns a set of generated files, in suite relative paths</returns>
        public ISet<TargetRelativePath> Run(IBuildContext context)
        {
            var buildKey = new BuildKey(wrappedBuilder.BuilderType, wrappedBuilder.Uid);

            cache.LockForBuilder(buildKey);
            try
            {
                if (wrappedBuilder.CanRun())
                {
                    try
                    {
                        var currentFingerprint = wrappedBuilder.Dependencies.Fingerprint;

                        if (cache.Contains(buildKey, currentFingerprint))
                        {
                            log.DebugFormat("Restoring cached build outputs for {0}", buildKey);
                            return cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions);
                        }
                        else
                        {
                            log.DebugFormat("Running builder {0}", buildKey);
                            var files = wrappedBuilder.Run(context);

                            log.DebugFormat("Storing build outputs of {0}", buildKey);
                            cache.Store(buildKey, currentFingerprint, files, targetDir);
                            return files;
                        }
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("Failed to run builder {0}: {1}", wrappedBuilder.Uid, ex);

                        // Fallback to any cached value
                        if (SupportsFallback && cache.ContainsAny(buildKey))
                        {
                            log.DebugFormat("Restoring cached build outputs for {0} without fingerprint check", buildKey);
                            return cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                else
                {
                    // Fallback to any cached value
                    if (cache.ContainsAny(buildKey))
                    {
                        log.DebugFormat("Restoring cached build outputs for {0} without fingerprint check", buildKey);
                        return cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions);
                    }
                    else
                    {
                        throw new BuilderCantRunException(wrappedBuilder.Uid);
                    }
                }
            }
            finally
            {
                cache.UnlockForBuilder(buildKey);
            }
        }
コード例 #41
0
ファイル: CachedBuilder.cs プロジェクト: vigoo/bari
        /// <summary>
        /// Verifies if the builder is able to run. Can be used to fallback to cached results without getting en error.
        /// </summary>
        /// <returns>If <c>true</c>, the builder thinks it can run.</returns>
        public bool CanRun()
        {
            var buildKey = new BuildKey(wrappedBuilder.BuilderType, wrappedBuilder.Uid);

            cache.LockForBuilder(buildKey);
            try
            {
                return wrappedBuilder.CanRun() || cache.ContainsAny(buildKey);
            }
            finally
            {
                cache.UnlockForBuilder(buildKey);
            }
        }
コード例 #42
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Locks the cache for a given builder. 
 /// 
 /// <para>Until calling <see cref="IBuildCache.UnlockForBuilder"/>, it is guaranteed that no
 /// <see cref="IBuildCache.Store"/> operation will be ran for the given builder from other
 /// threads.</para>
 /// </summary>
 /// <param name="builder">Builder key</param>
 public void LockForBuilder(BuildKey builder)
 {
     GetOrCreate(builder).EnterUpgradeableLock();
 }
コード例 #43
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Removes the lock put by the <see cref="IBuildCache.LockForBuilder"/> method.
 /// </summary>
 /// <param name="builder">Builder key</param>
 public void UnlockForBuilder(BuildKey builder)
 {
     GetOrCreate(builder).ExitUpgradeableLock();
 }
コード例 #44
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Locks the cache for a given builder. 
 /// 
 /// <para>Until calling <see cref="IBuildCache.UnlockForBuilder"/>, it is guaranteed that no
 /// <see cref="IBuildCache.Store"/> operation will be ran for the given builder from other
 /// threads.</para>
 /// </summary>
 /// <param name="builder">Builder key</param>
 public void LockForBuilder(BuildKey builder)
 {
     var lck = GetOrCreateLock(builder);
     lck.EnterUpgradeableReadLock();
 }
コード例 #45
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Checks if the cache contains stored outputs for a given builder with any dependency fingerprint
 /// </summary>
 /// <param name="builder">Builder key</param>
 /// <returns>Returns <c>true</c> if there are stored outputs for the given builder.</returns>
 public bool ContainsAny(BuildKey builder)
 {
     var lck = GetOrCreateLock(builder);
     lck.EnterReadLock();
     try
     {
         var dirName = GetCacheDirectoryName(builder);
         if (cacheRoot.Value.ChildDirectories.Contains(dirName))
         {
             var cacheDir = cacheRoot.Value.GetChildDirectory(dirName);
             if (cacheDir.Files.Contains(DepsFileName))
             {
                 return true;
             }
         }
         return false;
     }
     finally
     {
         lck.ExitReadLock();
     }
 }
コード例 #46
0
ファイル: FileBuildCache.cs プロジェクト: zvrana/bari
        /// <summary>
        /// Checks if the cache contains stored outputs for a given builder with a given dependency fingerprint
        /// 
        /// <para>If <see cref="IBuildCache.Restore"/> will be also called, the cache must be locked first using
        /// the <see cref="IBuildCache.LockForBuilder"/> method.</para>
        /// </summary>
        /// <param name="builder">Builder key</param>
        /// <param name="fingerprint">Current dependency fingerprint</param>
        /// <returns>Returns <c>true</c> if there are stored outputs for the given builder and fingerprint combination.</returns>
        public bool Contains(BuildKey builder, IDependencyFingerprint fingerprint)
        {
            var lck = GetOrCreateLock(builder);
            lck.EnterReadLock();
            try
            {
                var dirName = GetCacheDirectoryName(builder);
                if (cacheRoot.ChildDirectories.Contains(dirName))
                {
                    var cacheDir = cacheRoot.GetChildDirectory(dirName);
                    if (cacheDir.Files.Contains(DepsFileName))
                    {
                        using (var depsStream = cacheDir.ReadBinaryFile(DepsFileName))
                        {
                            var fpType = fingerprint.GetType();
                            var storedFp = Activator.CreateInstance(fpType, protocolSerializer, depsStream);
                            
                            bool fingerprintEquals = fingerprint.Equals(storedFp);

                            if (!fingerprintEquals && EnableFingerprintDiff)
                            {
                                log.DebugFormat("[{0}] Fingerprint differs", dirName);
                                log.DebugFormat("[{1}] Cached: {0}", storedFp, dirName);
                                log.DebugFormat("[{1}] Current: {0}", fingerprint, dirName);
                            }

                            return fingerprintEquals;
                        }
                    }
                }

                return false;
            }
            finally
            {
                lck.ExitReadLock();
            }
        }
コード例 #47
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
        /// <summary>
        /// Restores the stored files for a given builder to a file system directory
        /// 
        /// <para>The cache only stores the latest stored results and this is what will be restored
        /// to the target directory. To verify if it was generated with the correct dependency fingerprint,
        /// use <see cref="IBuildCache.Contains"/>.</para>
        /// <para>To ensure thread safety, use <see cref="IBuildCache.LockForBuilder"/>.</para>
        /// </summary>
        /// <param name="builder">Builder key</param>
        /// <param name="targetRoot">Target file system directory</param>
        /// <param name="aggressive">If <c>true</c>, files in the target directory won't be checked by hash before overriding them</param>
        /// <param name="aggressiveExceptions">Exceptions to the aggresivve mode. Can be <c>null</c> if not used.</param>
        /// <returns>Returns the target root relative paths of all the restored files</returns>
        public ISet<TargetRelativePath> Restore(BuildKey builder, IFileSystemDirectory targetRoot, bool aggressive, Regex[] aggressiveExceptions = null)
        {
            var lck = GetOrCreateLock(builder);
            lck.EnterReadLock();
            try
            {
                var dirName = GetCacheDirectoryName(builder);
                if (cacheRoot.Value.ChildDirectories.Contains(dirName))
                {
                    var cacheDir = cacheRoot.Value.GetChildDirectory(dirName);
                    if (cacheDir.Files.Contains(NamesFileName))
                    {
                        using (var reader = cacheDir.ReadTextFile(NamesFileName))
                        {
                            var result = new HashSet<TargetRelativePath>();

                            int idx = 0;
                            string line;
                            while ((line = reader.ReadLine()) != null)
                            {
                                var parts = line.Split(';');
                                if (parts.Length == 2)
                                {
                                    var relativeRoot = parts[0];
                                    var relativePath = parts[1];
                                    var fullPath = Path.Combine(relativeRoot, relativePath);

                                    var cacheFileName = idx.ToString(CultureInfo.InvariantCulture);

                                    // It is possible that only a file name (a virtual file) was cached without any contents:
                                    if (cacheDir.Exists(cacheFileName))
                                    {
                                        if (aggressive && BeAggressive(aggressiveExceptions, fullPath))
                                            cacheDir.CopyFile(cacheFileName, targetRoot, fullPath);
                                        else
                                        {
                                            if (aggressive)
                                                log.DebugFormat("Agressive cache restore is disabled for file {0}", fullPath);

                                            CopyIfDifferent(cacheDir, cacheFileName, targetRoot, fullPath);
                                        }
                                    }

                                    result.Add(new TargetRelativePath(relativeRoot, relativePath));
                                }
                                idx++;
                            }

                            return result;
                        }
                    }
                }

                return new HashSet<TargetRelativePath>();
            }
            finally
            {
                lck.ExitReadLock();
            }
        }
コード例 #48
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Removes the lock put by the <see cref="IBuildCache.LockForBuilder"/> method.
 /// </summary>
 /// <param name="builder">Builder key</param>
 public void UnlockForBuilder(BuildKey builder)
 {
     ReaderWriterLockSlim lck;
     if (locks.TryGetValue(builder, out lck))
         lck.ExitUpgradeableReadLock();
 }
コード例 #49
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Gets the directory name associated with a given Builder key
 /// </summary>
 /// <param name="builder">Builder key</param>
 /// <returns>Returns a valid directory name</returns>
 private static string GetCacheDirectoryName(BuildKey builder)
 {
     return builder.ToString().Replace("/", "___");
 }
コード例 #50
0
ファイル: FileBuildCache.cs プロジェクト: vigoo/bari
 /// <summary>
 /// Gets an existing lock or creates a new one
 /// </summary>
 /// <param name="builder">Builder key used as a key to get locks</param>
 /// <returns>Returns a reader-writer lock</returns>
 private ReaderWriterLockSlim GetOrCreateLock(BuildKey builder)
 {
     ReaderWriterLockSlim lck;
     if (!locks.TryGetValue(builder, out lck))
         locks.Add(builder, lck = new ReaderWriterLockSlim());
     return lck;
 }
コード例 #51
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
        /// <summary>
        /// Restores the stored files for a given builder to a file system directory
        /// 
        /// <para>The cache only stores the latest stored results and this is what will be restored
        /// to the target directory. To verify if it was generated with the correct dependency fingerprint,
        /// use <see cref="IBuildCache.Contains"/>.</para>
        /// <para>To ensure thread safety, use <see cref="IBuildCache.LockForBuilder"/>.</para>
        /// </summary>
        /// <param name="builder">Builder key</param>
        /// <param name="targetRoot">Target file system directory</param>        
        /// <param name="aggressive">If <c>true</c>, files in the target directory won't be checked by hash before overriding them</param>
        /// <param name="aggressiveExceptions">Exceptions to the aggresivve mode. Can be <c>null</c> if not used.</param>
        /// <returns>Returns the target root relative paths of all the restored files</returns>
        public ISet<TargetRelativePath> Restore(BuildKey builder, IFileSystemDirectory targetRoot, bool aggressive, Regex[] aggressiveExceptions = null)
        {
            MemoryCacheItem item;
            lock (cache)
                cache.TryGetValue(builder, out item);

            if (item != null)
            {
                var outputs = item.Outputs;
                var paths = new HashSet<TargetRelativePath>();
                foreach (var pair in outputs)
                {
                    if (pair.Value != null)
                    {
                        using (var stream = targetRoot.CreateBinaryFile(pair.Key))
                            stream.Write(pair.Value, 0, pair.Value.Length);
                    }

                    paths.Add(pair.Key);
                }

                return paths;
            }
            else
            {
                return new HashSet<TargetRelativePath>();
            }
        }
コード例 #52
0
ファイル: MemoryBuildCache.cs プロジェクト: vigoo/bari
        private MemoryCacheItem GetOrCreate(BuildKey builder)
        {
            Contract.Ensures(Contract.Result<MemoryCacheItem>() != null);

            lock (cache)
            {
                MemoryCacheItem item;
                if (!cache.TryGetValue(builder, out item))
                {
                    item = new MemoryCacheItem();
                    cache.Add(builder, item);
                }

                Contract.Assume(item != null);
                return item;
            }
        }