Skip to content

Commit abd1d87

Browse files
committed
Basic app install and app update commands
1 parent 4d5c0b0 commit abd1d87

File tree

4 files changed

+222
-1
lines changed

4 files changed

+222
-1
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Globalization;
17+
using System.Linq;
18+
using System.Threading.Tasks;
19+
using SeqCli.Cli.Features;
20+
using SeqCli.Config;
21+
using SeqCli.Connection;
22+
using SeqCli.Util;
23+
using Serilog;
24+
25+
#nullable enable
26+
27+
namespace SeqCli.Cli.Commands.App;
28+
29+
[Command("app", "install", "Install an app package",
30+
Example = "seqcli app install --package-id 'Seq.App.JsonArchive'")]
31+
// ReSharper disable once UnusedType.Global
32+
class InstallCommand : Command
33+
{
34+
readonly SeqConnectionFactory _connectionFactory;
35+
36+
readonly ConnectionFeature _connection;
37+
readonly OutputFormatFeature _output;
38+
39+
string? _packageId, _version, _feedId;
40+
41+
public InstallCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config)
42+
{
43+
_connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory));
44+
45+
Options.Add(
46+
"package-id=",
47+
"The package id of the app to install",
48+
packageId => _packageId = ArgumentString.Normalize(packageId));
49+
50+
Options.Add(
51+
"version=",
52+
"The package version to install; the default is to install the latest version",
53+
version => _version = ArgumentString.Normalize(version));
54+
55+
Options.Add(
56+
"feed-id=",
57+
"The id of the NuGet feed to install the package from; may be omitted if only one feed is configured",
58+
feedId => _feedId = ArgumentString.Normalize(feedId));
59+
60+
_connection = Enable<ConnectionFeature>();
61+
_output = Enable(new OutputFormatFeature(config.Output));
62+
}
63+
64+
protected override async Task<int> Run()
65+
{
66+
if (_packageId == null)
67+
{
68+
Log.Error("A `package-id` is required");
69+
return 1;
70+
}
71+
72+
var connection = _connectionFactory.Connect(_connection);
73+
74+
var feedId = _feedId;
75+
if (feedId == null)
76+
{
77+
var feeds = await connection.Feeds.ListAsync();
78+
if (feeds.Count != 1)
79+
{
80+
Log.Error("A `feed-id` is required unless the server has exactly one configured feed");
81+
return 1;
82+
}
83+
84+
feedId = feeds.Single().Id;
85+
}
86+
87+
var app = await connection.Apps.InstallPackageAsync(feedId, _packageId, _version);
88+
_output.WriteEntity(app);
89+
90+
return 0;
91+
}
92+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Globalization;
17+
using System.Threading.Tasks;
18+
using SeqCli.Cli.Features;
19+
using SeqCli.Config;
20+
using SeqCli.Connection;
21+
using SeqCli.Util;
22+
using Serilog;
23+
24+
#nullable enable
25+
26+
namespace SeqCli.Cli.Commands.App;
27+
28+
[Command("app", "update", "Update an installed app package",
29+
Example = "seqcli app update -n 'HTML Email'")]
30+
// ReSharper disable once UnusedType.Global
31+
class UpdateCommand : Command
32+
{
33+
readonly SeqConnectionFactory _connectionFactory;
34+
35+
readonly ConnectionFeature _connection;
36+
readonly OutputFormatFeature _output;
37+
38+
string? _id, _name, _version;
39+
bool _all, _force;
40+
41+
public UpdateCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config)
42+
{
43+
_connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory));
44+
45+
Options.Add(
46+
"i=|id=",
47+
"The id of a single installed app to update",
48+
id => _id = ArgumentString.Normalize(id));
49+
50+
Options.Add(
51+
"n=|name=",
52+
"The name of the installed app to update",
53+
name => _name = ArgumentString.Normalize(name));
54+
55+
Options.Add(
56+
"all",
57+
"Update all installed apps; not compatible with `-i` or `-n`",
58+
_ => _all = true);
59+
60+
Options.Add(
61+
"version=",
62+
"The package version to update to; the default is to update to the latest version in the associated feed",
63+
version => _version = ArgumentString.Normalize(version));
64+
65+
66+
Options.Add(
67+
"force",
68+
"Update the app even if the target version is already installed",
69+
_ => _force = true);
70+
71+
_connection = Enable<ConnectionFeature>();
72+
_output = Enable(new OutputFormatFeature(config.Output));
73+
}
74+
75+
protected override async Task<int> Run()
76+
{
77+
if (_all && (_id != null || _name != null) ||
78+
_id != null && _name != null)
79+
{
80+
Log.Error("The `id`, `name`, and `all` options are mutually exclusive");
81+
return 1;
82+
}
83+
84+
if (!_all && _id == null && _name == null)
85+
{
86+
Log.Error("One of `id`, `name`, or `all` must be specified");
87+
return 1;
88+
}
89+
90+
var connection = _connectionFactory.Connect(_connection);
91+
92+
var apps = await connection.Apps.ListAsync();
93+
foreach (var app in apps)
94+
{
95+
if (_all || app.Id == _id || _name != null && _name.Equals(app.Name, StringComparison.OrdinalIgnoreCase))
96+
{
97+
var updated = await connection.Apps.UpdatePackageAsync(app, _version, _force);
98+
_output.WriteEntity(updated);
99+
}
100+
}
101+
102+
return 0;
103+
}
104+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Threading.Tasks;
2+
using Seq.Api;
3+
using SeqCli.EndToEnd.Support;
4+
using Serilog;
5+
using Xunit;
6+
7+
namespace SeqCli.EndToEnd.App;
8+
9+
// ReSharper disable once UnusedType.Global
10+
public class AppBasicsTestCase: ICliTestCase
11+
{
12+
public Task ExecuteAsync(SeqConnection connection, ILogger logger, CliCommandRunner runner)
13+
{
14+
var exit = runner.Exec("feed list", "-n nuget.org");
15+
Assert.Equal(0, exit);
16+
17+
exit = runner.Exec("app install", "--package-id Seq.App.EmailPlus");
18+
Assert.Equal(0, exit);
19+
20+
exit = runner.Exec("app update", "--all");
21+
Assert.Equal(0, exit);
22+
23+
return Task.CompletedTask;
24+
}
25+
}

test/SeqCli.EndToEnd/Feed/FeedBasicsTestCase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static void AssertExistence(CliCommandRunner runner, string feedName, bool exist
4242
var exit = runner.Exec("feed list", $"-n {feedName}");
4343
Assert.Equal(0, exit);
4444

45-
var output = runner.LastRunProcess.Output;
45+
var output = runner.LastRunProcess!.Output;
4646

4747
if (exists)
4848
{

0 commit comments

Comments
 (0)