• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

KSP-CKAN / CKAN / 17678990388

12 Sep 2025 03:30PM UTC coverage: 72.067% (+1.0%) from 71.053%
17678990388

push

github

HebaruSan
Merge #4435 Add or fix tests for CmdLine, GUI.Util, and ModuleInstaller

5063 of 7378 branches covered (68.62%)

Branch coverage included in aggregate %.

19 of 31 new or added lines in 2 files covered. (61.29%)

2 existing lines in 1 file now uncovered.

10892 of 14761 relevant lines covered (73.79%)

1.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/GUI/Plugins/PluginController.cs
1
using System;
2
using System.Collections.Generic;
3
using System.IO;
4
using System.Reflection;
5

6
using log4net;
7

8
namespace CKAN.GUI
9
{
10
    public class PluginController
11
    {
NEW
12
        public PluginController(string path, bool activate = true)
×
13
        {
×
14
            m_PluginsPath = path;
×
UNCOV
15
            foreach (string dll in Directory.GetFiles(path, "*.dll"))
×
16
            {
×
NEW
17
                LoadAssembly(dll, activate);
×
18
            }
×
19
        }
×
20

21
        private void LoadAssembly(string dll, bool activate)
22
        {
×
23
            try
24
            {
×
25
                if (Assembly.UnsafeLoadFrom(dll) is Assembly assembly)
×
26
                {
×
27
                    try
28
                    {
×
29
                        log.InfoFormat("Loaded assembly - \"{0}\"", dll);
×
30

31
                        var typeName = string.Format("{0}.{0}",
×
32
                                                     Path.GetFileNameWithoutExtension(dll));
33

34
                        if (assembly.GetType(typeName) is Type type
×
35
                            && Activator.CreateInstance(type) is IGUIPlugin pluginInstance)
36
                        {
×
37
                            foreach (var loadedPlugin in m_ActivePlugins)
×
38
                            {
×
39
                                if (loadedPlugin.GetName() == pluginInstance.GetName())
×
40
                                {
×
41
                                    if (loadedPlugin.GetVersion().IsLessThan(pluginInstance.GetVersion()))
×
42
                                    {
×
43
                                        DeactivatePlugin(loadedPlugin);
×
44
                                        m_DormantPlugins.Remove(loadedPlugin);
×
45
                                    }
×
46
                                    else
47
                                    {
×
48
                                        return;
×
49
                                    }
50
                                }
×
51
                            }
×
52

53
                            foreach (var loadedPlugin in m_DormantPlugins)
×
54
                            {
×
55
                                if (loadedPlugin.GetName() == pluginInstance.GetName())
×
56
                                {
×
57
                                    if (loadedPlugin.GetVersion().IsLessThan(pluginInstance.GetVersion()))
×
58
                                    {
×
59
                                        m_DormantPlugins.Remove(loadedPlugin);
×
60
                                    }
×
61
                                    else
62
                                    {
×
63
                                        return;
×
64
                                    }
65
                                }
×
66
                            }
×
67

68
                            m_DormantPlugins.Add(pluginInstance);
×
NEW
69
                            if (activate)
×
NEW
70
                            {
×
NEW
71
                                ActivatePlugin(pluginInstance);
×
NEW
72
                            }
×
UNCOV
73
                            log.WarnFormat("Successfully instantiated type \"{0}\" from {1}.dll",
×
74
                                           assembly.FullName, assembly.FullName);
75
                        }
×
76
                    }
×
77
                    catch (Exception ex)
×
78
                    {
×
79
                        log.WarnFormat("Failed to instantiate type \"{0}\" from {1} - {2}.dll",
×
80
                                       assembly.FullName, assembly.FullName, ex.Message);
81
                    }
×
82
                }
×
83
            }
×
84
            catch (Exception ex)
×
85
            {
×
86
                log.WarnFormat("Failed to load assembly \"{0}\" - {1}",
×
87
                               dll, ex.Message);
88
            }
×
89
        }
×
90

91
        public void AddNewAssemblyToPluginsPath(string path)
92
        {
×
93
            if (Path.GetExtension(path) != ".dll")
×
94
            {
×
95
                log.ErrorFormat("Not a .dll, skipping..");
×
96
                return;
×
97
            }
98

99
            var targetPath = Path.Combine(m_PluginsPath, Path.GetFileName(path));
×
100
            if (File.Exists(targetPath))
×
101
            {
×
102
                try
103
                {
×
104
                    File.Delete(targetPath);
×
105
                }
×
106
                catch (Exception)
×
107
                {
×
108
                    log.ErrorFormat("Cannot copy plugin to {0}, because it already exists and is open..", targetPath);
×
109
                    return;
×
110
                }
111
            }
×
112

113
            File.Copy(path, targetPath);
×
NEW
114
            LoadAssembly(targetPath, false);
×
115
        }
×
116

117
        public void ActivatePlugin(IGUIPlugin plugin)
118
        {
×
119
            if (m_DormantPlugins.Contains(plugin))
×
120
            {
×
121
                try
122
                {
×
123
                    log.Debug("Initializing " + plugin.GetName());
×
124
                    plugin.Initialize();
×
125
                }
×
126
                catch (Exception ex)
×
127
                {
×
128
                    log.ErrorFormat("Failed to activate plugin \"{0} - {1}\" - {2}", plugin.GetName(), plugin.GetVersion(), ex.Message);
×
129
                    return;
×
130
                }
131

132
                m_ActivePlugins.Add(plugin);
×
133
                m_DormantPlugins.Remove(plugin);
×
134
                log.InfoFormat("Activated plugin \"{0} - {1}\"", plugin.GetName(), plugin.GetVersion());
×
135
            }
×
136
        }
×
137

138
        public void DeactivatePlugin(IGUIPlugin plugin)
139
        {
×
140
            if (m_ActivePlugins.Contains(plugin))
×
141
            {
×
142
                try
143
                {
×
144
                    log.Debug("Deinitialize " + plugin.GetName());
×
145
                    plugin.Deinitialize();
×
146
                }
×
147
                catch (Exception ex)
×
148
                {
×
149
                    log.ErrorFormat("Failed to deactivate plugin \"{0} - {1}\" - {2}", plugin.GetName(), plugin.GetVersion(), ex.Message);
×
150
                    return;
×
151
                }
152

153
                m_DormantPlugins.Add(plugin);
×
154
                m_ActivePlugins.Remove(plugin);
×
155
                log.InfoFormat("Deactivated plugin \"{0} - {1}\"", plugin.GetName(), plugin.GetVersion());
×
156
            }
×
157
        }
×
158

159
        public void UnloadPlugin(IGUIPlugin plugin)
160
        {
×
161
            if (m_ActivePlugins.Contains(plugin))
×
162
            {
×
163
                log.Debug("Deactivate " + plugin.GetName());
×
164
                DeactivatePlugin(plugin);
×
165
            }
×
NEW
166
            m_DormantPlugins.Remove(plugin);
×
167
        }
×
168

NEW
169
        public IReadOnlyCollection<IGUIPlugin> ActivePlugins  => m_ActivePlugins;
×
NEW
170
        public IReadOnlyCollection<IGUIPlugin> DormantPlugins => m_DormantPlugins;
×
171

NEW
172
        private readonly string              m_PluginsPath    = "";
×
173
        private readonly HashSet<IGUIPlugin> m_ActivePlugins  = new HashSet<IGUIPlugin>();
×
174
        private readonly HashSet<IGUIPlugin> m_DormantPlugins = new HashSet<IGUIPlugin>();
×
175

NEW
176
        private static readonly ILog log = LogManager.GetLogger(typeof(PluginController));
×
177
    }
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc