예제 #1
0
        public PackageManager()
        {
            var pkgs = Configuration.PackageDirectory;

            Directory.CreateDirectory(pkgs);

            _log.Info("Fetching package registry...");

            var registry = JArray.Parse(GitHub.GetString(Configuration.PackageRegistryUri))
                           .Select(x => new Package((JObject)x)).ToDictionary(x => x.Name);

            foreach (var pkg in registry.Values.ToArray())
            {
                var abs = Path.GetFullPath(pkg.Path);
                var bad = false;

                void CheckReferredPackages(bool dependencies)
                {
                    foreach (var name in dependencies ? pkg.Dependencies : pkg.Conflicts)
                    {
                        if (!registry.ContainsKey(name))
                        {
                            _log.Warning("Package {0} has {1} package {2} which does not exist; ignoring package",
                                         pkg.Name, dependencies ? "dependency" : "conflicting", name);
                            bad = true;
                        }
                    }
                }

                CheckReferredPackages(true);
                CheckReferredPackages(false);

                foreach (var file in pkg.Files)
                {
                    var loc = Path.GetFullPath(Path.Combine(abs, file));

                    if (!loc.StartsWith(abs + Path.DirectorySeparatorChar) &&
                        !loc.StartsWith(abs + Path.AltDirectorySeparatorChar))
                    {
                        _log.Warning("Package {0} has file path {1} which is illegal; ignoring package",
                                     pkg.Name, file);
                        bad = true;
                    }

                    if (loc == Path.Combine(abs, PackageFileName) ||
                        loc == Path.Combine(abs, ManifestFileName) ||
                        loc == Path.Combine(abs, ConfigurationFileName))
                    {
                        _log.Warning("Package {0} has file path {1} which is for internal use; ignoring package",
                                     pkg.Name, file);
                        bad = true;
                    }
                }

                if (bad)
                {
                    registry.Remove(pkg.Name);
                }
            }

            Registry = registry;

            _log.Info("Reading local package manifests...");

            foreach (var dir in Directory.EnumerateDirectories(pkgs))
            {
                if (!File.Exists(Path.Combine(dir, ManifestFileName)))
                {
                    continue;
                }

                var pkg = new LocalPackage(Path.GetFileName(dir));

                _locals.Add(pkg.Name, pkg);
            }
        }