Skip to content

Commit 67c2333

Browse files
committed
ci: Improve log output (mainly Travis).
* Bring back colors on Travis, which was disabled since #39036. Append --color=always to cargo when running in CI environment. * Removed `set -x` in the shell scripts. The `retry` function already prints which command it is running, add `-x` just add noise to the output. * Support travis_fold/travis_time. Matching pairs of these allow Travis CI to collapse the output in between. This greatly cut down the unnecessary "successful" output one need to scroll through before finding the failed statement.
1 parent 35337f7 commit 67c2333

File tree

10 files changed

+210
-15
lines changed

10 files changed

+210
-15
lines changed

.travis.yml

+7-6
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,21 @@ before_script:
152152
echo "#### Disk usage before running script:";
153153
df -h;
154154
du . | sort -nr | head -n100
155-
156-
script:
157155
- >
158156
if [ "$ALLOW_PR" = "" ] && [ "$TRAVIS_BRANCH" != "auto" ]; then
159-
echo skipping, not a full build
157+
export RUN_SCRIPT="echo 'skipping, not a full build'";
160158
else
161-
stamp src/ci/init_repo.sh . "$HOME/rustsrc" &&
159+
RUN_SCRIPT="stamp src/ci/init_repo.sh . $HOME/rustsrc";
162160
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
163-
stamp src/ci/run.sh;
161+
export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/run.sh";
164162
else
165-
stamp src/ci/docker/run.sh $IMAGE;
163+
export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/docker/run.sh $IMAGE";
166164
fi
167165
fi
168166
167+
script:
168+
- sh -x -c "$RUN_SCRIPT"
169+
169170
after_success:
170171
- >
171172
echo "#### Build successful; Disk usage after running script:";

src/bootstrap/check.rs

+9
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub fn cargo(build: &Build, stage: u32, host: &str) {
124124
/// otherwise just implements a few lint-like checks that are specific to the
125125
/// compiler itself.
126126
pub fn tidy(build: &Build, host: &str) {
127+
let _folder = build.fold_output(|| "tidy");
127128
println!("tidy check ({})", host);
128129
let compiler = Compiler::new(0, host);
129130
let mut cmd = build.tool_cmd(&compiler, "tidy");
@@ -148,6 +149,7 @@ pub fn compiletest(build: &Build,
148149
target: &str,
149150
mode: &str,
150151
suite: &str) {
152+
let _folder = build.fold_output(|| format!("test_{}", suite));
151153
println!("Check compiletest suite={} mode={} ({} -> {})",
152154
suite, mode, compiler.host, target);
153155
let mut cmd = Command::new(build.tool(&Compiler::new(0, compiler.host),
@@ -278,6 +280,8 @@ pub fn compiletest(build: &Build,
278280
cmd.arg("--android-cross-path").arg("");
279281
}
280282

283+
build.ci_env.force_coloring_in_ci(&mut cmd);
284+
281285
let _time = util::timeit();
282286
build.run(&mut cmd);
283287
}
@@ -292,6 +296,7 @@ pub fn docs(build: &Build, compiler: &Compiler) {
292296
// tests for all files that end in `*.md`
293297
let mut stack = vec![build.src.join("src/doc")];
294298
let _time = util::timeit();
299+
let _folder = build.fold_output(|| "test_docs");
295300

296301
while let Some(p) = stack.pop() {
297302
if p.is_dir() {
@@ -325,6 +330,7 @@ pub fn docs(build: &Build, compiler: &Compiler) {
325330
/// generate a markdown file from the error indexes of the code base which is
326331
/// then passed to `rustdoc --test`.
327332
pub fn error_index(build: &Build, compiler: &Compiler) {
333+
let _folder = build.fold_output(|| "test_error_index");
328334
println!("Testing error-index stage{}", compiler.stage);
329335

330336
let dir = testdir(build, compiler.host);
@@ -384,6 +390,9 @@ pub fn krate(build: &Build,
384390
}
385391
_ => panic!("can only test libraries"),
386392
};
393+
let _folder = build.fold_output(|| {
394+
format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, name)
395+
});
387396
println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage,
388397
compiler.host, target);
389398

src/bootstrap/compile.rs

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
3838
let libdir = build.sysroot_libdir(compiler, target);
3939
t!(fs::create_dir_all(&libdir));
4040

41+
let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
4142
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
4243
compiler.host, target);
4344

@@ -191,6 +192,7 @@ pub fn build_startup_objects(build: &Build, for_compiler: &Compiler, target: &st
191192
/// the build using the `compiler` targeting the `target` architecture. The
192193
/// artifacts created will also be linked into the sysroot directory.
193194
pub fn test(build: &Build, target: &str, compiler: &Compiler) {
195+
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
194196
println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
195197
compiler.host, target);
196198
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
@@ -227,6 +229,7 @@ pub fn test_link(build: &Build,
227229
/// the `compiler` targeting the `target` architecture. The artifacts
228230
/// created will also be linked into the sysroot directory.
229231
pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
232+
let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
230233
println!("Building stage{} compiler artifacts ({} -> {})",
231234
compiler.stage, compiler.host, target);
232235

@@ -456,6 +459,7 @@ pub fn maybe_clean_tools(build: &Build, stage: u32, target: &str, mode: Mode) {
456459
/// This will build the specified tool with the specified `host` compiler in
457460
/// `stage` into the normal cargo output directory.
458461
pub fn tool(build: &Build, stage: u32, target: &str, tool: &str) {
462+
let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
459463
println!("Building stage{} tool {} ({})", stage, tool, target);
460464

461465
let compiler = Compiler::new(stage, &build.config.build);

src/bootstrap/lib.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ use std::fs::{self, File};
8787
use std::io::Read;
8888
use std::path::{PathBuf, Path};
8989
use std::process::Command;
90+
use std::fmt::Display;
9091

9192
use build_helper::{run_silent, run_suppressed, output, mtime};
9293

93-
use util::{exe, libdir, add_lib_path};
94+
use util::{exe, libdir, add_lib_path, OutputFolder, CiEnv};
9495

9596
mod cc;
9697
mod channel;
@@ -179,6 +180,7 @@ pub struct Build {
179180
crates: HashMap<String, Crate>,
180181
is_sudo: bool,
181182
src_is_git: bool,
183+
ci_env: CiEnv,
182184
}
183185

184186
#[derive(Debug)]
@@ -272,6 +274,7 @@ impl Build {
272274
lldb_python_dir: None,
273275
is_sudo: is_sudo,
274276
src_is_git: src_is_git,
277+
ci_env: CiEnv::current(),
275278
}
276279
}
277280

@@ -507,6 +510,9 @@ impl Build {
507510
if self.config.vendor || self.is_sudo {
508511
cargo.arg("--frozen");
509512
}
513+
514+
self.ci_env.force_coloring_in_ci(&mut cargo);
515+
510516
return cargo
511517
}
512518

@@ -1011,6 +1017,19 @@ impl Build {
10111017
"nightly" | _ => true,
10121018
}
10131019
}
1020+
1021+
/// Fold the output of the commands after this method into a group. The fold
1022+
/// ends when the returned object is dropped. Folding can only be used in
1023+
/// the Travis CI environment.
1024+
pub fn fold_output<D, F>(&self, name: F) -> Option<OutputFolder<D>>
1025+
where D: Display, F: FnOnce() -> D
1026+
{
1027+
if self.ci_env == CiEnv::Travis {
1028+
Some(OutputFolder::new(name()))
1029+
} else {
1030+
None
1031+
}
1032+
}
10141033
}
10151034

10161035
impl<'a> Compiler<'a> {

src/bootstrap/native.rs

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub fn llvm(build: &Build, target: &str) {
6363
drop(fs::remove_dir_all(&out_dir));
6464
}
6565

66+
let _folder = build.fold_output(|| "llvm");
6667
println!("Building LLVM for {}", target);
6768
let _time = util::timeit();
6869
t!(fs::create_dir_all(&out_dir));
@@ -218,6 +219,7 @@ pub fn test_helpers(build: &Build, target: &str) {
218219
return
219220
}
220221

222+
let _folder = build.fold_output(|| "build_test_helpers");
221223
println!("Building test helpers");
222224
t!(fs::create_dir_all(&dst));
223225
let mut cfg = gcc::Config::new();

src/bootstrap/util.rs

+85-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use std::fs;
1919
use std::io;
2020
use std::path::{Path, PathBuf};
2121
use std::process::Command;
22-
use std::time::Instant;
22+
use std::time::{SystemTime, Instant};
23+
use std::fmt::Display;
2324

2425
use filetime::{self, FileTime};
2526

@@ -324,3 +325,86 @@ pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
324325
}
325326
}
326327
}
328+
329+
/// An RAII structure that indicates all output until this instance is dropped
330+
/// is part of the same group. On Travis CI, these output will be folded by
331+
/// default. This reduces visibility of unnecessary logs, allowing developers to
332+
/// quickly identify the error.
333+
pub struct OutputFolder<D: Display> {
334+
name: D,
335+
start_time: SystemTime, // we need SystemTime to get the UNIX timestamp.
336+
}
337+
338+
impl<D: Display> OutputFolder<D> {
339+
/// Creates a new output folder with the given group name.
340+
pub fn new(name: D) -> OutputFolder<D> {
341+
print!("travis_fold:start:{0}\ntravis_time:start:{0}\r\x1b[0K", name);
342+
OutputFolder {
343+
name,
344+
start_time: SystemTime::now(),
345+
}
346+
}
347+
}
348+
349+
impl<D: Display> Drop for OutputFolder<D> {
350+
fn drop(&mut self) {
351+
use std::time::*;
352+
use std::u64;
353+
354+
fn to_nanos(duration: Result<Duration, SystemTimeError>) -> u64 {
355+
match duration {
356+
Ok(d) => d.as_secs() * 1_000_000_000 + d.subsec_nanos() as u64,
357+
Err(_) => u64::MAX,
358+
}
359+
}
360+
361+
let end_time = SystemTime::now();
362+
let duration = end_time.duration_since(self.start_time);
363+
let start = self.start_time.duration_since(UNIX_EPOCH);
364+
let finish = end_time.duration_since(UNIX_EPOCH);
365+
println!(
366+
"travis_fold:end:{0}\ntravis_time:end:{0}:start={1},finish={2},duration={3}\r\x1b[0K",
367+
self.name,
368+
to_nanos(start),
369+
to_nanos(finish),
370+
to_nanos(duration)
371+
);
372+
}
373+
}
374+
375+
/// The CI environment rustbuild is running in. This mainly affects how the logs
376+
/// are printed.
377+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
378+
pub enum CiEnv {
379+
/// Not a CI environment.
380+
None,
381+
/// The Travis CI environment, for Linux (including Docker) and macOS builds.
382+
Travis,
383+
/// The AppVeyor environment, for Windows builds.
384+
AppVeyor,
385+
}
386+
387+
impl CiEnv {
388+
/// Obtains the current CI environment.
389+
pub fn current() -> CiEnv {
390+
if env::var("TRAVIS").ok().map_or(false, |e| &*e == "true") {
391+
CiEnv::Travis
392+
} else if env::var("APPVEYOR").ok().map_or(false, |e| &*e == "True") {
393+
CiEnv::AppVeyor
394+
} else {
395+
CiEnv::None
396+
}
397+
}
398+
399+
/// If in a CI environment, forces the command to run with colors.
400+
pub fn force_coloring_in_ci(self, cmd: &mut Command) {
401+
if self != CiEnv::None {
402+
// Due to use of stamp/docker, the output stream of rustbuild is not
403+
// a TTY in CI, so coloring is by-default turned off.
404+
// The explicit `TERM=xterm` environment is needed for
405+
// `--color always` to actually work. This env var was lost when
406+
// compiling through the Makefile. Very strange.
407+
cmd.env("TERM", "xterm").args(&["--color", "always"]);
408+
}
409+
}
410+
}

src/ci/docker/run.sh

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ root_dir="`dirname $src_dir`"
2121

2222
source "$ci_dir/shared.sh"
2323

24+
travis_fold start build_docker
25+
travis_time_start
26+
2427
if [ -f "$docker_dir/$image/Dockerfile" ]; then
2528
retry docker \
2629
build \
@@ -44,6 +47,9 @@ else
4447
exit 1
4548
fi
4649

50+
travis_fold end build_docker
51+
travis_time_finish
52+
4753
objdir=$root_dir/obj
4854

4955
mkdir -p $HOME/.cargo
@@ -72,6 +78,7 @@ exec docker \
7278
--env DEPLOY=$DEPLOY \
7379
--env DEPLOY_ALT=$DEPLOY_ALT \
7480
--env LOCAL_USER_ID=`id -u` \
81+
--env TRAVIS=${TRAVIS-false} \
7582
--volume "$HOME/.cargo:/cargo" \
7683
--volume "$HOME/rustsrc:$HOME/rustsrc" \
7784
--privileged \

src/ci/init_repo.sh

+19-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ set -o errexit
1313
set -o pipefail
1414
set -o nounset
1515

16-
set -o xtrace
17-
1816
ci_dir=$(cd $(dirname $0) && pwd)
1917
. "$ci_dir/shared.sh"
2018

19+
travis_fold start init_repo
20+
2121
REPO_DIR="$1"
2222
CACHE_DIR="$2"
2323

@@ -38,6 +38,7 @@ fi
3838

3939
# Wipe the cache if it's not valid, or mark it as invalid while we update it
4040
if [ ! -f "$cache_valid_file" ]; then
41+
echo "Invalid cache, wiping ($cache_valid_file missing)"
4142
rm -rf "$CACHE_DIR"
4243
mkdir "$CACHE_DIR"
4344
else
@@ -54,10 +55,14 @@ else
5455
rm -rf "$CACHE_DIR"
5556
mkdir "$CACHE_DIR"
5657
else
58+
echo "Valid cache ($cache_valid_file exists)"
5759
rm "$cache_valid_file"
5860
fi
5961
fi
6062

63+
travis_fold start update_cache
64+
travis_time_start
65+
6166
# Update the cache (a pristine copy of the rust source master)
6267
if [ ! -d "$cache_src_dir/.git" ]; then
6368
retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \
@@ -68,8 +73,15 @@ retry sh -c "cd $cache_src_dir && \
6873
git submodule deinit -f . && git submodule sync && git submodule update --init"
6974

7075
# Cache was updated without errors, mark it as valid
76+
echo "Refreshed cache (touch $cache_valid_file)"
7177
touch "$cache_valid_file"
7278

79+
travis_fold end update_cache
80+
travis_time_finish
81+
82+
travis_fold start update_submodules
83+
travis_time_start
84+
7385
# Update the submodules of the repo we're in, using the pristine repo as
7486
# a cache for any object files
7587
# No, `git submodule foreach` won't work:
@@ -84,3 +96,8 @@ for module in $modules; do
8496
retry sh -c "git submodule deinit -f $module && \
8597
git submodule update --init --reference $cache_src_dir/$module $module"
8698
done
99+
100+
travis_fold end update_submodules
101+
travis_time_finish
102+
103+
travis_fold end init_repo

0 commit comments

Comments
 (0)