Skip to content

Commit

Permalink
Replace most call to grep in run-make by a script that cat the input.
Browse files Browse the repository at this point in the history
Introduced a new src/etc/cat-and-grep.sh script (called in run-make as
$(CGREP)), which prints the input and do a grep simultaneously. This is
mainly used to debug spurious failures in run-make, such as the sanitizer
error in #45810, as well as real errors such as #46126.
  • Loading branch information
kennytm committed Nov 28, 2017
1 parent 3bde5e7 commit ab788a2
Show file tree
Hide file tree
Showing 47 changed files with 241 additions and 119 deletions.
89 changes: 89 additions & 0 deletions src/etc/cat-and-grep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/sh
set -eu

# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

# Performs `cat` and `grep` simultaneously for `run-make` tests in the Rust CI.
#
# This program will read lines from stdin and print them to stdout immediately.
# At the same time, it will check if the input line contains the substring or
# regex specified in the command line. If any match is found, the program will
# set the exit code to 0, otherwise 1.
#
# This is written to simplify debugging runmake tests. Since `grep` swallows all
# output, when a test involving `grep` failed, it is impossible to know the
# reason just by reading the failure log. While it is possible to `tee` the
# output into another stream, it becomes pretty annoying to do this for all test
# cases.

USAGE='
cat-and-grep.sh [-v] [-e] [-i] s1 s2 s3 ... < input.txt
Prints the stdin, and exits successfully only if all of `sN` can be found in
some lines of the input.
Options:
-v Invert match, exits successfully only if all of `sN` cannot be found
-e Regex search, search using extended Regex instead of fixed string
-i Case insensitive search.
'

GREPPER=fgrep
INVERT=0
GREPFLAGS='q'
while getopts ':vieh' OPTION; do
case "$OPTION" in
v)
INVERT=1
ERROR_MSG='should not be found'
;;
i)
GREPFLAGS="i$GREPFLAGS"
;;
e)
GREPPER=egrep
;;
h)
echo "$USAGE"
exit 2
;;
*)
break
;;
esac
done

shift $((OPTIND - 1))

LOG=$(mktemp -t cgrep.XXXXXX)
trap "rm -f $LOG" EXIT

printf "[[[ begin stdout ]]]\n\033[90m"
tee "$LOG"
echo >> "$LOG" # ensure at least 1 line of output, otherwise `grep -v` may unconditionally fail.
printf "\033[0m\n[[[ end stdout ]]]\n"

HAS_ERROR=0
for MATCH in "$@"; do
if "$GREPPER" "-$GREPFLAGS" -- "$MATCH" "$LOG"; then
if [ "$INVERT" = 1 ]; then
printf "\033[1;31mError: should not match: %s\033[0m\n" "$MATCH"
HAS_ERROR=1
fi
else
if [ "$INVERT" = 0 ]; then
printf "\033[1;31mError: cannot match: %s\033[0m\n" "$MATCH"
HAS_ERROR=1
fi
fi
done

exit "$HAS_ERROR"
24 changes: 12 additions & 12 deletions src/test/run-make/atomic-lock-free/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,36 @@ all:
ifeq ($(UNAME),Linux)
ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86)
$(RUSTC) --target=i686-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=x86_64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm)
$(RUSTC) --target=arm-unknown-linux-gnueabi atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=arm-unknown-linux-gnueabihf atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=armv7-unknown-linux-gnueabihf atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter aarch64,$(LLVM_COMPONENTS)),aarch64)
$(RUSTC) --target=aarch64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips)
$(RUSTC) --target=mips-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=mipsel-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
ifeq ($(filter powerpc,$(LLVM_COMPONENTS)),powerpc)
$(RUSTC) --target=powerpc-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=powerpc64-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=powerpc64le-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
$(RUSTC) --target=s390x-unknown-linux-gnu atomic_lock_free.rs
nm "$(TMPDIR)/libatomic_lock_free.rlib" | grep -vq __atomic_fetch_add
nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add
endif
endif
46 changes: 46 additions & 0 deletions src/test/run-make/cat-and-grep-sanity-check/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
-include ../tools.mk

all:
echo a | $(CGREP) a
! echo b | $(CGREP) a
echo xyz | $(CGREP) x y z
! echo abc | $(CGREP) b c d
printf "x\ny\nz" | $(CGREP) x y z

echo AbCd | $(CGREP) -i a b C D
! echo AbCd | $(CGREP) a b C D

true | $(CGREP) -v nothing
! echo nothing | $(CGREP) -v nothing
! echo xyz | $(CGREP) -v w x y
! echo xyz | $(CGREP) -v x y z
echo xyz | $(CGREP) -v a b c

! echo 'foo bar baz' | $(CGREP) 'foo baz'
echo 'foo bar baz' | $(CGREP) foo baz
echo 'x a `b` c y z' | $(CGREP) 'a `b` c'

echo baaac | $(CGREP) -e 'ba*c'
echo bc | $(CGREP) -e 'ba*c'
! echo aaac | $(CGREP) -e 'ba*c'

echo aaa | $(CGREP) -e 'a+'
! echo bbb | $(CGREP) -e 'a+'

echo abc | $(CGREP) -e 'a|e|i|o|u'
! echo fgh | $(CGREP) -e 'a|e|i|o|u'
echo abc | $(CGREP) -e '[aeiou]'
! echo fgh | $(CGREP) -e '[aeiou]'
! echo abc | $(CGREP) -e '[^aeiou]{3}'
echo fgh | $(CGREP) -e '[^aeiou]{3}'
echo ab cd ef gh | $(CGREP) -e '\bcd\b'
! echo abcdefgh | $(CGREP) -e '\bcd\b'
echo xyz | $(CGREP) -e '...'
! echo xy | $(CGREP) -e '...'
! echo xyz | $(CGREP) -e '\.\.\.'
echo ... | $(CGREP) -e '\.\.\.'

echo foo bar baz | $(CGREP) -e 'foo.*baz'
! echo foo bar baz | $(CGREP) -ve 'foo.*baz'
! echo foo bar baz | $(CGREP) -e 'baz.*foo'
echo foo bar baz | $(CGREP) -ve 'baz.*foo'
6 changes: 1 addition & 5 deletions src/test/run-make/cdylib-fewer-symbols/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,5 @@ all:
else
all:
$(RUSTC) foo.rs
nm -g "$(call DYLIB,foo)"
nm -g "$(call DYLIB,foo)" | grep -vq __rdl_
nm -g "$(call DYLIB,foo)" | grep -vq __rde_
nm -g "$(call DYLIB,foo)" | grep -vq __rg_
nm -g "$(call DYLIB,foo)" | grep -vq __rust_
nm -g "$(call DYLIB,foo)" | $(CGREP) -v __rdl_ __rde_ __rg_ __rust_
endif
34 changes: 16 additions & 18 deletions src/test/run-make/codegen-options-parsing/Makefile
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
-include ../tools.mk

LOG = $(TMPDIR)/log.txt

all:
#Option taking a number
$(RUSTC) -C codegen-units dummy.rs 2>&1 | tee $(LOG)
grep 'codegen option `codegen-units` requires a number' $(LOG)
$(RUSTC) -C codegen-units= dummy.rs 2>&1 | tee $(LOG)
grep 'incorrect value `` for codegen option `codegen-units` - a number was expected' $(LOG)
$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | tee $(LOG)
grep 'incorrect value `foo` for codegen option `codegen-units` - a number was expected' $(LOG)
$(RUSTC) -C codegen-units dummy.rs 2>&1 | \
$(CGREP) 'codegen option `codegen-units` requires a number'
$(RUSTC) -C codegen-units= dummy.rs 2>&1 | \
$(CGREP) 'incorrect value `` for codegen option `codegen-units` - a number was expected'
$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | \
$(CGREP) 'incorrect value `foo` for codegen option `codegen-units` - a number was expected'
$(RUSTC) -C codegen-units=1 dummy.rs
#Option taking a string
$(RUSTC) -C extra-filename dummy.rs 2>&1 | tee $(LOG)
grep 'codegen option `extra-filename` requires a string' $(LOG)
$(RUSTC) -C extra-filename dummy.rs 2>&1 | \
$(CGREP) 'codegen option `extra-filename` requires a string'
$(RUSTC) -C extra-filename= dummy.rs 2>&1
$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
#Option taking no argument
$(RUSTC) -C lto= dummy.rs 2>&1 | tee $(LOG)
grep 'codegen option `lto` takes no value' $(LOG)
$(RUSTC) -C lto=1 dummy.rs 2>&1 | tee $(LOG)
grep 'codegen option `lto` takes no value' $(LOG)
$(RUSTC) -C lto=foo dummy.rs 2>&1 | tee $(LOG)
grep 'codegen option `lto` takes no value' $(LOG)
$(RUSTC) -C lto= dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` takes no value'
$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` takes no value'
$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
$(CGREP) 'codegen option `lto` takes no value'
$(RUSTC) -C lto dummy.rs

# Should not link dead code...
$(RUSTC) -Z print-link-args dummy.rs 2>&1 | \
grep -e '--gc-sections' -e '-z[^ ]* [^ ]*\<ignore\>' -e '-dead_strip' -e '/OPT:REF'
$(CGREP) -e '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'
# ... unless you specifically ask to keep it
$(RUSTC) -Z print-link-args -C link-dead-code dummy.rs 2>&1 | \
(! grep -e '--gc-sections' -e '-z[^ ]* [^ ]*\<ignore\>' -e '-dead_strip' -e '/OPT:REF')
$(CGREP) -ve '--gc-sections|-z[^ ]* [^ ]*<ignore>|-dead_strip|/OPT:REF'
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

all:
$(RUSTC) foo.rs --crate-type staticlib
$(RUSTC) bar.rs 2>&1 | grep "found staticlib"
$(RUSTC) bar.rs 2>&1 | $(CGREP) "found staticlib"
4 changes: 2 additions & 2 deletions src/test/run-make/error-writing-dependencies/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
all:
# Let's get a nice error message
$(BARE_RUSTC) foo.rs --emit dep-info --out-dir foo/bar/baz 2>&1 | \
grep "error writing dependencies"
$(CGREP) "error writing dependencies"
# Make sure the filename shows up
$(BARE_RUSTC) foo.rs --emit dep-info --out-dir foo/bar/baz 2>&1 | grep "baz"
$(BARE_RUSTC) foo.rs --emit dep-info --out-dir foo/bar/baz 2>&1 | $(CGREP) "baz"
2 changes: 1 addition & 1 deletion src/test/run-make/hir-tree/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
all:
$(RUSTC) -o $(TMPDIR)/input.hir -Z unstable-options \
--unpretty=hir-tree input.rs
grep '"Hello, Rustaceans!\\n"' $(TMPDIR)/input.hir
$(CGREP) '"Hello, Rustaceans!\n"' < $(TMPDIR)/input.hir
3 changes: 1 addition & 2 deletions src/test/run-make/include_bytes_deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ ifneq ($(shell uname),FreeBSD)
ifndef IS_WINDOWS
all:
$(RUSTC) --emit dep-info main.rs
grep "input.txt" $(TMPDIR)/main.d
grep "input.bin" $(TMPDIR)/main.d
$(CGREP) "input.txt" "input.bin" < $(TMPDIR)/main.d
else
all:

Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make/inline-always-many-cgu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

all:
$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2
if grep -w call $(TMPDIR)/*.ll; then \
if cat $(TMPDIR)/*.ll | $(CGREP) -e '\bcall\b'; then \
echo "found call instruction when one wasn't expected"; \
exit 1; \
fi
2 changes: 1 addition & 1 deletion src/test/run-make/invalid-library/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
all:
touch $(TMPDIR)/rust.metadata.bin
$(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
$(RUSTC) foo.rs 2>&1 | grep "can't find crate for"
$(RUSTC) foo.rs 2>&1 | $(CGREP) "can't find crate for"
2 changes: 1 addition & 1 deletion src/test/run-make/invalid-staticlib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

all:
touch $(TMPDIR)/libfoo.a
echo | $(RUSTC) - --crate-type=rlib -lstatic=foo 2>&1 | grep "failed to add native library"
echo | $(RUSTC) - --crate-type=rlib -lstatic=foo 2>&1 | $(CGREP) "failed to add native library"
2 changes: 1 addition & 1 deletion src/test/run-make/issue-14698/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-include ../tools.mk

all:
TMP=fake TMPDIR=fake $(RUSTC) foo.rs 2>&1 | grep "couldn't create a temp dir:"
TMP=fake TMPDIR=fake $(RUSTC) foo.rs 2>&1 | $(CGREP) "couldn't create a temp dir:"
2 changes: 1 addition & 1 deletion src/test/run-make/issue-22131/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ all: foo.rs
$(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
$(RUSTDOC) --test --cfg 'feature="bar"' \
-L $(TMPDIR) foo.rs |\
grep -q 'foo.rs - foo (line 11) ... ok'
$(CGREP) 'foo.rs - foo (line 11) ... ok'
3 changes: 1 addition & 2 deletions src/test/run-make/issue-26092/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
-include ../tools.mk

all:
$(RUSTC) -o "" blank.rs 2>&1 | \
grep -i 'No such file or directory'
$(RUSTC) -o "" blank.rs 2>&1 | $(CGREP) -i 'No such file or directory'
4 changes: 2 additions & 2 deletions src/test/run-make/issue-33329/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-include ../tools.mk

all:
$(RUSTC) --target x86_64_unknown-linux-musl main.rs 2>&1 | \
grep "error: Error loading target specification: Could not find specification for target"
$(RUSTC) --target x86_64_unknown-linux-musl main.rs 2>&1 | $(CGREP) \
"error: Error loading target specification: Could not find specification for target"
2 changes: 1 addition & 1 deletion src/test/run-make/issue-35164/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-include ../tools.mk

all:
$(RUSTC) main.rs --error-format json 2>&1 | grep -q '"byte_start":490.*"byte_end":496'
$(RUSTC) main.rs --error-format json 2>&1 | $(CGREP) -e '"byte_start":490\b' '"byte_end":496\b'
10 changes: 6 additions & 4 deletions src/test/run-make/issue-40535/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
-include ../tools.mk

# The ICE occurred in the following situation:
# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`)
# * `bar` declares and depends on `extern crate baz`
# * All crates built in metadata-only mode (`cargo check`)
all:
# cc https://github.com/rust-lang/rust/issues/40623
$(RUSTC) baz.rs --emit=metadata --out-dir=$(TMPDIR)
$(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta --out-dir=$(TMPDIR)
$(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta --out-dir=$(TMPDIR) 2>&1 | \
grep -vq "unexpectedly panicked"
$(RUSTC) baz.rs --emit=metadata
$(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta
$(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta 2>&1 | \
$(CGREP) -v "unexpectedly panicked"
# ^ Succeeds if it doesn't find the ICE message
2 changes: 1 addition & 1 deletion src/test/run-make/link-arg/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
RUSTC_FLAGS = -C link-arg="-lfoo" -C link-arg="-lbar" -Z print-link-args

all:
$(RUSTC) $(RUSTC_FLAGS) empty.rs | grep lfoo | grep lbar
$(RUSTC) $(RUSTC_FLAGS) empty.rs | $(CGREP) lfoo lbar
2 changes: 1 addition & 1 deletion src/test/run-make/link-cfg/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

all: $(call DYLIB,return1) $(call DYLIB,return2) $(call NATIVE_STATICLIB,return3)
ls $(TMPDIR)
$(RUSTC) --print cfg --target x86_64-unknown-linux-musl | grep crt-static
$(RUSTC) --print cfg --target x86_64-unknown-linux-musl | $(CGREP) crt-static

$(RUSTC) no-deps.rs --cfg foo
$(call RUN,no-deps)
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make/linker-output-non-utf8/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ all:
$(RUSTC) library.rs
mkdir $(bad_dir)
mv $(TMPDIR)/liblibrary.a $(bad_dir)
LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | grep this_symbol_not_defined
LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined

endif
11 changes: 7 additions & 4 deletions src/test/run-make/many-crates-but-no-match/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ all:
mv $(TMPDIR)/$(call RLIB_GLOB,crateA) $(A3)
# Ensure crateC fails to compile since A1 is "missing" and A2/A3 hashes do not match
$(RUSTC) -L $(A2) -L $(A3) crateC.rs >$(LOG) 2>&1 || true
grep "found possibly newer version of crate \`crateA\` which \`crateB\` depends on" $(LOG)
grep "note: perhaps that crate needs to be recompiled?" $(LOG)
grep "crate \`crateA\`:" $(LOG) # this will match two entries
grep "crate \`crateB\`:" $(LOG)
$(CGREP) \
'found possibly newer version of crate `crateA` which `crateB` depends on' \
'note: perhaps that crate needs to be recompiled?' \
'crate `crateA`:' \
'crate `crateB`:' \
< $(LOG)
# the 'crate `crateA`' will match two entries.
2 changes: 1 addition & 1 deletion src/test/run-make/mismatching-target-triples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
all:
$(RUSTC) foo.rs --target=i686-unknown-linux-gnu
$(RUSTC) bar.rs --target=x86_64-unknown-linux-gnu 2>&1 \
| grep "couldn't find crate .foo. with expected target triple x86_64-unknown-linux-gnu"
| $(CGREP) 'couldn'"'"'t find crate `foo` with expected target triple x86_64-unknown-linux-gnu'
Loading

0 comments on commit ab788a2

Please sign in to comment.