예제 #1
0
        private static async Task <Tuple <List <Plugin>, List <Plugin> > > StageDefinition(SDK.Core.Plugins.Plugin definition, IDictionary <Name, Tuple <SDK.Core.Plugins.VersionRange, Plugin> > loaded = null)
        {
            var top    = new List <Plugin>();
            var nested = new List <Plugin>();

            foreach (var dependency in definition.Dependencies ?? new Dictionary <Name, SDK.Core.Plugins.VersionRange>())
            {
                var repo    = definition.Repositories?.FirstOrDefault(r => r.Name.ToString() == dependency.Key.ToString());
                var adapter = new AdapterBuilder(dependency.Key, repo).Adapter();

                var versions = await adapter.GetVersions();

                var versionMatch = versions.LastOrDefault(version => dependency.Value.IsSatisfied(version));
                if (versionMatch == null)
                {
                    throw new Exception("No matching version found");
                }

                if (loaded == null)
                {
                    loaded = new Dictionary <Name, Tuple <SDK.Core.Plugins.VersionRange, Plugin> >();
                }

                if (loaded.ContainsKey(dependency.Key))
                {
                    if (dependency.Value.Value != "*" && loaded[dependency.Key].Item1.Value != "*" && !dependency.Value.IsSatisfied(loaded[dependency.Key].Item2.Version))
                    {
                        throw new Exception($"{dependency.Key} was found");
                    }
                }

                var localPath = await adapter.Cache(versionMatch);

                var plugin = Plugin.Load(Path.Combine(localPath, ConfigurationManager.DefinitionFile));

                if (loaded.ContainsKey(dependency.Key))
                {
                    loaded.Add(dependency.Key, new Tuple <SDK.Core.Plugins.VersionRange, Plugin>(dependency.Value, plugin));
                }

                top.Add(plugin);

                // TODO: What should be validated?
                //if (plugin.Name != dependency.Key) throw new Exception("Downloaded package does not match requested.");
                //if (plugin.Version != versionMatch) throw new Exception("Downloaded package does not match requested.");

                nested.AddRange((await StageDefinition(plugin, loaded)).Item1);
            }

            return(new Tuple <List <Plugin>, List <Plugin> >(top, nested));
        }
예제 #2
0
파일: LocalAdapter.cs 프로젝트: Najsr/nfpm
        /// <inheritdoc />
        /// <summary>
        /// Gets the valid release versions.
        /// </summary>
        /// <exception cref="T:System.IO.FileNotFoundException">Unable to find definition file</exception>
        public async Task <IEnumerable <Version> > GetVersions()
        {
            var path = Path.Combine(Path.GetFullPath(this.repo.Path), ConfigurationManager.DefinitionFile);

            if (!File.Exists(path))
            {
                throw new FileNotFoundException("Unable to find definition file", path);
            }

            var definition = Plugin.Load(path);

            if (definition.Version == null)
            {
                return new List <Version> {
                           new Version("*")
                }
            }
            ;

            return(await Task.FromResult(new List <Version> {
                new Version(definition.Version.ToString())
            }));
        }
예제 #3
0
파일: LocalAdapter.cs 프로젝트: Najsr/nfpm
        /// <inheritdoc />
        /// <summary>
        /// Downloads and unpacks the specified plugin version.
        /// </summary>
        /// <param name="version">The version to download.</param>
        public async Task Download(Version version)
        {
            var src = Path.Combine(Path.GetFullPath(this.repo.Path), this.repo.Path);
            var dst = Path.Combine(Environment.CurrentDirectory, ConfigurationManager.PluginPath, this.name.Vendor, this.name.Project);

            var path = Path.Combine(Path.GetFullPath(this.repo.Path), ConfigurationManager.DefinitionFile);

            if (!File.Exists(path))
            {
                throw new FileNotFoundException("Unable to find definition file", path);
            }

            var definition = Plugin.Load(path);

            var stockFiles = new List <string>
            {
                "nfive.yml",
                "nfive.lock",
                "README.md",
                "README",
                "LICENSE.md",
                "LICENSE"
            };

            var files = new List <string>();

            if (definition.Client != null)
            {
                if (definition.Client.Main != null && definition.Client.Main.Any())
                {
                    files.AddRange(definition.Client.Main.Select(f => $"{f}.net.dll"));
                }

                if (definition.Client.Include != null && definition.Client.Include.Any())
                {
                    files.AddRange(definition.Client.Include.Select(f => $"{f}.net.dll"));
                }

                if (definition.Client.Files != null && definition.Client.Files.Any())
                {
                    files.AddRange(definition.Client.Files);
                }

                if (definition.Client.Overlays != null && definition.Client.Overlays.Any())
                {
                    files.AddRange(definition.Client.Overlays);
                }
            }

            if (definition.Server != null)
            {
                if (definition.Server.Main != null && definition.Server.Main.Any())
                {
                    files.AddRange(definition.Server.Main.Select(f => $"{f}.net.dll"));
                }

                if (definition.Server.Include != null && definition.Server.Include.Any())
                {
                    files.AddRange(definition.Server.Include.Select(f => $"{f}.net.dll"));
                }
            }

            files = files.Distinct().ToList();

            foreach (var file in stockFiles)
            {
                if (!File.Exists(Path.Combine(src, file)))
                {
                    continue;
                }

                File.Copy(Path.Combine(src, file), Path.Combine(dst, file), true);
            }

            foreach (var file in files)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine(dst, file).Replace(Path.DirectorySeparatorChar, '/')));

                File.Copy(Path.Combine(src, file).Replace(Path.DirectorySeparatorChar, '/'), Path.Combine(dst, file).Replace(Path.DirectorySeparatorChar, '/'), true);
            }

            await Task.FromResult(0);
        }
예제 #4
0
        public override async Task <int> Main()
        {
            var definition = LoadDefinition();
            var graph      = LoadGraph();

            // New plugins
            if (this.Plugins.Any())
            {
                foreach (var plugin in this.Plugins)
                {
                    var input = plugin;

                    // Local install
                    if (Directory.Exists(plugin) && File.Exists(Path.Combine(plugin, ConfigurationManager.DefinitionFile)))
                    {
                        var path = Path.GetFullPath(plugin);

                        var pluginDefinition = Plugin.Load(Path.Combine(path, ConfigurationManager.DefinitionFile));

                        if (definition.Repositories == null)
                        {
                            definition.Repositories = new List <Repository>();
                        }

                        definition.Repositories.RemoveAll(r => r.Name == pluginDefinition.Name);
                        definition.Repositories.Add(new Repository
                        {
                            Name = pluginDefinition.Name,
                            Type = "local",
                            Path = path
                        });

                        input = pluginDefinition.Name;
                    }

                    var parts = input.Split(new[] { '@' }, 2);
                    var name  = new Name(parts[0].Trim());

                    var versionInput = parts.Length == 2 ? parts[1].Trim() : "*";

                    Models.VersionRange range   = null;
                    Version             version = null;
                    PartialVersion      partial = null;

                    try
                    {
                        partial = new PartialVersion(versionInput);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }

                    var isSpecific = partial?.Major != null && partial.Minor.HasValue && partial.Patch.HasValue;

                    try
                    {
                        range = new Models.VersionRange(versionInput);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }

                    try
                    {
                        version = new Version(versionInput);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }

                    List <Version> versions;
                    try
                    {
                        var adapter = new AdapterBuilder(name, definition).Adapter();
                        versions = (await adapter.GetVersions()).ToList();
                    }
                    catch (WebException ex) when((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
                    {
                        Console.WriteLine("Error ".DarkRed(), $"{name}".Red(), " not found.".DarkRed());

                        return(1);
                    }

                    var versionMatch = range.MaxSatisfying(versions);
                    if (versionMatch == null)
                    {
                        Console.WriteLine("Error ".DarkRed(), $"{name}@{range}".Red(), " not found, available versions: ".DarkRed(), string.Join(" ", versions.Select(v => v.ToString())).Red());

                        return(1);
                    }

                    if (definition.Dependencies == null)
                    {
                        definition.Dependencies = new Dictionary <Name, SDK.Core.Plugins.VersionRange>();
                    }
                    definition.Dependencies[name] = new Models.VersionRange("^" + (isSpecific ? partial.ToZeroVersion() : version ?? versionMatch));

                    Console.WriteLine("+ ", $"{name}@{definition.Dependencies[name]}".White());
                }

                graph = new DefinitionGraph();
                await graph.Apply(definition);

                definition.Save(ConfigurationManager.DefinitionFile);
                graph.Save();
            }
            else
            {
                if (graph != null)
                {
                    await graph.Apply();
                }
                else
                {
                    graph = new DefinitionGraph();

                    await graph.Apply(definition);

                    graph.Save();
                }
            }

            if (PathManager.IsResource())
            {
                ResourceGenerator.Serialize(graph);
            }

            return(0);
        }
예제 #5
0
파일: Outdated.cs 프로젝트: lfshr/nfpm
        public override async Task <int> Main()
        {
            var results = new List <ColorToken[]>
            {
                new []
                {
                    "NAME".White(),
                    "CURRENT".White(),
                    "WANTED".White(),
                    "LATEST".White()
                }
            };

            var definition = LoadDefinition();

            foreach (var dependency in definition?.Dependencies ?? new Dictionary <Name, VersionRange>())
            {
                var repo    = definition?.Repositories?.FirstOrDefault(r => r.Name.ToString() == dependency.Key.ToString());
                var adapter = new AdapterBuilder(dependency.Key, repo).Adapter();

                var versions     = (await adapter.GetVersions()).ToList();
                var versionMatch = versions.LastOrDefault(version => dependency.Value.IsSatisfied(version));
                if (versionMatch == null)
                {
                    throw new Exception("No matching version found");
                }

                var        current = "MISSING".Red();
                ColorToken wanted  = versionMatch.ToString();
                ColorToken latest  = versions.Last().ToString();

                var pluginDefinition = new FileInfo(Path.Combine(Environment.CurrentDirectory, ConfigurationManager.PluginPath, dependency.Key.Vendor, dependency.Key.Project, ConfigurationManager.DefinitionFile));

                if (pluginDefinition.Exists)
                {
                    var plugin = Plugin.Load(pluginDefinition.FullName);

                    current = plugin.Version.ToString();

                    current = current.Text != wanted.Text ? current.Red() : current.Green();
                    wanted  = wanted.Text != latest.Text ? wanted.Red() : wanted.Green();

                    if (!this.All && current.Text == wanted.Text && wanted.Text == latest.Text)
                    {
                        continue;
                    }
                }

                results.Add(new[]
                {
                    dependency.Key.ToString(),
                    current,
                    wanted,
                    latest
                });
            }

            if (results.Count < 2)
            {
                return(0);
            }

            var nameLength    = Math.Max(Math.Min(50, results.Max(d => d[0].Text.Length)), 10);
            var currentLength = Math.Max(Math.Min(20, results.Max(d => d[1].Text.ToString().Length)), 7);
            var wantedLength  = Math.Max(Math.Min(20, results.Max(d => d[2].Text.ToString().Length)), 7);
            var latestLength  = Math.Max(Math.Min(20, results.Max(d => d[3].Text.ToString().Length)), 7);

            foreach (var result in results)
            {
                result[0].Text = result[0].Text.Truncate(nameLength).PadRight(nameLength);
                result[1].Text = result[1].Text.Truncate(currentLength).PadLeft(currentLength);
                result[2].Text = result[2].Text.Truncate(wantedLength).PadLeft(wantedLength);
                result[3].Text = result[3].Text.Truncate(latestLength).PadLeft(latestLength);

                Console.WriteLine(result[0], " | ", result[1], " | ", result[2], " | ", result[3]);
            }

            return(await Task.FromResult(0));
        }
예제 #6
0
        public async Task Apply(Plugin baseDefinition = null)
        {
            if (baseDefinition != null)
            {
                var results = await StageDefinition(baseDefinition);

                var top = results.Item1;
                var all = top.Concat(results.Item2).Distinct().ToList();

                foreach (var plugin in top.Where(d => d.Dependencies != null))
                {
                    foreach (var dependency in plugin.Dependencies)
                    {
                        var dependencyPlugin = all.FirstOrDefault(p => p.Name == dependency.Key);
                        if (dependencyPlugin == null)
                        {
                            throw new Exception($"Unable to find dependency {dependency.Key}@{dependency.Value} required by {plugin.Name}@{plugin.Version}");                                                   // TODO: DependencyException
                        }
                        if (!dependency.Value.IsSatisfied(dependencyPlugin.Version))
                        {
                            throw new Exception($"{plugin.Name}@{plugin.Version} requires {dependencyPlugin.Name}@{dependency.Value} but {dependencyPlugin.Name}@{dependencyPlugin.Version} was found");
                        }

                        if (plugin.DependencyNodes == null)
                        {
                            plugin.DependencyNodes = new List <Plugin>();
                        }
                        plugin.DependencyNodes.Add(dependencyPlugin);
                    }
                }

                this.Plugins = top;
            }

            this.Plugins = Sort(this.Plugins);             // TODO: Don't store nested dependencies but still load them

            foreach (var definition in this.Plugins)
            {
                var path = Path.Combine(Environment.CurrentDirectory, ConfigurationManager.PluginPath, definition.Name.Vendor, definition.Name.Project, ConfigurationManager.DefinitionFile);

                if (File.Exists(path))
                {
                    var loadedDefinition = Plugin.Load(path);

                    // TODO: IEquality
                    if (loadedDefinition.Name.ToString() == definition.Name.ToString() &&
                        loadedDefinition.Version.ToString() == definition.Version.ToString() &&
                        baseDefinition?.Repositories?.FirstOrDefault(r => r.Name == definition.Name && r.Type == "local") == null)
                    {
                        continue;
                    }
                }

                // TODO: Remove extra plugin folders/files

                // Missing or outdated

                var dir = Path.Combine(Environment.CurrentDirectory, ConfigurationManager.PluginPath, definition.Name.Vendor, definition.Name.Project);
                if (Directory.Exists(dir))
                {
                    DeleteDirectory(dir);
                }
                Directory.CreateDirectory(dir);

                var repo    = baseDefinition?.Repositories?.FirstOrDefault(r => r.Name == definition.Name);
                var adapter = new AdapterBuilder(definition.Name, repo).Adapter();
                await adapter.Download(new Version(definition.Version.ToString()));

                var dependencyDefinition = Plugin.Load(Path.Combine(dir, ConfigurationManager.DefinitionFile));

                if (dependencyDefinition.Name != definition.Name)
                {
                    throw new Exception("Downloaded package does not match requested.");
                }
                if (dependencyDefinition.Version.ToString() != definition.Version.ToString())
                {
                    throw new Exception("Downloaded package does not match requested.");
                }

                var configSrc = Path.Combine(dir, ConfigurationManager.ConfigurationPath);
                var configDst = Path.Combine(Environment.CurrentDirectory, ConfigurationManager.ConfigurationPath, definition.Name.Vendor, definition.Name.Project);

                if (!Directory.Exists(configSrc))
                {
                    continue;
                }
                if (!Directory.Exists(configDst))
                {
                    Directory.CreateDirectory(configDst);
                }

                // TODO: More files?
                // TODO: Ask user to replace
                foreach (var yml in Directory.EnumerateFiles(configSrc, "*.yml", SearchOption.TopDirectoryOnly))
                {
                    try
                    {
                        File.Copy(yml, Path.Combine(configDst, Path.GetFileName(yml)), false);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }