Skip to content

Commit

Permalink
Merge #3426 Override provides prompt with relationship property, chec…
Browse files Browse the repository at this point in the history
…k first recommendation in any_of group
  • Loading branch information
HebaruSan committed Aug 8, 2021
2 parents a833159 + 7dd593c commit 241741f
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 43 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Japanese Localization (#3394 by: utah239; reviewed: HebaruSan)
- [Multiple] Match underscore in DLL to dash in identifier (#3412 by: HebaruSan; reviewed: DasSkelett)
- [CLI] Add versions table option to ckan show command (#3414 by: HebaruSan; reviewed: DasSkelett)
- [Multiple] Override provides prompt with relationship property, check first recommendation in any_of group (#3426 by: HebaruSan; reviewed: DasSkelett)

### Bugfixes

Expand Down
8 changes: 8 additions & 0 deletions CKAN.schema
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@
"max_version" : {
"description" : "Optional maximum version",
"$ref" : "#/definitions/version"
},
"choice_help_text": {
"description" : "Optional help text shown when user has to choose among multiple modules",
"type" : "string"
}
},
"required" : [ "name" ]
Expand All @@ -394,6 +398,10 @@
"any_of": {
"description": "List of modules that can satisfy this relationship",
"$ref": "#/definitions/relationship"
},
"choice_help_text": {
"description" : "Optional help text shown when user has to choose among multiple modules",
"type" : "string"
}
},
"required": [ "any_of" ]
Expand Down
22 changes: 7 additions & 15 deletions Cmdline/Action/Install.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,25 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options)
}
catch (TooManyModsProvideKraken ex)
{
// Request the user selects one of the mods.
string[] mods = new string[ex.modules.Count];

for (int i = 0; i < ex.modules.Count; i++)
{
mods[i] = String.Format("{0} ({1})", ex.modules[i].identifier, ex.modules[i].name);
}

string message = String.Format("Too many mods provide {0}. Please pick from the following:\r\n", ex.requested);

// Request the user selects one of the mods
int result;

try
{
result = user.RaiseSelectionDialog(message, mods);
result = user.RaiseSelectionDialog(
ex.Message,
ex.modules
.Select(m => string.Format("{0} ({1})", m.identifier, m.name))
.ToArray());
}
catch (Kraken e)
{
user.RaiseMessage(e.Message);

return Exit.ERROR;
}

if (result < 0)
{
user.RaiseMessage(String.Empty); // Looks tidier.

user.RaiseMessage("");
return Exit.ERROR;
}

Expand Down
2 changes: 1 addition & 1 deletion Cmdline/Action/Upgrade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private static void UpgradeModules(
catch (TooManyModsProvideKraken k)
{
int choice = user.RaiseSelectionDialog(
$"Choose a module to provide {k.requested}:",
k.Message,
k.modules.Select(m => $"{m.identifier} ({m.name})").ToArray());
if (choice < 0)
{
Expand Down
2 changes: 1 addition & 1 deletion ConsoleUI/InstallScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null
} catch (TooManyModsProvideKraken ex) {

ConsoleChoiceDialog<CkanModule> ch = new ConsoleChoiceDialog<CkanModule>(
$"Module {ex.requested} is provided by multiple modules. Which would you like to install?",
ex.Message,
"Name",
ex.modules,
(CkanModule mod) => mod.ToString()
Expand Down
7 changes: 5 additions & 2 deletions Core/Converters/JsonRelationshipConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
if (child["any_of"] != null)
{
// Catch confused/invalid metadata
if (child.Properties().Count() > 1)
foreach (string forbiddenPropertyName in AnyOfRelationshipDescriptor.ForbiddenPropertyNames)
{
throw new Kraken("`any_of` should not be combined with other properties");
if (child.Property(forbiddenPropertyName) != null)
{
throw new Kraken($"`any_of` should not be combined with `{forbiddenPropertyName}`");
}
}
rels.Add(child.ToObject<AnyOfRelationshipDescriptor>());
}
Expand Down
11 changes: 7 additions & 4 deletions Core/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,7 @@ out Dictionary<CkanModule, HashSet<string>> supporters
)
{
Dictionary<CkanModule, List<string>> dependersIndex = getDependersIndex(sourceModules, registry, toInstall);
var instList = toInstall.ToList();
recommendations = new Dictionary<CkanModule, Tuple<bool, List<string>>>();
suggestions = new Dictionary<CkanModule, List<string>>();
supporters = new Dictionary<CkanModule, HashSet<string>>();
Expand All @@ -1194,21 +1195,23 @@ out Dictionary<CkanModule, HashSet<string>> supporters
registry,
ksp.VersionCriteria()
);
int i = 0;
foreach (CkanModule provider in providers)
{
if (!registry.IsInstalled(provider.identifier)
&& !toInstall.Any(m => m.identifier == provider.identifier)
&& dependersIndex.TryGetValue(provider, out List<string> dependers)
&& (provider.IsDLC || CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry)))
instList.Concat(new List<CkanModule>() { provider }).ToList(), registry)))
{
dependersIndex.Remove(provider);
recommendations.Add(
provider,
new Tuple<bool, List<string>>(
!provider.IsDLC && (providers.Count <= 1 || provider.identifier == (rel as ModuleRelationshipDescriptor)?.name),
!provider.IsDLC && (i == 0 || provider.identifier == (rel as ModuleRelationshipDescriptor)?.name),
dependers)
);
++i;
}
}
}
Expand All @@ -1227,7 +1230,7 @@ out Dictionary<CkanModule, HashSet<string>> supporters
&& !toInstall.Any(m => m.identifier == provider.identifier)
&& dependersIndex.TryGetValue(provider, out List<string> dependers)
&& (provider.IsDLC || CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry)))
instList.Concat(new List<CkanModule>() { provider }).ToList(), registry)))
{
dependersIndex.Remove(provider);
suggestions.Add(provider, dependers);
Expand Down Expand Up @@ -1267,7 +1270,7 @@ out Dictionary<CkanModule, HashSet<string>> supporters
}
supporters.RemoveWhere(kvp => !CanInstall(
RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { kvp.Key }).ToList(),
instList.Concat(new List<CkanModule>() { kvp.Key }).ToList(),
registry
));

Expand Down
4 changes: 2 additions & 2 deletions Core/Relationships/RelationshipResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -477,13 +477,13 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Selection
{
//We still have either nothing, or too many to pick from
//Just throw the TMP now
throw new TooManyModsProvideKraken(descriptor.ToString(), candidates);
throw new TooManyModsProvideKraken(descriptor.ToString(), candidates, descriptor.choice_help_text);
}
candidates[0] = provide.First();
}
else
{
throw new TooManyModsProvideKraken(descriptor.ToString(), candidates);
throw new TooManyModsProvideKraken(descriptor.ToString(), candidates, descriptor.choice_help_text);
}
}

Expand Down
22 changes: 13 additions & 9 deletions Core/Types/Kraken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,24 @@ public RegistryVersionNotSupportedKraken(int v, string reason = null, Exception

public class TooManyModsProvideKraken : Kraken
{
public List<CkanModule> modules;
public string requested;
public readonly List<CkanModule> modules;
public readonly string requested;
public readonly string choice_help_text;

public TooManyModsProvideKraken(string requested, List<CkanModule> modules, Exception innerException = null)
: base(FormatMessage(requested, modules), innerException)
public TooManyModsProvideKraken(string requested, List<CkanModule> modules, string choice_help_text = null, Exception innerException = null)
: base(FormatMessage(requested, modules, choice_help_text), innerException)
{
this.modules = modules;
this.requested = requested;
this.requested = requested;
this.modules = modules;
this.choice_help_text = choice_help_text;
}

internal static string FormatMessage(string requested, List<CkanModule> modules)
private static string FormatMessage(string requested, List<CkanModule> modules, string choice_help_text = null)
{
string oops = string.Format("Too many mods provide {0}:\r\n", requested);
return oops + String.Join("\r\n", modules.Select(m => $"* {m}"));
return choice_help_text
?? string.Format(
"Module {0} is provided by more than one available module. Please choose one of the following:",
requested);
}
}

Expand Down
15 changes: 12 additions & 3 deletions Core/Types/RelationshipDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public abstract List<CkanModule> LatestAvailableWithProvides(

public abstract bool StartsWith(string prefix);

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string choice_help_text;

// virtual ToString() already present in 'object'
}

Expand All @@ -42,7 +45,6 @@ public class ModuleRelationshipDescriptor : RelationshipDescriptor
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public ModuleVersion version;


public override bool WithinBounds(CkanModule otherModule)
{
return otherModule.ProvidesList.Contains(name)
Expand Down Expand Up @@ -169,7 +171,6 @@ public override bool StartsWith(string prefix)
return name.IndexOf(prefix, StringComparison.CurrentCultureIgnoreCase) == 0;
}


/// <summary>
/// A user friendly message for what versions satisfies this descriptor.
/// </summary>
Expand Down Expand Up @@ -215,6 +216,14 @@ public class AnyOfRelationshipDescriptor : RelationshipDescriptor
[JsonConverter(typeof(JsonRelationshipConverter))]
public List<RelationshipDescriptor> any_of;

public static readonly List<string> ForbiddenPropertyNames = new List<string>()
{
"name",
"version",
"min_version",
"max_version"
};

public override bool WithinBounds(CkanModule otherModule)
{
return any_of?.Any(r => r.WithinBounds(otherModule))
Expand All @@ -236,7 +245,7 @@ public override List<CkanModule> LatestAvailableWithProvides(
IEnumerable<CkanModule> toInstall = null
)
{
return any_of?.SelectMany(r => r.LatestAvailableWithProvides(registry, crit, installed, toInstall)).ToList();
return any_of?.SelectMany(r => r.LatestAvailableWithProvides(registry, crit, installed, toInstall)).Distinct().ToList();
}

public override bool Equals(RelationshipDescriptor other)
Expand Down
7 changes: 2 additions & 5 deletions GUI/Controls/ChooseProvidedMods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ public ChooseProvidedMods()
InitializeComponent();
}

public void LoadProviders(string requested, List<CkanModule> modules, NetModuleCache cache)
public void LoadProviders(string message, List<CkanModule> modules, NetModuleCache cache)
{
Util.Invoke(this, () =>
{
ChooseProvidedModsLabel.Text = String.Format(
Properties.Resources.MainInstallProvidedBy,
requested
);
ChooseProvidedModsLabel.Text = message;
ChooseProvidedModsListView.Items.Clear();
ChooseProvidedModsListView.Items.AddRange(modules
Expand Down
2 changes: 1 addition & 1 deletion GUI/Main/MainInstall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ out Dictionary<CkanModule, HashSet<string>> supporters
{
// Prompt user to choose which mod to use
tabController.ShowTab("ChooseProvidedModsTabPage", 3);
ChooseProvidedMods.LoadProviders(k.requested, k.modules, Manager.Cache);
ChooseProvidedMods.LoadProviders(k.Message, k.modules, Manager.Cache);
tabController.SetTabLock(true);
CkanModule chosen = ChooseProvidedMods.Wait();
// Close the selection prompt
Expand Down

0 comments on commit 241741f

Please sign in to comment.