Skip to content

Commit

Permalink
More command-line argument additions.
Browse files Browse the repository at this point in the history
Rename upload and download verbs to push and get.
Add additional argument aliases, rename exclude/include arguments, and add explicit add/remove for dependencies and DLC.
Rewrite README.md with better organization, and links.
Enforce dependencies as workshop mods.
  • Loading branch information
Gwindalmir committed Sep 4, 2021
1 parent c8a40e3 commit ec7e8c4
Show file tree
Hide file tree
Showing 11 changed files with 702 additions and 282 deletions.
391 changes: 282 additions & 109 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
</ItemGroup>
Expand Down
13 changes: 3 additions & 10 deletions WorkshopToolCommon/GameBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public virtual int InitGame(string[] args)
ProcessedOptions options = default(ProcessedOptions);
var parser = new CommandLine.Parser(with => with.HelpWriter = null);

var result = parser.ParseArguments<DownloadVerb, UploadVerb, PublishVerb, CompileVerb, CloudVerb>(args)
var result = parser.ParseArguments<DownloadVerb, UploadVerb, PublishVerb, ChangeVerb, CompileVerb, CloudVerb>(args)
.WithParsed(o => options = (ProcessedOptions)(dynamic)o)
.WithNotParsed(l =>
{
Expand All @@ -140,6 +140,8 @@ public virtual int InitGame(string[] args)
newargs = parser.FormatCommandLine((UploadVerb)options, s=> s.SkipDefault = true);
else if (options.Download)
newargs = parser.FormatCommandLine((DownloadVerb)options, s => s.SkipDefault = true);
else if (options.Type == typeof(ChangeVerb))
newargs = parser.FormatCommandLine((ChangeVerb)options, s => s.SkipDefault = true);
else if (options.Type == typeof(CloudVerb))
newargs = parser.FormatCommandLine((CloudVerb)options, s => s.SkipDefault = true);
Expand Down Expand Up @@ -192,15 +194,6 @@ public virtual int InitGame(string[] args)
}
}

// If a "0" or "none" was specified for DLC, that means remove them all.
if(options.DLCs?.Count() > 0 &&
(options.DLCs.Contains("0") || options.DLCs.Contains("none", StringComparer.InvariantCultureIgnoreCase)))
options.DLCs = new string[0];

// If a 0 was specified for dependencies, that means remove them all.
if (options.Dependencies?.Count() > 0 && options.Dependencies.Contains((ulong)0))
options.Dependencies = new ulong[0];

// SE requires -appdata, but the commandline dll requires --appdata, so fix it
for (var idx = 0; idx < args.Length; idx++)
if (string.Compare(args[idx], "--appdata", StringComparison.InvariantCultureIgnoreCase) == 0)
Expand Down
11 changes: 11 additions & 0 deletions WorkshopToolCommon/Options/ChangeVerb.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using CommandLine;
using System;
using System.Collections.Generic;
using System.Text;

namespace Phoenix.WorkshopTool.Options
{
[Verb("change", HelpText = "Push metadata changes to workshop items (tags, thumbnail, etc.)")]
public class ChangeVerb : PublishVerbBase
{ }
}
3 changes: 1 addition & 2 deletions WorkshopToolCommon/Options/DownloadVerb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@

namespace Phoenix.WorkshopTool.Options
{
[Verb("download", HelpText = "Download workshop items")]
[Verb("get", HelpText = "Download workshop items")]
public class DownloadVerb : OptionBase
{
[Option("ids", Required = true, Min = 1, HelpText = "Workshop IDs of items or collections to download")]
public IEnumerable<ulong> Ids { get; set; }

[Option('E', "no-extract", Default = false, HelpText = "Don't automatically extract downloaded workshop items to AppData.")]
public bool NoExtract { get; set; }

}
}
6 changes: 3 additions & 3 deletions WorkshopToolCommon/Options/LegacyOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public sealed class LegacyOptions : Options.OptionBase
[Option("visibility", Default = null, HelpText = "Sets mod visibility (for new only). Accepted values: Public, FriendsOnly, Private, Unlisted")]
public PublishedFileVisibility? Visibility { get; set; }

[Option("dev", Default = false, HelpText = "Set to true if the mod will have the 'development' tag when uploaded (deprecated)")]
[Option("dev", Default = false, Hidden = true, HelpText = "This is obsolete and no longer functional.")]
public bool Development { get; set; }

[Option('c', "compile", Default = false, HelpText = "Compile the mod before uploading. Will not upload if compilation fails.")]
Expand Down Expand Up @@ -77,8 +77,8 @@ public sealed class LegacyOptions : Options.OptionBase
#endif
public IEnumerable<string> DLCs { get; set; }

[Option("dependencies", HelpText = "Specify dependencies to other mods (modids only). Use 0 to remove all.")]
public IEnumerable<ulong> Dependencies { get; set; }
[Option("dependencies", HelpText = "Specify dependencies to other mods. Use 0 to remove all.")]
public IEnumerable<string> Dependencies { get; set; }

[Option("description", HelpText = "File containing the description to set for workshop item")]
public string DescriptionFile { get; set; }
Expand Down
137 changes: 117 additions & 20 deletions WorkshopToolCommon/Options/ProcessedOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,68 @@ public IList<string> TagsToAdd
IList<string> _tagsToRemove;
public IList<string> TagsToRemove
{
get => _tagsToAdd;
get => _tagsToRemove;
set
{
if (value != null)
{
var tags = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
value.ForEach(s => s.Split(',', ';').ForEach(t => tags.Add(t)));
_tagsToAdd = tags.ToList();
_tagsToRemove = tags.ToList();
}
}
}

IList<string> _dependencies;
public IList<string> Dependencies
{
get => _dependencies;
set
{
// If user comma-separated the dependencies, split them
if (value != null)
{
var dependencies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
value.ForEach(s => s.Split(',', ';').ForEach(t => dependencies.Add(t)));
_dependencies = dependencies.ToList();
}
}
}

IList<string> _dependenciesToAdd;
public IList<string> DependenciesToAdd
{
get => _dependenciesToAdd;
set
{
if (value != null)
{
var dependencies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
value.ForEach(s => s.Split(',', ';').ForEach(t => dependencies.Add(t)));
_dependenciesToAdd = dependencies.ToList();
}
}
}

IList<string> _dependenciesToRemove;
public IList<string> DependenciesToRemove
{
get => _dependenciesToRemove;
set
{
if (value != null)
{
var dependencies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
value.ForEach(s => s.Split(',', ';').ForEach(t => dependencies.Add(t)));
_dependenciesToRemove = dependencies.ToList();
}
}
}

public IList<string> DLCs { get; set; }
public IList<ulong> Dependencies { get; set; }
public IList<string> DLCToAdd { get; set; }
public IList<string> DLCToRemove { get; set; }

public string Thumbnail { get; set; }
public string DescriptionFile { get; set; }
public string Changelog { get; set; }
Expand All @@ -102,46 +150,64 @@ public ProcessedOptions(DownloadVerb options)
}

public ProcessedOptions(UploadVerb options)
: this((OptionBase)options)
: this((PublishVerbBase)options)
{
UpdateOnly = options.UpdateOnly;
DryRun = options.DryRun;
Compile = options.Compile;
Changelog = options.Changelog;

ExcludeExtensions = options.ExcludeExtensions?.ToList();
IgnorePaths = options.IgnorePaths?.ToList();
}

public ProcessedOptions(ChangeVerb options)
: this((PublishVerbBase)options)
{
}

public ProcessedOptions(CompileVerb options)
: this((UGCOptionBase)options)
{
Compile = true;
}

public ProcessedOptions(CloudVerb options)
: this((OptionBase)options)
{
ListCloud = options.List;
Files = options.Files;
Clear = options.Clear;
}

public ProcessedOptions(PublishVerbBase options)
: this((UGCOptionBase)options)
{
DryRun = options.DryRun;
Thumbnail = options.Thumbnail;
DescriptionFile = options.DescriptionFile;
Changelog = options.Changelog;
Visibility = options.Visibility;

Mods = options.Mods?.ToList();
Blueprints = options.Blueprints?.ToList();
Scenarios = options.Scenarios?.ToList();
IngameScripts = options.IngameScripts?.ToList();

ExcludeExtensions = options.ExcludeExtensions?.ToList();
IgnorePaths = options.IgnorePaths?.ToList();
Tags = options.Tags?.ToList();
TagsToAdd = options.TagsToAdd?.ToList();
TagsToRemove = options.TagsToRemove?.ToList();
DLCs = options.DLCs?.ToList();
DLCToAdd = options.DLCToAdd?.ToList();
DLCToRemove = options.DLCToRemove?.ToList();
Dependencies = options.Dependencies?.ToList();
DependenciesToAdd = options.DependenciesToAdd?.ToList();
DependenciesToRemove = options.DependenciesToRemove?.ToList();
}

public ProcessedOptions(CompileVerb options)
public ProcessedOptions(UGCOptionBase options)
: this((OptionBase)options)
{
Compile = true;
Mods = options.Mods?.ToList();
IngameScripts = options.IngameScripts?.ToList();
}

public ProcessedOptions(CloudVerb options)
: this((OptionBase)options)
{
ListCloud = options.List;
Files = options.Files;
Clear = options.Clear;
}

public ProcessedOptions(OptionBase options)
{
Type = options.GetType();
Expand Down Expand Up @@ -209,6 +275,7 @@ public ProcessedOptions(LegacyOptions options)

public static implicit operator ProcessedOptions(DownloadVerb options) => new ProcessedOptions(options);
public static implicit operator ProcessedOptions(UploadVerb options) => new ProcessedOptions(options);
public static implicit operator ProcessedOptions(ChangeVerb options) => new ProcessedOptions(options);
public static implicit operator ProcessedOptions(CompileVerb options) => new ProcessedOptions(options);
public static implicit operator ProcessedOptions(CloudVerb options) => new ProcessedOptions(options);
public static implicit operator ProcessedOptions(LegacyOptions options) => new ProcessedOptions(options);
Expand Down Expand Up @@ -251,7 +318,11 @@ public ProcessedOptions(LegacyOptions options)
result.Visibility = options.Visibility;
result.Blueprints = options.Blueprints;
result.Dependencies = options.Dependencies;
result.DependenciesToAdd = options.DependenciesToAdd;
result.DependenciesToRemove = options.DependenciesToRemove;
result.DLCs = options.DLCs;
result.DLCToAdd = options.DLCToAdd;
result.DLCToRemove = options.DLCToRemove;
result.ExcludeExtensions = options.ExcludeExtensions;
result.IgnorePaths = options.IgnorePaths;
result.IngameScripts = options.IngameScripts;
Expand All @@ -260,7 +331,33 @@ public ProcessedOptions(LegacyOptions options)
result.Tags = options.Tags;
result.TagsToAdd = options.TagsToAdd;
result.TagsToRemove = options.TagsToRemove;
result.Worlds = options.Worlds;
return result;
}

public static explicit operator ChangeVerb(ProcessedOptions options)
{
var result = new ChangeVerb();
result.AppData = options.AppData;
result.Force = options.Force;
result.ModIO = options.ModIO;
result.DescriptionFile = options.Changelog;
result.DryRun = options.DryRun;
result.Thumbnail = options.Thumbnail;
result.Visibility = options.Visibility;
result.Blueprints = options.Blueprints;
result.Dependencies = options.Dependencies;
result.DependenciesToAdd = options.DependenciesToAdd;
result.DependenciesToRemove = options.DependenciesToRemove;
result.DLCs = options.DLCs;
result.DLCToAdd = options.DLCToAdd;
result.DLCToRemove = options.DLCToRemove;
result.IngameScripts = options.IngameScripts;
result.Mods = options.Mods;
result.Scenarios = options.Scenarios;
result.Tags = options.Tags;
result.TagsToAdd = options.TagsToAdd;
result.TagsToRemove = options.TagsToRemove;
result.Worlds = options.Worlds;
return result;
}
Expand Down
79 changes: 79 additions & 0 deletions WorkshopToolCommon/Options/PublishVerbBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using CommandLine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Phoenix.WorkshopTool.Options
{
public abstract class PublishVerbBase : UGCOptionBase
{
[Option('d', "dry-run", Default = false, HelpText = "Only run a test, do not actually upload")]
public bool DryRun { get; set; }
[Option('d', "dryrun", Default = false, HelpText = "Only run a test, do not actually upload", Hidden = true)]
public bool Dry_Run { get => DryRun; set => DryRun = DryRun || value; }

[Option("description", HelpText = "File containing the description to set for workshop item", MetaValue = "<filename>")]
public string DescriptionFile { get; set; }

[Option("visibility", Default = null, HelpText = "Sets mod visibility (defaults: current for existing, Private for new)")]
public PublishedFileVisibility? Visibility { get; set; }

[Option("thumb", HelpText = "Thumbnail to upload (doesn't re-upload mod)", MetaValue = "<filename>")]
public string Thumbnail { get; set; }

[Option("dependencies", HelpText = "Specify dependencies to other mods. Use 0 to remove all.", MetaValue = "<id>")]
public IEnumerable<string> Dependencies { get; set; }

// Provide aliases for add-dependency and remove-dependency, as add-dependencies and remove-dependencies, respectively
protected IList<string> _dependenciesToAdd = new List<string>();
[Option("add-dependency", HelpText = "List of dependencies to add", Hidden = true)]
public IEnumerable<string> DependencyToAdd { get => _dependenciesToAdd; set => value?.ForEach(t => _dependenciesToAdd.Add(t)); }
[Option("add-dependencies", HelpText = "List of dependencies to add")]
public IEnumerable<string> DependenciesToAdd { get => _dependenciesToAdd; set => value?.ForEach(t => _dependenciesToAdd.Add(t)); }

protected IList<string> _dependenciesToRemove = new List<string>();
[Option("remove-dependency", HelpText = "List of dependencies to remove", Hidden = true)]
public IEnumerable<string> DependencyToRemove { get => _dependenciesToRemove; set => value?.ForEach(t => _dependenciesToRemove.Add(t)); }
[Option("remove-dependencies", HelpText = "List of dependencies to remove")]
public IEnumerable<string> DependenciesToRemove { get => _dependenciesToRemove; set => value?.ForEach(t => _dependenciesToRemove.Add(t)); }

internal bool TagsSpecified => Tags != null || TagsToAdd != null || TagsToRemove != null;

[Option("tags", HelpText = "List of workshop mod categories/tags to use (overwrites previous, default: keep)")]
public IEnumerable<string> Tags { get; set; }

// Provide aliases for add-tag and remove-tag, as add-tags and remove-tags, respectively
protected IList<string> _tagsToAdd = new List<string>();
[Option("add-tag", HelpText = "List of workshop categories/tags to add", Hidden = true)]
public IEnumerable<string> TagToAdd { get => _tagsToAdd; set => value?.ForEach(t => _tagsToAdd.Add(t)); }
[Option("add-tags", HelpText = "List of workshop categories/tags to add")]
public IEnumerable<string> TagsToAdd { get => _tagsToAdd; set => value?.ForEach(t => _tagsToAdd.Add(t)); }

protected IList<string> _tagsToRemove = new List<string>();
[Option("remove-tag", HelpText = "List of workshop categories/tags to remove", Hidden = true)]
public IEnumerable<string> TagToRemove { get => _tagsToRemove; set => value?.ForEach(t => _tagsToRemove.Add(t)); }
[Option("remove-tags", HelpText = "List of workshop categories/tags to remove")]
public IEnumerable<string> TagsToRemove { get => _tagsToRemove; set => value?.ForEach(t => _tagsToRemove.Add(t)); }

#if SE
[Option("dlc", HelpText = "Add DLC dependency to mod, accepts numeric ID or name. Use 0 or None to remove all.")]
#endif
public IEnumerable<string> DLCs { get; set; }

[Option("add-dlc", HelpText = "Add DLC dependency to mod.")]
public IEnumerable<string> DLCToAdd { get; set; }

[Option("remove-dlc", HelpText = "Remove DLC dependency from mod.")]
public IEnumerable<string> DLCToRemove { get; set; }

[Option("blueprints", Min = 1, Group = "workshop", HelpText = "List of folder names of blueprints")]
public IEnumerable<string> Blueprints { get; set; }

[Option("scenarios", Min = 1, Group = "workshop", HelpText = "List of folder names of scenarios")]
public IEnumerable<string> Scenarios { get; set; }

[Option("worlds", Min = 1, Group = "workshop", HelpText = "List of folder names of worlds")]
public IEnumerable<string> Worlds { get; set; }
}
}

0 comments on commit ec7e8c4

Please sign in to comment.