Ejemplo n.º 1
0
        private static async Task ProcessStep(string projectId, Project.Dependency projectDependency, ProcessContext context)
        {
            var versionRange = new SemVer.Range(projectDependency.Version, true);

            // if already resolved dependency, skip it

            if (context.PackageMap.ContainsKey(projectId))
            {
                if (versionRange.IsSatisfied(context.PackageMap[projectId]) == false)
                {
                    throw new InvalidDataException($"Cannot meet version requirement: {projectId} {projectDependency.Version} (but {context.PackageMap[projectId]})");
                }
                return;
            }

            // download package

            Console.WriteLine("Restore: " + projectId);

            var packageFile    = "";
            var packageVersion = new SemVer.Version(0, 0, 0);
            var nugetTargetFrameworkMoniker = string.Empty;
            var sourceName      = projectId;
            var sourceExtention = ".unitypackage";

            if (string.IsNullOrEmpty(projectDependency.SourceType) == false)
            {
                var source = projectDependency.SourceType.Split(':');
                sourceName = source[0];
                if (source.Length > 1)
                {
                    sourceExtention = source[1];
                    if (sourceExtention.Contains(".") == false)
                    {
                        sourceExtention = sourceExtention.Insert(0, ".");
                    }
                }
            }
            if (projectDependency.Source != "local" && string.IsNullOrEmpty(context.Options.LocalRepositoryDirectory) == false)
            {
                var packages     = LocalPackage.GetPackages(context.Options.LocalRepositoryDirectory, projectId);
                var versionIndex = versionRange.GetSatisfiedVersionIndex(packages.Select(x => x.Item2).ToList());
                if (versionIndex != -1)
                {
                    packageFile    = packages[versionIndex].Item1;
                    packageVersion = packages[versionIndex].Item2;
                }
            }

            if (string.IsNullOrEmpty(packageFile) == false)
            {
            }
            else if (projectDependency.Source == "local")
            {
                var packages     = LocalPackage.GetPackages(context.Options.LocalRepositoryDirectory ?? "", projectId);
                var versionIndex = versionRange.GetSatisfiedVersionIndex(packages.Select(x => x.Item2).ToList());
                if (versionIndex == -1)
                {
                    throw new InvalidOperationException("Cannot find package from local repository: " + projectId);
                }

                packageFile    = packages[versionIndex].Item1;
                packageVersion = packages[versionIndex].Item2;
            }
            else if (projectDependency.Source.StartsWith("github:"))
            {
                var parts = projectDependency.Source.Substring(7).Split('/');
                if (parts.Length != 2)
                {
                    throw new InvalidDataException("Cannot determine github repo information from url: " + projectDependency.Source);
                }

                var r = await GithubPackage.DownloadPackageAsync(parts[0], parts[1], projectId, versionRange, sourceName, sourceExtention, context.Options.Token);

                packageFile    = r.Item1;
                packageVersion = r.Item2;
            }
            else if (projectDependency.Source.StartsWith("nuget:"))
            {
                nugetTargetFrameworkMoniker = projectDependency.Source.Substring(6);

                var r = NugetPackage.DownloadPackage(projectId, projectDependency.Version);
                packageFile    = r.Item1;
                packageVersion = r.Item2;
            }
            else
            {
                throw new InvalidOperationException("Cannot recognize source: " + projectDependency.Source);
            }

            context.PackageMap.Add(projectId, packageVersion);

            if (string.IsNullOrEmpty(nugetTargetFrameworkMoniker))
            {
                var projectFile = Path.Combine(context.OutputDir, $"Assets/UnityPackages/{projectId}.unitypackage.json");

                // apply package
                if (sourceExtention == ".zip")
                {
                    var isCreateProjectFile = SourcePackage.ExtractUnityPackage(packageFile, context.OutputDir,
                                                                                projectId, projectDependency.IncludeExtra, projectDependency.IncludeMerged);
                    if (isCreateProjectFile)
                    {
                        var p = new Project {
                            Id = projectId, Version = packageVersion.ToString()
                        };
                        p.Description = $"Source package";
                        p.Files       = new List <JToken>()
                        {
                            JToken.FromObject($"Assets/UnityPackages/{projectId}")
                        };
                        var jsonSettings = new JsonSerializerSettings
                        {
                            DefaultValueHandling = DefaultValueHandling.Ignore,
                        };
                        File.WriteAllText(projectFile, JsonConvert.SerializeObject(p, Formatting.Indented, jsonSettings));
                        File.WriteAllBytes(projectFile + ".meta", Packer.GenerateMeta(projectFile, projectFile).Item2);
                    }
                }
                else
                {
                    Extracter.ExtractUnityPackage(packageFile, context.OutputDir,
                                                  projectId, projectDependency.IncludeExtra, projectDependency.IncludeMerged);
                }

                // deep into dependencies

                if (File.Exists(projectFile))
                {
                    var project = Project.Load(projectFile);
                    if (project.MergedDependencies != null && projectDependency.IncludeMerged)
                    {
                        foreach (var d in project.MergedDependencies)
                        {
                            if (context.PackageMap.ContainsKey(d.Key) == false)
                            {
                                context.PackageMap[d.Key] = new SemVer.Version(d.Value.Version, true);
                            }
                        }
                    }
                    if (project.Dependencies != null)
                    {
                        foreach (var d in project.Dependencies)
                        {
                            context.DepQueue.Enqueue(d);
                        }
                    }
                }
            }
            else
            {
                // apply package

                NugetPackage.ExtractPackage(projectId, packageVersion.ToString(),
                                            nugetTargetFrameworkMoniker, context.OutputDir);

                // create proxy project file

                var outputDir        = Path.Combine(context.OutputDir, $"Assets/UnityPackages/{projectId}");
                var projectAssetPath = $"Assets/UnityPackages/{projectId}.unitypackage.json";
                var projectFile      = Path.Combine(context.OutputDir, projectAssetPath);
                var p = new Project {
                    Id = projectId, Version = packageVersion.ToString()
                };
                p.Description = $"Nuget package (TFM:{nugetTargetFrameworkMoniker})";
                p.Files       = Directory.GetFiles(outputDir, "*")
                                .Where(f => Path.GetExtension(f).ToLower() != ".meta")
                                .Select(f => JToken.FromObject(f.Substring(outputDir.Length + 1).Replace("\\", "/"))).ToList();
                var jsonSettings = new JsonSerializerSettings
                {
                    DefaultValueHandling = DefaultValueHandling.Ignore,
                };
                File.WriteAllText(projectFile, JsonConvert.SerializeObject(p, Formatting.Indented, jsonSettings));

                File.WriteAllBytes(projectFile + ".meta",
                                   Packer.GenerateMeta(projectFile, projectAssetPath).Item2);
            }
        }
Ejemplo n.º 2
0
        internal static int Process(Options options)
        {
            var p          = Project.Load(options.ProjectFile);
            var projectDir = Path.GetDirectoryName(options.ProjectFile);
            var outputDir  = options.OutputDirectory ?? projectDir;

            if (string.IsNullOrEmpty(p.Id))
            {
                throw new InvalidDataException("Cannot find id from project.");
            }

            if (string.IsNullOrEmpty(p.Version))
            {
                throw new InvalidDataException("Cannot find version from project.");
            }

            p.Version = new SemVer.Version(p.Version).ToString();

            if (p.Files == null || p.Files.Any() == false)
            {
                throw new InvalidDataException("Cannot find files from project.");
            }

            var homeBaseDir = "Assets/UnityPackages";
            var homeDir     = homeBaseDir + "/" + p.Id;
            var tempDir     = Extracter.CreateTemporaryDirectory();

            var files       = new List <Project.FileItem>();
            var packagePath = Path.Combine(outputDir, $"{p.Id}.{p.Version}.unitypackage");

            using (var packer = new Packer(packagePath))
            {
                foreach (var fileValue in p.Files)
                {
                    if (fileValue is JObject)
                    {
                        var fileItem       = fileValue.ToObject <Project.FileItem>();
                        var filePath       = Path.Combine(projectDir, fileItem.Source);
                        var targetResolved = fileItem.Target.Replace("$id$", p.Id)
                                             .Replace("$home$", homeDir)
                                             .Replace("$homebase$", homeBaseDir);
                        AddFiles(packer, files, filePath, targetResolved, fileItem.Extra);
                    }
                    else if (fileValue.ToString().StartsWith("$"))
                    {
                        var keyword = fileValue.ToString().ToLower();
                        if (keyword != "$dependencies$")
                        {
                            throw new InvalidDataException("Wrong keyword: " + keyword);
                        }

                        var mergedProjectMap = RestoreTool.Process(new RestoreTool.Options
                        {
                            ProjectFile              = options.ProjectFile,
                            OutputDirectory          = tempDir,
                            LocalRepositoryDirectory = options.LocalRepositoryDirectory
                        }).Result;

                        p.MergedDependencies = mergedProjectMap.ToDictionary(
                            i => i.Key,
                            i => new Project.Dependency {
                            Version = i.Value.ToString()
                        });

                        foreach (var file in Directory.GetFiles(tempDir, "*", SearchOption.AllDirectories))
                        {
                            if (Path.GetExtension(file).ToLower() == ".meta")
                            {
                                var assetFile  = file.Substring(0, file.Length - 5);
                                var targetFile = assetFile.Substring(tempDir.Length + 1).Replace("\\", "/");

                                // NOTE:
                                // if Extra field of file in merged dependencies,
                                // read *.unitypackage.json and use data from them.

                                if (File.Exists(assetFile))
                                {
                                    files.Add(new Project.FileItem
                                    {
                                        Source = assetFile,
                                        Target = targetFile,
                                        Merged = true
                                    });
                                }

                                packer.Add(assetFile, targetFile);
                            }
                        }
                    }
                    else
                    {
                        var filePath = Path.Combine(projectDir, fileValue.ToString());
                        AddFiles(packer, files, filePath, homeDir + "/", false);
                    }
                }

                if (files.Any() == false)
                {
                    throw new InvalidDataException("Nothing to add for files.");
                }

                // make files

                var jsonSettings = new JsonSerializerSettings
                {
                    DefaultValueHandling = DefaultValueHandling.Ignore,
                };
                p.Files = files.Select(
                    f => (f.Extra || f.Merged)
                        ? JToken.FromObject(new Project.FileItem {
                    Target = f.Target, Extra = f.Extra, Merged = f.Merged
                }, JsonSerializer.Create(jsonSettings))
                        : JToken.FromObject(f.Target)).ToList();

                // add project.json

                var projectPath = Path.Combine(tempDir, p.Id + ".unitypackage.json");
                File.WriteAllText(projectPath, JsonConvert.SerializeObject(p, Formatting.Indented, jsonSettings));
                packer.AddWithMetaGenerated(projectPath, homeBaseDir + "/" + p.Id + ".unitypackage.json");
                packer.AddDirectoriesWithMetaGenerated(homeBaseDir);
            }

            if (string.IsNullOrEmpty(tempDir) == false)
            {
                Directory.Delete(tempDir, true);
            }

            return(0);
        }