Skip to content

Commit b344e47

Browse files
committed
[cli] Disable spinner animation on non-live TTYs
Gating the spinner animation logic on the term->cout_is_live() flag. This prevents messy output (backspaces and animation frames) when Multipass is run in non-interactive environments.
1 parent afd36ee commit b344e47

File tree

12 files changed

+30
-20
lines changed

12 files changed

+30
-20
lines changed

src/client/cli/cmd/animated_spinner.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ void clear_line(std::ostream& out)
2929
}
3030
} // namespace
3131

32-
mp::AnimatedSpinner::AnimatedSpinner(std::ostream& cout)
33-
: spinner{'|', '/', '-', '\\'}, cout{cout}, running{false}
32+
mp::AnimatedSpinner::AnimatedSpinner(std::ostream& cout, bool is_tty)
33+
: spinner{'|', '/', '-', '\\'}, cout{cout}, running{false}, is_tty(is_tty)
3434
{
3535
}
3636

@@ -46,15 +46,23 @@ void mp::AnimatedSpinner::start(const std::string& start_message)
4646
{
4747
current_message = start_message;
4848
running = true;
49-
clear_line(cout);
50-
cout << start_message << " " << std::flush;
51-
t = std::thread(&AnimatedSpinner::draw, this);
49+
50+
if (is_tty)
51+
{
52+
clear_line(cout);
53+
cout << start_message << " " << std::flush;
54+
t = std::thread(&AnimatedSpinner::draw, this);
55+
}
56+
else
57+
{
58+
cout << start_message << std::flush;
59+
}
5260
}
5361
}
5462

5563
void mp::AnimatedSpinner::start()
5664
{
57-
if (!current_message.empty())
65+
if (is_tty && !current_message.empty())
5866
start(current_message);
5967
}
6068

@@ -69,7 +77,9 @@ void mp::AnimatedSpinner::stop()
6977
if (t.joinable())
7078
t.join();
7179
}
72-
clear_line(cout);
80+
81+
if (is_tty)
82+
clear_line(cout);
7383
}
7484

7585
void mp::AnimatedSpinner::print(std::ostream& stream, const std::string& message)
@@ -92,6 +102,5 @@ void mp::AnimatedSpinner::draw()
92102
cout << "\b" << *it << std::flush;
93103
cv.wait_for(lock, std::chrono::milliseconds(100));
94104
}
95-
cout << "\b"
96-
<< " " << std::flush;
105+
cout << "\b" << " " << std::flush;
97106
}

src/client/cli/cmd/animated_spinner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace multipass
2727
class AnimatedSpinner
2828
{
2929
public:
30-
explicit AnimatedSpinner(std::ostream& cout);
30+
explicit AnimatedSpinner(std::ostream& cout, bool is_tty = true);
3131
~AnimatedSpinner();
3232

3333
void start(const std::string& message);
@@ -44,5 +44,6 @@ class AnimatedSpinner
4444
std::mutex mutex;
4545
std::condition_variable cv;
4646
std::thread t;
47+
const bool is_tty;
4748
};
4849
} // namespace multipass

src/client/cli/cmd/clone.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ mp::ReturnCodeVariant cmd::Clone::run(ArgParser* parser)
3333
return parser->returnCodeFrom(parscode);
3434
}
3535

36-
AnimatedSpinner spinner{cout};
36+
AnimatedSpinner spinner{cout, term->cout_is_live()};
3737
auto action_on_success = [this, &spinner](CloneReply& reply) -> ReturnCodeVariant {
3838
spinner.stop();
3939
cout << reply.reply_message();

src/client/cli/cmd/launch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ mp::ReturnCodeVariant cmd::Launch::request_launch(const ArgParser* parser)
468468
{
469469
if (!spinner)
470470
spinner = std::make_unique<multipass::AnimatedSpinner>(
471-
cout); // Creating just in time to work around canonical/multipass#2075
471+
cout, term->cout_is_live()); // Creating just in time to work around canonical/multipass#2075
472472

473473
if (timer)
474474
timer->resume();

src/client/cli/cmd/mount.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ mp::ReturnCodeVariant cmd::Mount::run(mp::ArgParser* parser)
7878
return parser->returnCodeFrom(ret);
7979
}
8080

81-
mp::AnimatedSpinner spinner{cout};
81+
mp::AnimatedSpinner spinner{cout, term->cout_is_live()};
8282

8383
auto on_success = [&spinner](mp::MountReply& reply) -> ReturnCodeVariant {
8484
spinner.stop();

src/client/cli/cmd/restart.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ mp::ReturnCodeVariant cmd::Restart::run(mp::ArgParser* parser)
3838
if (ret != ParseCode::Ok)
3939
return parser->returnCodeFrom(ret);
4040

41-
AnimatedSpinner spinner{cout};
41+
AnimatedSpinner spinner{cout, term->cout_is_live()};
4242
auto on_success = [this, &spinner](mp::RestartReply& reply) -> ReturnCodeVariant {
4343
spinner.stop();
4444
if (term->is_live() && update_available(reply.update_info()))

src/client/cli/cmd/restore.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mp::ReturnCodeVariant cmd::Restore::run(mp::ArgParser* parser)
3131
if (auto ret = parse_args(parser); ret != ParseCode::Ok)
3232
return parser->returnCodeFrom(ret);
3333

34-
AnimatedSpinner spinner{cout};
34+
AnimatedSpinner spinner{cout, term->cout_is_live()};
3535

3636
auto on_success = [this, &spinner](mp::RestoreReply& reply) -> ReturnCodeVariant {
3737
spinner.stop();

src/client/cli/cmd/snapshot.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mp::ReturnCodeVariant cmd::Snapshot::run(mp::ArgParser* parser)
3131
if (auto ret = parse_args(parser); ret != ParseCode::Ok)
3232
return parser->returnCodeFrom(ret);
3333

34-
AnimatedSpinner spinner{cout};
34+
AnimatedSpinner spinner{cout, term->cout_is_live()};
3535

3636
auto on_success = [this, &spinner](mp::SnapshotReply& reply) -> ReturnCodeVariant {
3737
spinner.stop();

src/client/cli/cmd/start.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ mp::ReturnCodeVariant cmd::Start::run(mp::ArgParser* parser)
5555
return parser->returnCodeFrom(ret);
5656
}
5757

58-
AnimatedSpinner spinner{cout};
58+
AnimatedSpinner spinner{cout, term->cout_is_live()};
5959

6060
auto on_success = [&spinner, this](mp::StartReply& reply) -> ReturnCodeVariant {
6161
spinner.stop();

src/client/cli/cmd/stop.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ mp::ReturnCodeVariant cmd::Stop::run(mp::ArgParser* parser)
3939

4040
auto on_success = [](mp::StopReply& reply) -> ReturnCodeVariant { return ReturnCode::Ok; };
4141

42-
AnimatedSpinner spinner{cout};
42+
AnimatedSpinner spinner{cout, term->cout_is_live()};
4343
auto on_failure = [this, &spinner](grpc::Status& status) -> ReturnCodeVariant {
4444
spinner.stop();
4545

0 commit comments

Comments
 (0)