Beispiel #1
0
        public override bool Execute()
        {
            Log.LogTaskName("FindItemWithLogicalName");
            Log.LogTaskProperty("Items", Items);
            Log.LogTaskProperty("LogicalName", LogicalName);
            Log.LogTaskProperty("ProjectDir", ProjectDir);
            Log.LogTaskProperty("ResourcePrefix", ResourcePrefix);

            if (Items != null)
            {
                var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix);

                foreach (var item in Items)
                {
                    var logical = BundleResource.GetLogicalName(ProjectDir, prefixes, item);

                    if (logical == LogicalName)
                    {
                        Log.LogMessage(MessageImportance.Low, "  {0} found at: {1}", LogicalName, item.ItemSpec);
                        Item = item;
                        break;
                    }
                }
            }

            return(!Log.HasLoggedErrors);
        }
        protected override string GenerateCommandLineCommands()
        {
            var prefixes     = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var intermediate = Path.Combine(IntermediateOutputPath, ToolName);
            var logicalName  = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId));
            var path         = Path.Combine(intermediate, logicalName);
            var args         = new ProcessArgumentBuilder();
            var dir          = Path.GetDirectoryName(path);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            OutputFile = new TaskItem(Path.ChangeExtension(path, ".air"));
            OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air"));

            args.Add("-arch", "air64");
            args.Add("-emit-llvm");
            args.Add("-c");
            args.Add("-gline-tables-only");
            args.Add("-ffast-math");
            args.Add(string.Format("-std={0}-metal1.0", OperatingSystem));

            args.Add("-serialize-diagnostics");
            args.AddQuoted(Path.ChangeExtension(path, ".dia"));

            args.Add("-o");
            args.AddQuoted(Path.ChangeExtension(path, ".air"));

            args.AddQuoted(SourceFile.ItemSpec);

            return(args.ToString());
        }
        protected override IEnumerable <ITaskItem> EnumerateInputs()
        {
            if (AtlasTextures == null)
            {
                yield break;
            }

            // group the atlas textures by their parent .atlas directories
            foreach (var item in AtlasTextures)
            {
                var atlas = Path.GetDirectoryName(BundleResource.GetVirtualProjectPath(ProjectDir, item));
                List <ITaskItem> items;

                if (!atlases.TryGetValue(atlas, out items))
                {
                    items = new List <ITaskItem> ();
                    atlases.Add(atlas, items);
                }

                items.Add(item);
            }

            foreach (var atlas in atlases.Keys)
            {
                yield return(new TaskItem(atlas));
            }

            yield break;
        }
Beispiel #4
0
 private void AddBundles(string[] bundles)
 {
     foreach (string thisBundle in bundles)
     {
         BundleResource newBundle = new BundleResource(Path.Combine(PathThirdPartyIOS, "bundle", thisBundle + ".bundle"));
         AdditionalBundleResources.Add(newBundle);
     }
 }
Beispiel #5
0
        protected override string GenerateCommandLineCommands()
        {
            var    prefixes     = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var    intermediate = Path.Combine(IntermediateOutputPath, ToolName);
            var    logicalName  = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId));
            var    path         = Path.Combine(intermediate, logicalName);
            var    args         = new CommandLineArgumentBuilder();
            var    dir          = Path.GetDirectoryName(path);
            string minimumDeploymentTarget;

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            if (AppManifest != null)
            {
                var     plist = PDictionary.FromFile(AppManifest.ItemSpec);
                PString value;

                if (!plist.TryGetValue(MinimumDeploymentTargetKey, out value) || string.IsNullOrEmpty(value.Value))
                {
                    minimumDeploymentTarget = SdkVersion;
                }
                else
                {
                    minimumDeploymentTarget = value.Value;
                }
            }
            else
            {
                minimumDeploymentTarget = SdkVersion;
            }

            OutputFile = new TaskItem(Path.ChangeExtension(path, ".air"));
            OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air"));

            args.Add("-arch", "air64");
            args.Add("-emit-llvm");
            args.Add("-c");
            args.Add("-gline-tables-only");
            args.Add("-ffast-math");

            args.Add("-serialize-diagnostics");
            args.AddQuoted(Path.ChangeExtension(path, ".dia"));

            args.Add("-o");
            args.AddQuoted(Path.ChangeExtension(path, ".air"));

            args.Add(string.Format("-m{0}-version-min={1}", OperatingSystem, minimumDeploymentTarget));

            args.AddQuoted(SourceFile.ItemSpec);

            return(args.ToString());
        }
Beispiel #6
0
        public bool TryAdd(string version, BundleResource resource)
        {
            var addSuccessful = BundleVersions.TryAdd(version,
                                                      new Dictionary <string, string>()
            {
                { "templates", version }
            });

            addSuccessful = addSuccessful && Templates.v1.TryAdd(version, resource);
            return(addSuccessful);
        }
Beispiel #7
0
        public override bool Execute()
        {
            var prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var intermediate    = Path.Combine(IntermediateOutputPath, ToolName);
            var bundleResources = new List <ITaskItem> ();

            foreach (var input in EnumerateInputs())
            {
                var       relative = GetBundleRelativeOutputPath(prefixes, input);
                ITaskItem output;

                if (!string.IsNullOrEmpty(relative))
                {
                    string illegal;

                    if (BundleResource.IsIllegalName(relative, out illegal))
                    {
                        Log.LogError(null, null, null, input.ItemSpec, 0, 0, 0, 0, "The name '{0}' is reserved and cannot be used.", illegal);
                        continue;
                    }

                    var rpath = Path.Combine(intermediate, relative);

                    output = new TaskItem(rpath);
                }
                else
                {
                    output = new TaskItem(intermediate);
                }

                output.SetMetadata("LogicalName", relative);

                if (NeedsBuilding(input, output))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(output.ItemSpec));

                    if (ExecuteTool(input, output) == -1)
                    {
                        return(false);
                    }
                }

                bundleResources.AddRange(GetCompiledBundleResources(input, output));
            }

            BundleResources = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
Beispiel #8
0
        public void TestCreateResponse()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();

            twilioRestClient.AccountSid.Returns("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            twilioRestClient.Request(Arg.Any <Request>())
            .Returns(new Response(
                         System.Net.HttpStatusCode.Created,
                         "{\"sid\": \"BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"account_sid\": \"ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"regulation_sid\": \"RNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"friendly_name\": \"friendly_name\",\"status\": \"draft\",\"email\": \"email\",\"status_callback\": \"http://www.example.com\",\"date_created\": \"2019-07-30T22:29:24Z\",\"date_updated\": \"2019-07-31T01:09:00Z\",\"url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"links\": {\"evaluations\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Evaluations\",\"item_assignments\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ItemAssignments\"}}"
                         ));

            var response = BundleResource.Create("friendly_name", "email", client: twilioRestClient);

            Assert.NotNull(response);
        }
        public void TestDeleteResponse()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();

            twilioRestClient.AccountSid.Returns("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            twilioRestClient.Request(Arg.Any <Request>())
            .Returns(new Response(
                         System.Net.HttpStatusCode.NoContent,
                         "null"
                         ));

            var response = BundleResource.Delete("BUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", client: twilioRestClient);

            Assert.NotNull(response);
        }
Beispiel #10
0
        public void TestReadFullResponse()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();

            twilioRestClient.AccountSid.Returns("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            twilioRestClient.Request(Arg.Any <Request>())
            .Returns(new Response(
                         System.Net.HttpStatusCode.OK,
                         "{\"results\": [{\"sid\": \"BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"account_sid\": \"ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"regulation_sid\": \"RNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"friendly_name\": \"friendly_name\",\"status\": \"draft\",\"email\": \"email\",\"status_callback\": \"http://www.example.com\",\"date_created\": \"2019-07-30T22:29:24Z\",\"date_updated\": \"2019-07-31T01:09:00Z\",\"url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"links\": {\"evaluations\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Evaluations\",\"item_assignments\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles/BUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ItemAssignments\"}}],\"meta\": {\"page\": 0,\"page_size\": 50,\"first_page_url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles?Status=draft&RegulationSid=RNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&IsoCountry=US&FriendlyName=friendly_name&NumberType=mobile&PageSize=50&Page=0\",\"previous_page_url\": null,\"url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles?Status=draft&RegulationSid=RNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&IsoCountry=US&FriendlyName=friendly_name&NumberType=mobile&PageSize=50&Page=0\",\"next_page_url\": null,\"key\": \"results\"}}"
                         ));

            var response = BundleResource.Read(client: twilioRestClient);

            Assert.NotNull(response);
        }
Beispiel #11
0
        public void TestReadEmptyResponse()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();

            twilioRestClient.AccountSid.Returns("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            twilioRestClient.Request(Arg.Any <Request>())
            .Returns(new Response(
                         System.Net.HttpStatusCode.OK,
                         "{\"results\": [],\"meta\": {\"page\": 0,\"page_size\": 50,\"first_page_url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles?PageSize=50&Page=0\",\"previous_page_url\": null,\"url\": \"https://numbers.twilio.com/v2/RegulatoryCompliance/Bundles?PageSize=50&Page=0\",\"next_page_url\": null,\"key\": \"results\"}}"
                         ));

            var response = BundleResource.Read(client: twilioRestClient);

            Assert.NotNull(response);
        }
Beispiel #12
0
        protected override string GenerateCommandLineCommands()
        {
            var prefixes     = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var intermediate = Path.Combine(IntermediateOutputPath, ToolName);
            var logicalName  = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId));
            var path         = Path.Combine(intermediate, logicalName);
            var args         = new CommandLineArgumentBuilder();
            var dir          = Path.GetDirectoryName(path);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            OutputFile = new TaskItem(Path.ChangeExtension(path, ".air"));
            OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air"));

            args.Add("-arch", "air64");
            args.Add("-emit-llvm");
            args.Add("-c");
            args.Add("-gline-tables-only");
            args.Add("-ffast-math");

            args.Add("-serialize-diagnostics");
            args.AddQuoted(Path.ChangeExtension(path, ".dia"));

            args.Add("-o");
            args.AddQuoted(Path.ChangeExtension(path, ".air"));

            if (Platform == ApplePlatform.MacCatalyst)
            {
                args.Add($"-target");
                args.Add($"air64-apple-ios{MinimumOSVersion}-macabi");
            }
            else
            {
                args.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));
            }
            args.AddQuoted(SourceFile.ItemSpec);

            return(args.ToString());
        }
Beispiel #13
0
        public void TestReadRequest()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();
            var request          = new Request(
                HttpMethod.Get,
                Twilio.Rest.Domain.Numbers,
                "/v2/RegulatoryCompliance/Bundles",
                ""
                );

            twilioRestClient.Request(request).Throws(new ApiException("Server Error, no content"));

            try
            {
                BundleResource.Read(client: twilioRestClient);
                Assert.Fail("Expected TwilioException to be thrown for 500");
            }
            catch (ApiException) {}
            twilioRestClient.Received().Request(request);
        }
        public override bool Execute()
        {
            if (Items != null)
            {
                var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix);

                foreach (var item in Items)
                {
                    var logical = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId));

                    if (logical == LogicalName)
                    {
                        Log.LogMessage(MessageImportance.Low, "  {0} found at: {1}", LogicalName, item.ItemSpec);
                        Item = item;
                        break;
                    }
                }
            }

            return(!Log.HasLoggedErrors);
        }
Beispiel #15
0
        public void TestCreateRequest()
        {
            var twilioRestClient = Substitute.For <ITwilioRestClient>();
            var request          = new Request(
                HttpMethod.Post,
                Twilio.Rest.Domain.Numbers,
                "/v2/RegulatoryCompliance/Bundles",
                ""
                );

            request.AddPostParam("FriendlyName", Serialize("friendly_name"));
            request.AddPostParam("Email", Serialize("email"));
            twilioRestClient.Request(request).Throws(new ApiException("Server Error, no content"));

            try
            {
                BundleResource.Create("friendly_name", "email", client: twilioRestClient);
                Assert.Fail("Expected TwilioException to be thrown for 500");
            }
            catch (ApiException) {}
            twilioRestClient.Received().Request(request);
        }
        private string TransformContent(BundleResource bundleResource, HttpContext context)
        {
            var bundleType = bundleResource.Type;
            var content = bundleResource.Content;
            var serverpath = bundleResource.ServerPath;

            try
            {
                if (bundleType == BundleResourceType.EmbeddedScript || bundleType == BundleResourceType.ScriptFile)
                {
                    var compressor = new JavaScriptCompressor
                    {
                        CompressionType = CompressionType.Standard,
                        Encoding = Encoding.UTF8,
                        ObfuscateJavascript = bundleResource.ObfuscateJs
                    };


                    //Minimize
                    var contentOut = compressor.Compress(content.Trim()) + ";";

                    //Return deffered execution
                    if (ClientSettings.IsJavascriptDefferingEnabled)
                    {
                        return string.Format(ClientSettings.JavascriptDefferingScript,
                                      JsonConvert.SerializeObject(contentOut));
                    }
                    return contentOut;
                }
                if (!string.IsNullOrEmpty(serverpath))
                {
                    string directoryName = Path.GetDirectoryName(serverpath);
                    if (directoryName != null)
                        serverpath = directoryName.Replace('\\', '/');
                }
                if (bundleType == BundleResourceType.EmbeddedStyle || bundleType == BundleResourceType.StyleFile)
                {
                    var compressor = new CssCompressor
                                         {
                                             CompressionType = CompressionType.Standard,
                                             RemoveComments = true
                                         };

                    return ReplaceUrls(compressor.Compress(content), serverpath, context);
                }
                if (bundleType == BundleResourceType.LessFile)
                {
                    DotlessConfiguration cfg = DotlessConfiguration.GetDefaultWeb();
                    cfg.Web = true;
                    cfg.MinifyOutput = true;
                    cfg.MapPathsToWeb = true;
                    cfg.CacheEnabled = false;

                    //Prefilter
                    content = ReplaceImportRegex.Replace(content, match => ReplaceImports(match, serverpath));
                    string processed = ReplaceUrls(LessWeb.Parse(content, cfg), serverpath, context);
                    return processed;
                }
            }
            catch (EcmaScript.NET.EcmaScriptException e)
            {
                _log.ErrorFormat("EcmaScriptException: {0} in {1} at {2} ({3}, {4}) at ", e.Message, serverpath, e.LineSource, e.LineNumber, e.ColumnNumber, e.ScriptStackTrace);
            }
            catch (Exception e)
            {
                _log.Error(e);
            }
            return content;
        }
 protected virtual string GetBundleRelativeOutputPath(IList <string> prefixes, ITaskItem input)
 {
     return(BundleResource.GetLogicalName(ProjectDir, prefixes, input));
 }
Beispiel #18
0
        public override bool Execute()
        {
            var    intermediate          = Path.Combine(IntermediateOutputPath, ToolName);
            var    intermediateBundleDir = Path.Combine(intermediate, "bundle");
            var    intermediateCloneDir  = Path.Combine(intermediate, "cloned-assets");
            var    manifest         = new TaskItem(Path.Combine(intermediate, "asset-manifest.plist"));
            var    bundleResources  = new List <ITaskItem> ();
            var    outputManifests  = new List <ITaskItem> ();
            var    catalogs         = new List <ITaskItem> ();
            var    unique           = new HashSet <string> ();
            string bundleIdentifier = null;
            var    knownSpecs       = new HashSet <string> ();
            var    clones           = new HashSet <string> ();
            var    items            = new List <ITaskItem> ();
            var    specs            = new PArray();

            Log.LogTaskName("ACTool");
            Log.LogTaskProperty("AppManifest", AppManifest);
            Log.LogTaskProperty("DeviceModel", DeviceModel);
            Log.LogTaskProperty("DeviceOSVersion", DeviceOSVersion);
            Log.LogTaskProperty("EnableOnDemandResources", EnableOnDemandResources);
            Log.LogTaskProperty("ImageAssets", ImageAssets);
            Log.LogTaskProperty("IntermediateOutputPath", IntermediateOutputPath);
            Log.LogTaskProperty("IsWatchApp", IsWatchApp);
            Log.LogTaskProperty("OptimizePNGs", OptimizePNGs);
            Log.LogTaskProperty("OutputPath", OutputPath);
            Log.LogTaskProperty("ProjectDir", ProjectDir);
            Log.LogTaskProperty("ResourcePrefix", ResourcePrefix);
            Log.LogTaskProperty("SdkBinPath", SdkBinPath);
            Log.LogTaskProperty("SdkPlatform", SdkPlatform);
            Log.LogTaskProperty("SdkVersion", SdkVersion);

            switch (SdkPlatform)
            {
            case "iPhoneSimulator":
            case "iPhoneOS":
            case "MacOSX":
            case "WatchSimulator":
            case "WatchOS":
            case "AppleTVSimulator":
            case "AppleTVOS":
                break;

            default:
                Log.LogError("Unrecognized platform: {0}", SdkPlatform);
                return(false);
            }

            if (AppManifest != null)
            {
                try {
                    plist = PDictionary.FromFile(AppManifest.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "{0}", ex.Message);
                    return(false);
                }

                bundleIdentifier = plist.GetCFBundleIdentifier();
            }

            for (int i = 0; i < ImageAssets.Length; i++)
            {
                var vpath = BundleResource.GetVirtualProjectPath(ProjectDir, ImageAssets[i], !string.IsNullOrEmpty(SessionId));

                // Ignore MacOS .DS_Store files...
                if (Path.GetFileName(vpath).Equals(".DS_Store", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
                var catalog = Path.GetDirectoryName(vpath);

                // keep walking up the directory structure until we get to the .xcassets directory
                while (!string.IsNullOrEmpty(catalog) && Path.GetExtension(catalog) != ".xcassets")
                {
                    catalog = Path.GetDirectoryName(catalog);
                }

                if (string.IsNullOrEmpty(catalog))
                {
                    Log.LogWarning(null, null, null, ImageAssets[i].ItemSpec, 0, 0, 0, 0, "Asset not part of an asset catalog: {0}", ImageAssets[i].ItemSpec);
                    continue;
                }

                if (ImageAssets[i].GetMetadata("Link") != null)
                {
                    // Note: if any of the files within a catalog are linked, we'll have to clone the *entire* catalog
                    clones.Add(catalog);
                    continue;
                }

                // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                if (Path.GetFileName(vpath) != "Contents.json")
                {
                    continue;
                }

                items.Add(ImageAssets[i]);
            }

            // clone any *.xcassets dirs that need cloning
            if (clones.Count > 0)
            {
                if (Directory.Exists(intermediateCloneDir))
                {
                    Directory.Delete(intermediateCloneDir, true);
                }

                Directory.CreateDirectory(intermediateCloneDir);

                items.Clear();

                for (int i = 0; i < ImageAssets.Length; i++)
                {
                    var       vpath = BundleResource.GetVirtualProjectPath(ProjectDir, ImageAssets[i], !string.IsNullOrEmpty(SessionId));
                    var       clone = false;
                    ITaskItem item;

                    // Ignore MacOS .DS_Store files...
                    if (Path.GetFileName(vpath).Equals(".DS_Store", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    foreach (var catalog in clones)
                    {
                        if (vpath.Length > catalog.Length && vpath[catalog.Length] == '/' && vpath.StartsWith(catalog, StringComparison.Ordinal))
                        {
                            clone = true;
                            break;
                        }
                    }

                    if (clone)
                    {
                        var src = ImageAssets[i].GetMetadata("FullPath");

                        if (!File.Exists(src))
                        {
                            Log.LogError(null, null, null, src, 0, 0, 0, 0, "File not found: {0}", src);
                            return(false);
                        }

                        var dest = Path.Combine(intermediateCloneDir, vpath);
                        var dir  = Path.GetDirectoryName(dest);

                        Directory.CreateDirectory(dir);

                        File.Copy(src, dest, true);

                        // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                        if (Path.GetFileName(vpath) != "Contents.json")
                        {
                            continue;
                        }

                        item = new TaskItem(dest);
                        ImageAssets[i].CopyMetadataTo(item);
                        item.SetMetadata("Link", vpath);
                    }
                    else
                    {
                        // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                        if (Path.GetFileName(vpath) != "Contents.json")
                        {
                            continue;
                        }

                        item = ImageAssets[i];
                    }

                    items.Add(item);
                }
            }

            // Note: `items` contains only the Contents.json files at this point
            for (int i = 0; i < items.Count; i++)
            {
                var vpath = BundleResource.GetVirtualProjectPath(ProjectDir, items[i], !string.IsNullOrEmpty(SessionId));
                var path  = items[i].GetMetadata("FullPath");

                // get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
                var catalog = Path.GetDirectoryName(vpath);
                path = Path.GetDirectoryName(path);

                // keep walking up the directory structure until we get to the .xcassets directory
                while (!string.IsNullOrEmpty(catalog) && Path.GetExtension(catalog) != ".xcassets")
                {
                    catalog = Path.GetDirectoryName(catalog);
                    path    = Path.GetDirectoryName(path);
                }

                if (unique.Add(catalog))
                {
                    var item = new TaskItem(path);
                    item.SetMetadata("Link", catalog);

                    catalogs.Add(item);
                }

                if (AppleSdkSettings.XcodeVersion.Major >= 7 && !string.IsNullOrEmpty(bundleIdentifier) && SdkPlatform != "WatchSimulator")
                {
                    var text = File.ReadAllText(items[i].ItemSpec);

                    if (string.IsNullOrEmpty(text))
                    {
                        continue;
                    }

                    var json = JsonConvert.DeserializeObject(text) as JObject;

                    if (json == null)
                    {
                        continue;
                    }

                    var properties = json.Property("properties");

                    if (properties == null)
                    {
                        continue;
                    }

                    var resourceTags = properties.Value.ToObject <JObject> ().Property("on-demand-resource-tags");

                    if (resourceTags == null || resourceTags.Value.Type != JTokenType.Array)
                    {
                        continue;
                    }

                    var    tagArray = resourceTags.Value.ToObject <JArray> ();
                    var    tags     = new HashSet <string> ();
                    string hash;

                    foreach (var tag in tagArray.Select(token => token.ToObject <string> ()))
                    {
                        tags.Add(tag);
                    }

                    var tagList = tags.ToList();
                    tagList.Sort();

                    var assetDir = AssetPackUtils.GetAssetPackDirectory(intermediate, bundleIdentifier, tagList, out hash);

                    if (knownSpecs.Add(hash))
                    {
                        var assetpack = new PDictionary();
                        var ptags     = new PArray();

                        Directory.CreateDirectory(assetDir);

                        for (int j = 0; j < tagList.Count; j++)
                        {
                            ptags.Add(new PString(tagList[j]));
                        }

                        assetpack.Add("bundle-id", new PString(string.Format("{0}.asset-pack-{1}", bundleIdentifier, hash)));
                        assetpack.Add("bundle-path", new PString(Path.GetFullPath(assetDir)));
                        assetpack.Add("tags", ptags);
                        specs.Add(assetpack);
                    }
                }
            }

            if (catalogs.Count == 0)
            {
                // There are no (supported?) asset catalogs
                return(true);
            }

            partialAppManifest = new TaskItem(Path.Combine(intermediate, "partial-info.plist"));

            if (specs.Count > 0)
            {
                outputSpecs = Path.Combine(intermediate, "output-specifications.plist");
                specs.Save(outputSpecs, true);
            }

            Directory.CreateDirectory(intermediateBundleDir);

            // Note: Compile() will set the PartialAppManifest property if it is used...
            if ((Compile(catalogs.ToArray(), intermediateBundleDir, manifest)) != 0)
            {
                return(false);
            }

            if (PartialAppManifest != null && !File.Exists(PartialAppManifest.GetMetadata("FullPath")))
            {
                Log.LogError("Partial Info.plist file was not generated: {0}", PartialAppManifest.GetMetadata("FullPath"));
            }

            try {
                var manifestOutput = PDictionary.FromFile(manifest.ItemSpec);

                LogWarningsAndErrors(manifestOutput, catalogs[0]);

                bundleResources.AddRange(GetCompiledBundleResources(manifestOutput, intermediateBundleDir));
                outputManifests.Add(manifest);
            } catch (Exception ex) {
                Log.LogError("Failed to load output manifest for {0} for the file {2}: {1}", ToolName, ex.Message, manifest.ItemSpec);
            }

            foreach (var assetpack in specs.OfType <PDictionary> ())
            {
                var path       = Path.Combine(assetpack.GetString("bundle-path").Value, "Info.plist");
                var bundlePath = PathUtils.AbsoluteToRelative(intermediate, path);
                var outputPath = Path.Combine(OutputPath, bundlePath);
                var rpath      = Path.Combine(intermediate, bundlePath);
                var dict       = new PDictionary();

                dict.SetCFBundleIdentifier(assetpack.GetString("bundle-id").Value);
                dict.Add("Tags", assetpack.GetArray("tags").Clone());

                dict.Save(path, true, true);

                var item = new TaskItem(rpath);
                item.SetMetadata("LogicalName", bundlePath);
                item.SetMetadata("OutputPath", outputPath);
                item.SetMetadata("Optimize", "false");

                bundleResources.Add(item);
            }

            BundleResources = bundleResources.ToArray();
            OutputManifests = outputManifests.ToArray();

            return(!Log.HasLoggedErrors);
        }
        public override bool Execute()
        {
            Log.LogTaskName("CompileSceneKitAssets");
            Log.LogTaskProperty("IntermediateOutputPath", IntermediateOutputPath);
            Log.LogTaskProperty("ProjectDir", ProjectDir);
            Log.LogTaskProperty("ResourcePrefix", ResourcePrefix);
            Log.LogTaskProperty("SceneKitAssets", SceneKitAssets);
            Log.LogTaskProperty("SdkDevPath", SdkDevPath);
            Log.LogTaskProperty("SdkRoot", SdkRoot);
            Log.LogTaskProperty("SdkVersion", SdkVersion);

            var    prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var    intermediate    = Path.Combine(IntermediateOutputPath, ToolName);
            var    bundleResources = new List <ITaskItem> ();
            var    modified        = new HashSet <string> ();
            var    items           = new List <ITaskItem> ();
            string metadata;

            foreach (var asset in SceneKitAssets)
            {
                if (!File.Exists(asset.ItemSpec))
                {
                    continue;
                }

                // get the .scnassets directory path
                var scnassets = Path.GetDirectoryName(asset.ItemSpec);
                while (scnassets.Length > 0 && Path.GetExtension(scnassets).ToLowerInvariant() != ".scnassets")
                {
                    scnassets = Path.GetDirectoryName(scnassets);
                }

                if (scnassets.Length == 0)
                {
                    continue;
                }

                metadata = asset.GetMetadata("LogicalName");
                if (!string.IsNullOrEmpty(metadata))
                {
                    asset.SetMetadata("LogicalName", string.Empty);
                }

                var bundleName = BundleResource.GetLogicalName(ProjectDir, prefixes, asset, !string.IsNullOrEmpty(SessionId));
                var output     = new TaskItem(Path.Combine(intermediate, bundleName));

                if (!modified.Contains(scnassets) && (!File.Exists(output.ItemSpec) || File.GetLastWriteTimeUtc(asset.ItemSpec) > File.GetLastWriteTimeUtc(output.ItemSpec)))
                {
                    var item = new TaskItem(scnassets);

                    metadata = asset.GetMetadata("DefiningProjectFullPath");
                    if (!string.IsNullOrEmpty(metadata))
                    {
                        item.SetMetadata("DefiningProjectFullPath", metadata);
                    }

                    modified.Add(scnassets);
                    items.Add(item);
                }

                output.SetMetadata("LogicalName", bundleName);
                output.SetMetadata("Optimize", "false");
                bundleResources.Add(output);
            }

            if (modified.Count == 0)
            {
                BundleResources = bundleResources.ToArray();
                return(!Log.HasLoggedErrors);
            }

            if (!Directory.Exists(intermediate))
            {
                Directory.CreateDirectory(intermediate);
            }

            foreach (var item in items)
            {
                var bundleDir = BundleResource.GetLogicalName(ProjectDir, prefixes, new TaskItem(item), !string.IsNullOrEmpty(SessionId));
                var output    = Path.Combine(intermediate, bundleDir);

                if (CopySceneKitAssets(item.ItemSpec, output, intermediate) == -1)
                {
                    return(false);
                }
            }

            BundleResources = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
        public override bool Execute()
        {
            var    intermediate          = Path.Combine(IntermediateOutputPath, ToolName);
            var    intermediateBundleDir = Path.Combine(intermediate, "bundle");
            var    manifest         = new TaskItem(Path.Combine(intermediate, "asset-manifest.plist"));
            var    bundleResources  = new List <ITaskItem> ();
            var    outputManifests  = new List <ITaskItem> ();
            var    catalogs         = new List <ITaskItem> ();
            var    unique           = new HashSet <string> ();
            string bundleIdentifier = null;
            var    knownSpecs       = new HashSet <string> ();
            var    specs            = new PArray();
            int    rc;

            Log.LogTaskName("ACTool");
            Log.LogTaskProperty("AppManifest", AppManifest);
            Log.LogTaskProperty("DeviceModel", DeviceModel);
            Log.LogTaskProperty("DeviceOSVersion", DeviceOSVersion);
            Log.LogTaskProperty("ImageAssets", ImageAssets);
            Log.LogTaskProperty("IntermediateOutputPath", IntermediateOutputPath);
            Log.LogTaskProperty("IsWatchApp", IsWatchApp);
            Log.LogTaskProperty("OptimizePNGs", OptimizePNGs);
            Log.LogTaskProperty("OutputPath", OutputPath);
            Log.LogTaskProperty("ProjectDir", ProjectDir);
            Log.LogTaskProperty("ResourcePrefix", ResourcePrefix);
            Log.LogTaskProperty("SdkBinPath", SdkBinPath);
            Log.LogTaskProperty("SdkPlatform", SdkPlatform);
            Log.LogTaskProperty("SdkVersion", SdkVersion);

            switch (SdkPlatform)
            {
            case "iPhoneSimulator":
            case "iPhoneOS":
            case "MacOSX":
            case "WatchSimulator":
            case "WatchOS":
            case "AppleTVSimulator":
            case "AppleTVOS":
                break;

            default:
                Log.LogError("Unrecognized platform: {0}", SdkPlatform);
                return(false);
            }

            if (AppManifest != null)
            {
                try {
                    plist = PDictionary.FromFile(AppManifest.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "{0}", ex.Message);
                    return(false);
                }

                bundleIdentifier = plist.GetCFBundleIdentifier();
            }

            foreach (var asset in ImageAssets)
            {
                var vpath = BundleResource.GetVirtualProjectPath(ProjectDir, asset);
                if (Path.GetFileName(vpath) != "Contents.json")
                {
                    continue;
                }

                // get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
                var catalog = Path.GetDirectoryName(vpath);

                // keep walking up the directory structure until we get to the .xcassets directory
                while (!string.IsNullOrEmpty(catalog) && Path.GetExtension(catalog) != ".xcassets")
                {
                    catalog = Path.GetDirectoryName(catalog);
                }

                if (string.IsNullOrEmpty(catalog))
                {
                    Log.LogWarning(null, null, null, asset.ItemSpec, 0, 0, 0, 0, "Asset not part of an asset catalog: {0}", asset.ItemSpec);
                    continue;
                }

                if (unique.Add(catalog))
                {
                    catalogs.Add(new TaskItem(catalog));
                }

                if (AppleSdkSettings.XcodeVersion.Major >= 7 && !string.IsNullOrEmpty(bundleIdentifier) && SdkPlatform != "WatchSimulator")
                {
                    var text = File.ReadAllText(asset.ItemSpec);

                    if (string.IsNullOrEmpty(text))
                    {
                        continue;
                    }

                    var json = JsonConvert.DeserializeObject(text) as JObject;

                    if (json == null)
                    {
                        continue;
                    }

                    var properties = json.Property("properties");

                    if (properties == null)
                    {
                        continue;
                    }

                    var resourceTags = properties.Value.ToObject <JObject> ().Property("on-demand-resource-tags");

                    if (resourceTags == null || resourceTags.Value.Type != JTokenType.Array)
                    {
                        continue;
                    }

                    var    tagArray = resourceTags.Value.ToObject <JArray> ();
                    var    tags     = new HashSet <string> ();
                    string hash;

                    foreach (var tag in tagArray.Select(token => token.ToObject <string> ()))
                    {
                        tags.Add(tag);
                    }

                    var tagList = tags.ToList();
                    tagList.Sort();

                    var path = AssetPackUtils.GetAssetPackDirectory(intermediate, bundleIdentifier, tagList, out hash);

                    if (knownSpecs.Add(hash))
                    {
                        var assetpack = new PDictionary();
                        var ptags     = new PArray();

                        Directory.CreateDirectory(path);

                        for (int i = 0; i < tags.Count; i++)
                        {
                            ptags.Add(new PString(tagList[i]));
                        }

                        assetpack.Add("bundle-id", new PString(string.Format("{0}.asset-pack-{1}", bundleIdentifier, hash)));
                        assetpack.Add("bundle-path", new PString(Path.GetFullPath(path)));
                        assetpack.Add("tags", ptags);
                        specs.Add(assetpack);
                    }
                }
            }

            if (catalogs.Count == 0)
            {
                // There are no (supported?) asset catalogs
                return(true);
            }

            partialAppManifest = new TaskItem(Path.Combine(intermediate, "partial-info.plist"));

            if (specs.Count > 0)
            {
                outputSpecs = Path.Combine(intermediate, "output-specifications.plist");
                specs.Save(outputSpecs, true);
            }

            var output = new TaskItem(intermediateBundleDir);

            Directory.CreateDirectory(intermediateBundleDir);

            // Note: Compile() will set the PartialAppManifest property if it is used...
            if ((rc = Compile(catalogs.ToArray(), output, manifest)) != 0)
            {
                if (File.Exists(manifest.ItemSpec))
                {
                    try {
                        var log = PDictionary.FromFile(manifest.ItemSpec);

                        LogWarningsAndErrors(log, catalogs[0]);
                    } catch (FormatException) {
                        Log.LogError("actool exited with code {0}", rc);
                    }

                    File.Delete(manifest.ItemSpec);
                }

                return(false);
            }

            if (PartialAppManifest != null && !File.Exists(PartialAppManifest.GetMetadata("FullPath")))
            {
                Log.LogError("Partial Info.plist file was not generated: {0}", PartialAppManifest.GetMetadata("FullPath"));
            }

            try {
                var manifestOutput = PDictionary.FromFile(manifest.ItemSpec);

                LogWarningsAndErrors(manifestOutput, catalogs[0]);

                bundleResources.AddRange(GetCompiledBundleResources(manifestOutput, intermediateBundleDir));
                outputManifests.Add(manifest);
            } catch (Exception ex) {
                Log.LogError("Failed to load output manifest for {0} for the file {2}: {1}", ToolName, ex.Message, manifest.ItemSpec);
            }

            foreach (var assetpack in specs.OfType <PDictionary> ())
            {
                var path       = Path.Combine(assetpack.GetString("bundle-path").Value, "Info.plist");
                var bundlePath = PathUtils.AbsoluteToRelative(intermediate, path);
                var outputPath = Path.Combine(OutputPath, bundlePath);
                var rpath      = Path.Combine(intermediate, bundlePath);
                var dict       = new PDictionary();

                dict.SetCFBundleIdentifier(assetpack.GetString("bundle-id").Value);
                dict.Add("Tags", assetpack.GetArray("tags").Clone());

                dict.Save(path, true, true);

                var item = new TaskItem(rpath);
                item.SetMetadata("LogicalName", bundlePath);
                item.SetMetadata("OutputPath", outputPath);
                item.SetMetadata("Optimize", "false");

                bundleResources.Add(item);
            }

            BundleResources = bundleResources.ToArray();
            OutputManifests = outputManifests.ToArray();

            return(!Log.HasLoggedErrors);
        }
Beispiel #21
0
        protected override void AppendCommandLineArguments(IDictionary <string, string> environment, ProcessArgumentBuilder args, ITaskItem[] items)
        {
            string minimumDeploymentTarget;

            if (plist != null)
            {
                PString value;

                if (!plist.TryGetValue(MinimumDeploymentTargetKey, out value) || string.IsNullOrEmpty(value.Value))
                {
                    minimumDeploymentTarget = SdkVersion;
                }
                else
                {
                    minimumDeploymentTarget = value.Value;
                }

                var assetDirs = new HashSet <string> (items.Select(x => BundleResource.GetVirtualProjectPath(ProjectDir, x, !string.IsNullOrEmpty(SessionId))));

                if (plist.TryGetValue(ManifestKeys.XSAppIconAssets, out value) && !string.IsNullOrEmpty(value.Value))
                {
                    int    index    = value.Value.IndexOf(".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
                    string assetDir = null;
                    var    rpath    = value.Value;

                    if (index != -1)
                    {
                        assetDir = rpath.Substring(0, index + ".xcassets".Length);
                    }

                    if (assetDirs != null && assetDirs.Contains(assetDir))
                    {
                        var assetName = Path.GetFileNameWithoutExtension(rpath);

                        if (PartialAppManifest == null)
                        {
                            args.Add("--output-partial-info-plist");
                            args.AddQuoted(partialAppManifest.GetMetadata("FullPath"));

                            PartialAppManifest = partialAppManifest;
                        }

                        args.Add("--app-icon");
                        args.AddQuoted(assetName);

                        if (IsMessagesExtension(plist))
                        {
                            args.Add("--product-type com.apple.product-type.app-extension.messages");
                        }
                    }
                }

                if (plist.TryGetValue(ManifestKeys.XSLaunchImageAssets, out value) && !string.IsNullOrEmpty(value.Value))
                {
                    int    index    = value.Value.IndexOf(".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
                    string assetDir = null;
                    var    rpath    = value.Value;

                    if (index != -1)
                    {
                        assetDir = rpath.Substring(0, index + ".xcassets".Length);
                    }

                    if (assetDirs != null && assetDirs.Contains(assetDir))
                    {
                        var assetName = Path.GetFileNameWithoutExtension(rpath);

                        if (PartialAppManifest == null)
                        {
                            args.Add("--output-partial-info-plist");
                            args.AddQuoted(partialAppManifest.GetMetadata("FullPath"));

                            PartialAppManifest = partialAppManifest;
                        }

                        args.Add("--launch-image");
                        args.AddQuoted(assetName);
                    }
                }

                if (plist.TryGetValue(ManifestKeys.CLKComplicationGroup, out value) && !string.IsNullOrEmpty(value.Value))
                {
                    args.Add("--complication", value);
                }
            }
            else
            {
                minimumDeploymentTarget = SdkVersion;
            }

            if (OptimizePNGs)
            {
                args.Add("--compress-pngs");
            }

            if (AppleSdkSettings.XcodeVersion.Major >= 7)
            {
                if (!string.IsNullOrEmpty(outputSpecs))
                {
                    args.Add("--enable-on-demand-resources", EnableOnDemandResources ? "YES" : "NO");
                }

                if (!string.IsNullOrEmpty(DeviceModel))
                {
                    args.Add("--filter-for-device-model", DeviceModel);
                }

                if (!string.IsNullOrEmpty(DeviceOSVersion))
                {
                    args.Add("--filter-for-device-os-version", DeviceOSVersion);
                }

                if (!string.IsNullOrEmpty(outputSpecs))
                {
                    args.Add("--asset-pack-output-specifications");
                    args.AddQuoted(Path.GetFullPath(outputSpecs));
                }
            }

            if (plist != null)
            {
                foreach (var targetDevice in GetTargetDevices(plist))
                {
                    args.Add("--target-device", targetDevice);
                }
            }

            args.Add("--minimum-deployment-target", minimumDeploymentTarget);

            switch (SdkPlatform)
            {
            case "iPhoneSimulator":
                args.Add("--platform", IsWatchApp ? "watchsimulator" : "iphonesimulator");
                break;

            case "iPhoneOS":
                args.Add("--platform", IsWatchApp ? "watchos" : "iphoneos");
                break;

            case "MacOSX":
                args.Add("--platform", "macosx");
                break;

            case "WatchSimulator":
                args.Add("--platform", "watchsimulator");
                break;

            case "WatchOS":
                args.Add("--platform", "watchos");
                break;

            case "AppleTVSimulator":
                args.Add("--platform", "appletvsimulator");
                break;

            case "AppleTVOS":
                args.Add("--platform", "appletvos");
                break;
            }
        }
        void RegisterFonts(PDictionary plist)
        {
            if (FontFilesToRegister == null || FontFilesToRegister.Length == 0)
            {
                return;
            }

            // https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text

            // Compute the relative location in the app bundle for each font file
            var          prefixes       = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            const string logicalNameKey = "_ComputedLogicalName_";

            foreach (var item in FontFilesToRegister)
            {
                var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId));
                item.SetMetadata(logicalNameKey, logicalName);
            }

            switch (Platform)
            {
            case ApplePlatform.iOS:
            case ApplePlatform.TVOS:
            case ApplePlatform.WatchOS:
            case ApplePlatform.MacCatalyst:
                // Fonts are listed in the Info.plist in a UIAppFonts entry for iOS, tvOS, watchOS and Mac Catalyst.
                var uiAppFonts = plist.GetArray("UIAppFonts");
                if (uiAppFonts == null)
                {
                    uiAppFonts           = new PArray();
                    plist ["UIAppFonts"] = uiAppFonts;
                }
                foreach (var item in FontFilesToRegister)
                {
                    uiAppFonts.Add(new PString(item.GetMetadata(logicalNameKey)));
                }
                break;

            case ApplePlatform.MacOSX:
                // The directory where the fonts are located is in the Info.plist in the ATSApplicationFontsPath entry for macOS.
                // It's relative to the Resources directory.
                // Make sure that all the fonts are in the same directory in the app bundle
                var allSubdirectories      = FontFilesToRegister.Select(v => Path.GetDirectoryName(v.GetMetadata(logicalNameKey)));
                var distinctSubdirectories = allSubdirectories.Distinct().ToArray();
                if (distinctSubdirectories.Length > 1)
                {
                    Log.LogError(MSBStrings.E7083 /* "All font files must be located in the same directory in the app bundle. The following font files have different target directories in the app bundle:" */, CompiledAppManifest.ItemSpec);
                    foreach (var fonts in FontFilesToRegister)
                    {
                        Log.LogError(null, null, null, fonts.ItemSpec, 0, 0, 0, 0, MSBStrings.E7084 /* "The target directory is {0}" */, fonts.GetMetadata(logicalNameKey));
                    }
                }
                else
                {
                    plist.SetIfNotPresent("ATSApplicationFontsPath", string.IsNullOrEmpty(distinctSubdirectories [0]) ? "." : distinctSubdirectories [0]);
                }
                break;

            default:
                throw new InvalidOperationException(string.Format(MSBStrings.InvalidPlatform, Platform));
            }
        }
Beispiel #23
0
        public override bool Execute()
        {
            var intermediate          = Path.Combine(IntermediateOutputPath, ToolName);
            var intermediateBundleDir = Path.Combine(intermediate, "bundle");
            var intermediateCloneDir  = Path.Combine(intermediate, "cloned-assets");
            var manifest        = new TaskItem(Path.Combine(intermediate, "asset-manifest.plist"));
            var bundleResources = new List <ITaskItem> ();
            var outputManifests = new List <ITaskItem> ();
            var catalogs        = new List <ITaskItem> ();
            var unique          = new HashSet <string> ();

            var knownSpecs = new HashSet <string> ();
            var clones     = new HashSet <string> ();
            var items      = new List <ITaskItem> ();
            var specs      = new PArray();

            if (AppManifest != null)
            {
                try {
                    plist = PDictionary.FromFile(AppManifest.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "{0}", ex.Message);
                    return(false);
                }
            }

            for (int i = 0; i < ImageAssets.Length; i++)
            {
                var vpath = BundleResource.GetVirtualProjectPath(ProjectDir, ImageAssets[i], !string.IsNullOrEmpty(SessionId));

                // Ignore MacOS .DS_Store files...
                if (Path.GetFileName(vpath).Equals(".DS_Store", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
                var catalog = Path.GetDirectoryName(vpath);

                // keep walking up the directory structure until we get to the .xcassets directory
                while (!string.IsNullOrEmpty(catalog) && Path.GetExtension(catalog) != ".xcassets")
                {
                    catalog = Path.GetDirectoryName(catalog);
                }

                if (string.IsNullOrEmpty(catalog))
                {
                    Log.LogWarning(null, null, null, ImageAssets[i].ItemSpec, 0, 0, 0, 0, MSBStrings.W0090, ImageAssets[i].ItemSpec);
                    continue;
                }

                if (ImageAssets[i].GetMetadata("Link") != null)
                {
                    // Note: if any of the files within a catalog are linked, we'll have to clone the *entire* catalog
                    clones.Add(catalog);
                    continue;
                }

                // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                if (Path.GetFileName(vpath) != "Contents.json")
                {
                    continue;
                }

                items.Add(ImageAssets[i]);
            }

            // clone any *.xcassets dirs that need cloning
            if (clones.Count > 0)
            {
                if (Directory.Exists(intermediateCloneDir))
                {
                    Directory.Delete(intermediateCloneDir, true);
                }

                Directory.CreateDirectory(intermediateCloneDir);

                items.Clear();

                for (int i = 0; i < ImageAssets.Length; i++)
                {
                    var       vpath = BundleResource.GetVirtualProjectPath(ProjectDir, ImageAssets[i], !string.IsNullOrEmpty(SessionId));
                    var       clone = false;
                    ITaskItem item;

                    // Ignore MacOS .DS_Store files...
                    if (Path.GetFileName(vpath).Equals(".DS_Store", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    foreach (var catalog in clones)
                    {
                        if (vpath.Length > catalog.Length && vpath[catalog.Length] == '/' && vpath.StartsWith(catalog, StringComparison.Ordinal))
                        {
                            clone = true;
                            break;
                        }
                    }

                    if (clone)
                    {
                        var src = ImageAssets[i].GetMetadata("FullPath");

                        if (!File.Exists(src))
                        {
                            Log.LogError(null, null, null, src, 0, 0, 0, 0, MSBStrings.E0091, src);
                            return(false);
                        }

                        var dest = Path.Combine(intermediateCloneDir, vpath);
                        var dir  = Path.GetDirectoryName(dest);

                        Directory.CreateDirectory(dir);

                        File.Copy(src, dest, true);

                        // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                        if (Path.GetFileName(vpath) != "Contents.json")
                        {
                            continue;
                        }

                        item = new TaskItem(dest);
                        ImageAssets[i].CopyMetadataTo(item);
                        item.SetMetadata("Link", vpath);
                    }
                    else
                    {
                        // filter out everything except paths containing a Contents.json file since our main processing loop only cares about these
                        if (Path.GetFileName(vpath) != "Contents.json")
                        {
                            continue;
                        }

                        item = ImageAssets[i];
                    }

                    items.Add(item);
                }
            }

            // Note: `items` contains only the Contents.json files at this point
            for (int i = 0; i < items.Count; i++)
            {
                var vpath = BundleResource.GetVirtualProjectPath(ProjectDir, items[i], !string.IsNullOrEmpty(SessionId));
                var path  = items[i].GetMetadata("FullPath");

                // get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
                var catalog = Path.GetDirectoryName(vpath);
                path = Path.GetDirectoryName(path);

                // keep walking up the directory structure until we get to the .xcassets directory
                while (!string.IsNullOrEmpty(catalog) && Path.GetExtension(catalog) != ".xcassets")
                {
                    catalog = Path.GetDirectoryName(catalog);
                    path    = Path.GetDirectoryName(path);
                }

                if (unique.Add(catalog))
                {
                    var item = new TaskItem(path);
                    item.SetMetadata("Link", catalog);

                    catalogs.Add(item);
                }

                if (AppleSdkSettings.XcodeVersion.Major >= 7 && SdkPlatform != "WatchSimulator")
                {
                    var text = File.ReadAllText(items[i].ItemSpec);

                    if (string.IsNullOrEmpty(text))
                    {
                        continue;
                    }

                    JsonDocument json;
                    JsonElement  value;

                    try {
                        var options = new JsonDocumentOptions()
                        {
                            AllowTrailingCommas = true,
                        };
                        json = JsonDocument.Parse(text, options);
                    } catch (JsonException je) {
                        var line = (int)(je.LineNumber + 1 ?? 0);
                        var col  = (int)(je.BytePositionInLine + 1 ?? 0);
                        Log.LogError(null, null, null, items [i].ItemSpec, line, col, line, col, "{0}", je.Message);
                        return(false);
                    } catch (Exception e) {
                        Log.LogError(null, null, null, items[i].ItemSpec, 0, 0, 0, 0, MSBStrings.E0092, e.Message);
                        return(false);
                    }

                    if (!json.RootElement.TryGetProperty("properties", out value) || value.ValueKind != JsonValueKind.Object)
                    {
                        continue;
                    }

                    var properties = value;

                    if (!properties.TryGetProperty("on-demand-resource-tags", out value) || value.ValueKind != JsonValueKind.Array)
                    {
                        continue;
                    }

                    var    resourceTags = value;
                    var    tags         = new HashSet <string> ();
                    string hash;

                    foreach (var tag in resourceTags.EnumerateArray())
                    {
                        if (tag.ValueKind == JsonValueKind.String)
                        {
                            tags.Add(tag.GetString());
                        }
                    }

                    var tagList = tags.ToList();
                    tagList.Sort();

                    var assetDir = AssetPackUtils.GetAssetPackDirectory(intermediate, BundleIdentifier, tagList, out hash);

                    if (knownSpecs.Add(hash))
                    {
                        var assetpack = new PDictionary();
                        var ptags     = new PArray();

                        Directory.CreateDirectory(assetDir);

                        for (int j = 0; j < tagList.Count; j++)
                        {
                            ptags.Add(new PString(tagList[j]));
                        }

                        assetpack.Add("bundle-id", new PString(string.Format("{0}.asset-pack-{1}", BundleIdentifier, hash)));
                        assetpack.Add("bundle-path", new PString(Path.GetFullPath(assetDir)));
                        assetpack.Add("tags", ptags);
                        specs.Add(assetpack);
                    }
                }
            }

            if (catalogs.Count == 0)
            {
                // There are no (supported?) asset catalogs
                return(!Log.HasLoggedErrors);
            }

            partialAppManifest = new TaskItem(Path.Combine(intermediate, "partial-info.plist"));

            if (specs.Count > 0)
            {
                outputSpecs = Path.Combine(intermediate, "output-specifications.plist");
                specs.Save(outputSpecs, true);
            }

            Directory.CreateDirectory(intermediateBundleDir);

            // Note: Compile() will set the PartialAppManifest property if it is used...
            if ((Compile(catalogs.ToArray(), intermediateBundleDir, manifest)) != 0)
            {
                return(false);
            }

            if (PartialAppManifest != null && !File.Exists(PartialAppManifest.GetMetadata("FullPath")))
            {
                Log.LogError(MSBStrings.E0093, PartialAppManifest.GetMetadata("FullPath"));
            }

            try {
                var manifestOutput = PDictionary.FromFile(manifest.ItemSpec);

                LogWarningsAndErrors(manifestOutput, catalogs[0]);

                bundleResources.AddRange(GetCompiledBundleResources(manifestOutput, intermediateBundleDir));
                outputManifests.Add(manifest);
            } catch (Exception ex) {
                Log.LogError(MSBStrings.E0094, ToolName, manifest.ItemSpec, ex.Message);
            }

            foreach (var assetpack in specs.OfType <PDictionary> ())
            {
                var path       = Path.Combine(assetpack.GetString("bundle-path").Value, "Info.plist");
                var bundlePath = PathUtils.AbsoluteToRelative(intermediate, path);
                var outputPath = Path.Combine(OutputPath, bundlePath);
                var rpath      = Path.Combine(intermediate, bundlePath);
                var dict       = new PDictionary();

                dict.SetCFBundleIdentifier(assetpack.GetString("bundle-id").Value);
                dict.Add("Tags", assetpack.GetArray("tags").Clone());

                dict.Save(path, true, true);

                var item = new TaskItem(rpath);
                item.SetMetadata("LogicalName", bundlePath);
                item.SetMetadata("OutputPath", outputPath);
                item.SetMetadata("Optimize", "false");

                bundleResources.Add(item);
            }

            BundleResources = bundleResources.ToArray();
            OutputManifests = outputManifests.ToArray();

            return(!Log.HasLoggedErrors);
        }
Beispiel #24
0
        public override bool Execute()
        {
            var prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var bundleResources = new List <ITaskItem> ();

            if (BundleResources != null)
            {
                foreach (var item in BundleResources)
                {
                    var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId));
                    // We need a physical path here, ignore the Link element
                    var    path = item.GetMetadata("FullPath");
                    string illegal;

                    if (!File.Exists(path))
                    {
                        Log.LogError("  Bundle Resource '{0}' not found on disk (should be at '{1}')", logicalName, path);
                        continue;
                    }

                    if (logicalName.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal))
                    {
                        Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, "The path '{0}' would result in a file outside of the app bundle and cannot be used.", logicalName);
                        continue;
                    }

                    if (logicalName == "Info.plist")
                    {
                        Log.LogWarning(null, null, null, item.ItemSpec, 0, 0, 0, 0, "Info.plist files should have a Build Action of 'None'.");
                        continue;
                    }

                    if (BundleResource.IsIllegalName(logicalName, out illegal))
                    {
                        Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, "The name '{0}' is reserved and cannot be used.", illegal);
                        continue;
                    }

                    var bundleResource = new TaskItem(item);
                    bundleResource.SetMetadata("LogicalName", logicalName);

                    bool optimize = false;

                    if (CanOptimize(item.ItemSpec))
                    {
                        var metadata = item.GetMetadata("Optimize");

                        // fall back to old metadata name
                        if (string.IsNullOrEmpty(metadata))
                        {
                            metadata = item.GetMetadata("OptimizeImage");
                        }

                        if (string.IsNullOrEmpty(metadata) || !bool.TryParse(metadata, out optimize))
                        {
                            switch (Path.GetExtension(item.ItemSpec).ToLowerInvariant())
                            {
                            case ".plist":
                            case ".strings": optimize = OptimizePropertyLists; break;

                            case ".png": optimize = OptimizePNGs; break;
                            }
                        }
                    }

                    bundleResource.SetMetadata("Optimize", optimize.ToString());

                    bundleResources.Add(bundleResource);
                }
            }

            BundleResourcesWithLogicalNames = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
        public override bool Execute()
        {
            var coremlcOutputDir = Path.Combine(IntermediateOutputPath, "coremlc");
            var prefixes         = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var mapping          = new Dictionary <string, IDictionary> ();
            var bundleResources  = new List <ITaskItem> ();
            var partialPlists    = new List <ITaskItem> ();

            if (Models.Length > 0)
            {
                Directory.CreateDirectory(coremlcOutputDir);

                foreach (var model in Models)
                {
                    var logicalName  = BundleResource.GetLogicalName(ProjectDir, prefixes, model, !string.IsNullOrEmpty(SessionId));
                    var bundleName   = GetPathWithoutExtension(logicalName) + ".mlmodelc";
                    var outputPath   = Path.Combine(coremlcOutputDir, bundleName);
                    var outputDir    = Path.GetDirectoryName(outputPath);
                    var partialPlist = GetPathWithoutExtension(outputPath) + "-partial.plist";
                    var log          = GetPathWithoutExtension(outputPath) + ".log";
                    var resourceTags = model.GetMetadata("ResourceTags");
                    var output       = new TaskItem(outputPath);

                    output.SetMetadata("LogicalName", bundleName);
                    output.SetMetadata("Optimize", "false");

                    if (EnableOnDemandResources && !string.IsNullOrEmpty(resourceTags))
                    {
                        output.SetMetadata("ResourceTags", resourceTags);
                    }

                    var metadata = output.CloneCustomMetadata();
                    mapping[outputPath + "/"] = metadata;

                    if (FileChanged(model, partialPlist))
                    {
                        Directory.CreateDirectory(outputDir);

                        if ((Compile(model, outputDir, log, partialPlist)) != 0)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        Log.LogMessage(MessageImportance.Low, "Skipping `{0}' as the output file, `{1}', is newer.", model.ItemSpec, partialPlist);
                    }
                }

                bundleResources.AddRange(GetCompiledOutput(coremlcOutputDir, mapping));

                foreach (var path in Directory.EnumerateFiles(coremlcOutputDir, "*-partial.plist", SearchOption.AllDirectories))
                {
                    partialPlists.Add(new TaskItem(path));
                }
            }

            BundleResources     = bundleResources.ToArray();
            PartialAppManifests = partialPlists.ToArray();

            return(!Log.HasLoggedErrors);
        }
        private void WriteResponse(BundleResource bundleResource, AsyncBundlingRequestState asyncState)
        {

            string content = TransformContent(bundleResource, asyncState.Context);
            asyncState.ResourceData.Append(content).Append(Environment.NewLine);

            asyncState.Context.Response.Write(content);
            asyncState.Context.Response.Write(Environment.NewLine);

        }
        private void ProcessItem(BundleResource resource, AsyncBundlingRequestState asyncState)
        {
            if (resource == BundleResource.Empty)
            {
                return;
            }

            if (resource.Type == BundleResourceType.EmbeddedScript || resource.Type == BundleResourceType.EmbeddedStyle)
            {
                resource.ServerPath = null;
                WriteResponse(resource, asyncState);

                ProcessItem(GetNextResource(asyncState), asyncState);
            }
            else if (resource.Type == BundleResourceType.ClientScript)
            {
                try
                {
                    var handler = ClientScriptBundle.GetHttpHandler(resource.ServerPath.Split('/').Last().Split('.').First());
                    var content = handler.GetData(asyncState.Context);

                    asyncState.ResourceData.Append(content).Append(Environment.NewLine);
                    asyncState.Context.Response.Write(content);
                    asyncState.Context.Response.Write(Environment.NewLine);

                    ProcessItem(GetNextResource(asyncState), asyncState);
                }
                catch (Exception e)
                {
                    _log.Error("ClientScriptError", e);
                }
            }
            else
            {
                //If it's file begin read and go to IOCP thread
                if (File.Exists(resource.Content))
                {
                    FileStream file = File.Open(resource.Content, FileMode.Open, FileAccess.Read, FileShare.Read);
                    var buffer = new byte[file.Length];
                    file.BeginRead(buffer, 0, (int)file.Length, result =>
                                                                     {
                                                                         try
                                                                         {
                                                                             int readed = file.EndRead(result);
                                                                             var asyncObject =
                                                                                 result.AsyncState as
                                                                                 AsyncBundlingRequestState;
                                                                             HttpContext.Current = asyncState.Context;
                                                                             resource.Content =
                                                                                 Encoding.UTF8.GetString(buffer, 0,
                                                                                                         readed);
                                                                             WriteResponse(resource, asyncState);
                                                                             ProcessItem(GetNextResource(asyncObject),
                                                                                         asyncObject);
                                                                         }
                                                                         catch (Exception e)
                                                                         {
                                                                             _log.Error(
                                                                                 string.Format(
                                                                                     "Error while processing file:{0}",
                                                                                     resource.Content), e);
                                                                         }
                                                                         finally
                                                                         {
                                                                             //We got wht we need in buffer. close stream
                                                                             file.Close();
                                                                             file.Dispose();
                                                                         }
                                                                     }, asyncState);
                }
            }
        }
Beispiel #28
0
        protected override void AppendCommandLineArguments(IDictionary <string, string> environment, CommandLineArgumentBuilder args, ITaskItem[] items)
        {
            var assetDirs = new HashSet <string> (items.Select(x => BundleResource.GetVirtualProjectPath(ProjectDir, x, !string.IsNullOrEmpty(SessionId))));

            if (!string.IsNullOrEmpty(XSAppIconAssets))
            {
                int    index    = XSAppIconAssets.IndexOf(".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
                string assetDir = null;
                var    rpath    = XSAppIconAssets;

                if (index != -1)
                {
                    assetDir = rpath.Substring(0, index + ".xcassets".Length);
                }

                if (assetDirs != null && assetDirs.Contains(assetDir))
                {
                    var assetName = Path.GetFileNameWithoutExtension(rpath);

                    if (PartialAppManifest == null)
                    {
                        args.Add("--output-partial-info-plist");
                        args.AddQuoted(partialAppManifest.GetMetadata("FullPath"));

                        PartialAppManifest = partialAppManifest;
                    }

                    args.Add("--app-icon");
                    args.AddQuoted(assetName);

                    if (IsMessagesExtension)
                    {
                        args.Add("--product-type com.apple.product-type.app-extension.messages");
                    }
                }
            }

            if (!string.IsNullOrEmpty(XSLaunchImageAssets))
            {
                int    index    = XSLaunchImageAssets.IndexOf(".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
                string assetDir = null;
                var    rpath    = XSLaunchImageAssets;

                if (index != -1)
                {
                    assetDir = rpath.Substring(0, index + ".xcassets".Length);
                }

                if (assetDirs != null && assetDirs.Contains(assetDir))
                {
                    var assetName = Path.GetFileNameWithoutExtension(rpath);

                    if (PartialAppManifest == null)
                    {
                        args.Add("--output-partial-info-plist");
                        args.AddQuoted(partialAppManifest.GetMetadata("FullPath"));

                        PartialAppManifest = partialAppManifest;
                    }

                    args.Add("--launch-image");
                    args.AddQuoted(assetName);
                }
            }

            if (!string.IsNullOrEmpty(CLKComplicationGroup))
            {
                args.Add("--complication", CLKComplicationGroup);
            }

            if (OptimizePNGs)
            {
                args.Add("--compress-pngs");
            }

            if (AppleSdkSettings.XcodeVersion.Major >= 7)
            {
                if (!string.IsNullOrEmpty(outputSpecs))
                {
                    args.Add("--enable-on-demand-resources", EnableOnDemandResources ? "YES" : "NO");
                }

                if (!string.IsNullOrEmpty(DeviceModel))
                {
                    args.Add("--filter-for-device-model", DeviceModel);
                }

                if (!string.IsNullOrEmpty(DeviceOSVersion))
                {
                    args.Add("--filter-for-device-os-version", DeviceOSVersion);
                }

                if (!string.IsNullOrEmpty(outputSpecs))
                {
                    args.Add("--asset-pack-output-specifications");
                    args.AddQuoted(Path.GetFullPath(outputSpecs));
                }
            }

            if (Platform == ApplePlatform.MacCatalyst)
            {
                args.Add("--ui-framework-family");
                args.Add("uikit");
            }

            foreach (var targetDevice in GetTargetDevices())
            {
                args.Add("--target-device", targetDevice);
            }

            args.Add("--minimum-deployment-target", MinimumOSVersion);

            var platform = PlatformUtils.GetTargetPlatform(SdkPlatform, IsWatchApp);

            if (platform != null)
            {
                args.Add("--platform", platform);
            }
        }
Beispiel #29
0
        public override bool Execute()
        {
            var prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var bundleResources = new List <ITaskItem> ();

            if (BundleResources != null)
            {
                foreach (var item in BundleResources)
                {
                    // Skip anything with the PublishFolderType metadata, these are copied directly to the ResolvedFileToPublish item group instead.
                    var publishFolderType = item.GetMetadata("PublishFolderType");
                    if (!string.IsNullOrEmpty(publishFolderType))
                    {
                        continue;
                    }

                    var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId));
                    // We need a physical path here, ignore the Link element
                    var    path = item.GetMetadata("FullPath");
                    string illegal;

                    if (!File.Exists(path))
                    {
                        Log.LogError(MSBStrings.E0099, logicalName, path);
                        continue;
                    }

                    if (logicalName.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal))
                    {
                        Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0100, logicalName);
                        continue;
                    }

                    if (logicalName == "Info.plist")
                    {
                        Log.LogWarning(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0101);
                        continue;
                    }

                    if (BundleResource.IsIllegalName(logicalName, out illegal))
                    {
                        Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0102, illegal);
                        continue;
                    }

                    var bundleResource = new TaskItem(item);
                    bundleResource.SetMetadata("LogicalName", logicalName);

                    bool optimize = false;

                    if (CanOptimize(item.ItemSpec))
                    {
                        var metadata = item.GetMetadata("Optimize");

                        // fall back to old metadata name
                        if (string.IsNullOrEmpty(metadata))
                        {
                            metadata = item.GetMetadata("OptimizeImage");
                        }

                        if (string.IsNullOrEmpty(metadata) || !bool.TryParse(metadata, out optimize))
                        {
                            switch (Path.GetExtension(item.ItemSpec).ToLowerInvariant())
                            {
                            case ".plist":
                            case ".strings": optimize = OptimizePropertyLists; break;

                            case ".png": optimize = OptimizePNGs; break;
                            }
                        }
                    }

                    bundleResource.SetMetadata("Optimize", optimize.ToString());

                    bundleResources.Add(bundleResource);
                }
            }

            BundleResourcesWithLogicalNames = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
Beispiel #30
0
 protected virtual string GetBundleRelativeOutputPath(IList <string> prefixes, ITaskItem input)
 {
     return(BundleResource.GetLogicalName(ProjectDir, prefixes, input, !string.IsNullOrEmpty(SessionId)));
 }
        public override bool Execute()
        {
            var    prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var    intermediate    = Path.Combine(IntermediateOutputPath, ToolName);
            var    bundleResources = new List <ITaskItem> ();
            var    modified        = new HashSet <string> ();
            var    items           = new List <ITaskItem> ();
            string metadata;

            foreach (var asset in SceneKitAssets)
            {
                if (!File.Exists(asset.ItemSpec))
                {
                    continue;
                }

                // get the .scnassets directory path
                var scnassets = Path.GetDirectoryName(asset.ItemSpec);
                while (scnassets.Length > 0 && Path.GetExtension(scnassets).ToLowerInvariant() != ".scnassets")
                {
                    scnassets = Path.GetDirectoryName(scnassets);
                }

                if (scnassets.Length == 0)
                {
                    continue;
                }

                metadata = asset.GetMetadata("LogicalName");
                if (!string.IsNullOrEmpty(metadata))
                {
                    asset.SetMetadata("LogicalName", string.Empty);
                }

                var bundleName = BundleResource.GetLogicalName(ProjectDir, prefixes, asset, !string.IsNullOrEmpty(SessionId));
                var output     = new TaskItem(Path.Combine(intermediate, bundleName));

                if (!modified.Contains(scnassets) && (!File.Exists(output.ItemSpec) || File.GetLastWriteTimeUtc(asset.ItemSpec) > File.GetLastWriteTimeUtc(output.ItemSpec)))
                {
                    // Base the new item on @asset, to get the `DefiningProject*` metadata too
                    var scnassetsItem = new TaskItem(asset);

                    // .. but we really want it to be for @scnassets, so set ItemSpec accordingly
                    scnassetsItem.ItemSpec = scnassets;

                    // .. and remove the @OriginalItemSpec which is for @asset
                    scnassetsItem.RemoveMetadata("OriginalItemSpec");

                    var assetMetadata = asset.GetMetadata("DefiningProjectFullPath");
                    if (assetMetadata != scnassetsItem.GetMetadata("DefiningProjectFullPath"))
                    {
                        // xbuild doesn't set this, so we'll do it
                        //
                        // `DefiningProjectFullPath` is a reserved metadata for msbuild, so
                        // setting this is not allowed anyway
                        scnassetsItem.SetMetadata("DefiningProjectFullPath", assetMetadata);
                    }

                    modified.Add(scnassets);
                    items.Add(scnassetsItem);
                }

                output.SetMetadata("LogicalName", bundleName);
                output.SetMetadata("Optimize", "false");
                bundleResources.Add(output);
            }

            if (modified.Count == 0)
            {
                BundleResources = bundleResources.ToArray();
                return(!Log.HasLoggedErrors);
            }

            if (!Directory.Exists(intermediate))
            {
                Directory.CreateDirectory(intermediate);
            }

            foreach (var item in items)
            {
                var bundleDir = BundleResource.GetLogicalName(ProjectDir, prefixes, new TaskItem(item), !string.IsNullOrEmpty(SessionId));
                var output    = Path.Combine(intermediate, bundleDir);

                if (CopySceneKitAssets(item.ItemSpec, output, intermediate) == -1)
                {
                    return(false);
                }
            }

            BundleResources = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
Beispiel #32
0
 public BundleResourceDisplayProxy(BundleResource original)
 {
     Link = original.Link;
     UnevaluatedInclude = original.UnevaluatedInclude;
 }