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

KSP-CKAN / CKAN / 15889942503

26 Jun 2025 12:20AM UTC coverage: 47.631% (+5.4%) from 42.239%
15889942503

push

github

HebaruSan
Merge #4400 Make hash caches thread-safe, Netkan warning for uncompiled plugins

3880 of 8730 branches covered (44.44%)

Branch coverage included in aggregate %.

33 of 75 new or added lines in 9 files covered. (44.0%)

6 existing lines in 3 files now uncovered.

8334 of 16913 relevant lines covered (49.28%)

1.01 hits per line

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

61.43
/Core/Registry/InstalledModule.cs
1
using System;
2
using System.Linq;
3
using System.ComponentModel;
4
using System.Collections.Generic;
5
using System.IO;
6
using System.Runtime.Serialization;
7

8
using CKAN.IO;
9
using Newtonsoft.Json;
10

11
namespace CKAN
12
{
13
    [JsonObject(MemberSerialization.OptIn)]
14
    public class InstalledModuleFile
15
    {
16
        [JsonConstructor]
17
        public InstalledModuleFile()
2✔
18
        {
2✔
19
        }
2✔
20
    }
21

22
    /// <summary>
23
    /// A simple class that represents an installed module. Includes the time of installation,
24
    /// the module itself, and a list of files installed with it.
25
    ///
26
    /// Primarily used by the Registry class.
27
    /// </summary>
28

29
    [JsonObject(MemberSerialization.OptIn)]
30
    public class InstalledModule
31
    {
32
        #region Fields and Properties
33

34
        [JsonProperty]
35
        private readonly DateTime install_time;
36

37
        [JsonProperty]
38
        private readonly CkanModule source_module;
39

40
        [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
41
        [DefaultValue(false)]
42
        private bool auto_installed;
43

44
        // TODO: Our InstalledModuleFile already knows its path, so this could just
45
        // be a list. However we've left it as a dictionary for now to maintain
46
        // registry format compatibility.
47
        [JsonProperty]
48
        private Dictionary<string, InstalledModuleFile> installed_files;
49

50
        public IReadOnlyCollection<string> Files       => installed_files.Keys;
2✔
51
        public string                      identifier  => source_module.identifier;
2✔
52
        public CkanModule                  Module      => source_module;
2✔
53
        public DateTime                    InstallTime => install_time;
×
54

55
        public bool AutoInstalled
56
        {
57
            get => auto_installed;
2✔
58
            set {
×
59
                if (Module.IsDLC)
×
60
                {
×
61
                    throw new ModuleIsDLCKraken(Module);
×
62
                }
63
                auto_installed = value;
×
64
            }
×
65
        }
66

67
        #endregion
68

69
        #region Constructors
70

71
        public InstalledModule(GameInstance? ksp, CkanModule module, IEnumerable<string> relative_files, bool autoInstalled)
2✔
72
        {
2✔
73
            install_time = DateTime.Now;
2✔
74
            source_module = module;
2✔
75
            // We need case insensitive path matching on Windows
76
            installed_files = new Dictionary<string, InstalledModuleFile>(Platform.PathComparer);
2✔
77
            auto_installed = autoInstalled;
2✔
78

79
            if (ksp != null)
2✔
80
            {
2✔
81
                foreach (string file in relative_files)
5✔
82
                {
2✔
83
                    if (Path.IsPathRooted(file))
2!
84
                    {
×
85
                        throw new PathErrorKraken(file, "InstalledModule *must* have relative paths");
×
86
                    }
87

88
                    // IMF needs a KSP object so it can compute the SHA1.
89
                    installed_files[file] = new InstalledModuleFile();
2✔
90
                }
2✔
91
            }
2✔
92
        }
2✔
93

94
        #endregion
95

96
        #region Serialisation Fixes
97

98
        [OnDeserialized]
99
        private void DeSerialisationFixes(StreamingContext context)
100
        {
2✔
101
            installed_files ??= new Dictionary<string, InstalledModuleFile>();
2!
102
            if (Platform.IsWindows)
2!
103
            {
×
104
                // We need case insensitive path matching on Windows
105
                installed_files = new Dictionary<string, InstalledModuleFile>(installed_files,
×
106
                                                                              Platform.PathComparer);
107
            }
×
108
        }
2✔
109

110
        /// <summary>
111
        /// Ensures all files for this module have relative paths.
112
        /// Called when upgrading registry versions. Should be a no-op
113
        /// if called on newer registries.
114
        /// </summary>
115
        public void Renormalise(GameInstance inst)
116
        {
×
NEW
117
            installed_files = installed_files.ToDictionary(
×
NEW
118
                                  kvp => Path.IsPathRooted(kvp.Key)
×
119
                                             ? inst.ToRelativeGameDir(kvp.Key)
120
                                             : CKANPathUtils.NormalizePath(kvp.Key),
NEW
121
                                  kvp => kvp.Value,
×
122
                                  // We need case insensitive path matching on Windows
123
                                  Platform.PathComparer);
UNCOV
124
        }
×
125

126
        #endregion
127

128
        public bool AllFilesExist(GameInstance    instance,
129
                                  HashSet<string> filters)
130
            // Don't make them reinstall files they've filtered out since installing
131
            => Files.Where(f => !filters.Any(filt => f.Contains(filt)))
1✔
132
                    .Select(instance.ToAbsoluteGameDir)
133
                    .All(p => Directory.Exists(p) || File.Exists(p));
2✔
134

135
        public override string ToString()
136
            => string.Format(AutoInstalled ? Properties.Resources.InstalledModuleToStringAutoInstalled
×
137
                                           : Properties.Resources.InstalledModuleToString,
138
                             Module,
139
                             InstallTime);
140
    }
141
}
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