Skip to content

Commit

Permalink
Add file tester
Browse files Browse the repository at this point in the history
Should be useful for onboarding to package managers. Does non-trivial
testing on the files, but doesn't actually launch fzf.
  • Loading branch information
alpiccioni committed Dec 7, 2023
1 parent 1b8f9df commit edf73db
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 59 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
g3upt/
g3doc/
out/
obj/
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Support for Windows may be provided in future, but is not a current priority.
* [perl](https://www.perl.org/)

### Guide
`purr` includes a simple tool to help select the device serial from `adb devices`, or can read from the `$ANDROID_SERIAL` environment variable if set. Otherwise, `purr` has six command-line parameters:
`purr` includes a simple tool to help select the device serial from `adb devices`, or can read from the `$ANDROID_SERIAL` environment variable if set. Otherwise, `purr` has the following command-line parameters:

* -a: Sets custom parameters for `adb` that will be used as well as the defaults whenever an input stream is selected.
* -f: Sets custom parameters for `fzf`. Used on top of default parameters.
Expand All @@ -52,6 +52,12 @@ Support for Windows may be provided in future, but is not a current priority.
* -v: Shows the `purr` version.
* -V: Shows a composite version of `purr` and dependencies.

There are also the following special command line parameters that should only be used for testing and debugging:

* -A: Replace all calls to `adb` with the given binary. This can be used in conjunction with the bundled `adb_mock` binary to perform basic testing on purr.
* -D: Use the given directory to store all generated files instead of the standard /tmp dir.
* -X: Do not execute `fzf` when reached in the execution loop; return as if `fzf` executed correctly.

Any other command-line parameters will print the help dialog.

Note that both `-a` and `-f` are read without validation; there is no guarantee that setting either parameter will not break `purr`.
Expand Down
108 changes: 74 additions & 34 deletions makefile
Original file line number Diff line number Diff line change
@@ -1,75 +1,80 @@
OUTDIR?=$(CURDIR)/out
OBJDIR?=$(CURDIR)/obj
SRCDIR?=$(CURDIR)/src
RESDIR?=$(CURDIR)/res
TESTDIR?=$(CURDIR)/tests

PURRFILE ?=$(OUTDIR)/purr
PURRFILE_TEMP ?=$(OUTDIR)/purr_temp
PURRFILE_TEMP ?=$(OBJDIR)/purr

ADBMOCKFILE ?=$(OUTDIR)/adb_mock
ADBMOCKFILE_TEMP ?=$(OBJDIR)/adb_mock

all: purr adb_mock
FILETESTERFILE ?=$(OUTDIR)/file_tester
FILETESTERFILE_TEMP ?=$(OBJDIR)/file_tester

all: purr adb_mock file_tester

.PHONY: purr

purr:
mkdir -p $(OUTDIR)
mkdir -p $(OBJDIR)

echo "" > $(PURRFILE)
echo "" > $(PURRFILE_TEMP)

# We first need the threading functions, since we use them as part of shell
# env setup, specifically to create the cache files.
cat $(SRCDIR)/threads/thread_background.sh >> "$(PURRFILE)"
cat $(SRCDIR)/threads/thread_controller.sh >> "$(PURRFILE)"
cat $(SRCDIR)/threads/thread_interface.sh >> "$(PURRFILE)"
cat $(SRCDIR)/threads/thread_setup.sh >> "$(PURRFILE)"
cat $(SRCDIR)/threads/thread_background.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/threads/thread_controller.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/threads/thread_interface.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/threads/thread_setup.sh >> "$(PURRFILE_TEMP)"

# We can then cleanly do shell setup.
cat $(SRCDIR)/shell/shell_utils.sh >> "$(PURRFILE)"
cat $(SRCDIR)/shell/argument_parsing.sh >> "$(PURRFILE)"
cat $(SRCDIR)/shell/shell_env_check.sh >> "$(PURRFILE)"
cat $(SRCDIR)/shell/shell_env_init.sh >> "$(PURRFILE)"
cat $(SRCDIR)/shell/shell_utils.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/shell/argument_parsing.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/shell/shell_env_check.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/shell/shell_env_init.sh >> "$(PURRFILE_TEMP)"

# After we've validated the shell, we want to query for a serial number.
cat $(SRCDIR)/serial/serial_picker.sh >> "$(PURRFILE)"
cat $(SRCDIR)/serial/serial_interface.sh >> "$(PURRFILE)"
cat $(SRCDIR)/serial/serial_init.sh >> "$(PURRFILE)"
cat $(SRCDIR)/serial/serial_picker.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/serial/serial_interface.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/serial/serial_init.sh >> "$(PURRFILE_TEMP)"

# Load in all the UI utilities. We'll need these for setting up the fzf
# environment in the next step.
cat $(SRCDIR)/ui/ui_strings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/ui/ui_utils.sh >> "$(PURRFILE)"
cat $(SRCDIR)/ui/ui_strings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/ui/ui_utils.sh >> "$(PURRFILE_TEMP)"

# Finalizes the fzf environment; program is in a ready state at this point.
# We just need to load in all the UI/UX elements from bindings.
cat $(SRCDIR)/fzf_env/load_copy_program.sh >> "$(PURRFILE)"
cat $(SRCDIR)/fzf_env/fzf_default_state.sh >> "$(PURRFILE)"
cat $(SRCDIR)/fzf_env/load_copy_program.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/fzf_env/fzf_default_state.sh >> "$(PURRFILE_TEMP)"

# Load the binding libraries; this is the main block of code for purr.
# Order here isn't super important, but the stream bindings need to be
# at the very bottom after the command suites are fully initialized.
cat $(SRCDIR)/bindings/command_suites.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/copy_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/history_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/input_trim_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/misc_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/mode_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/navigation_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/preview_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/query_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/stream_bindings.sh >> "$(PURRFILE)"
cat $(SRCDIR)/bindings/command_suites.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/copy_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/history_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/input_trim_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/misc_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/mode_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/navigation_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/preview_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/query_bindings.sh >> "$(PURRFILE_TEMP)"
cat $(SRCDIR)/bindings/stream_bindings.sh >> "$(PURRFILE_TEMP)"

# Load the execution loop that actually makes things happen.
cat $(SRCDIR)/execution_loop.sh >> "$(PURRFILE)"
cat $(SRCDIR)/execution_loop.sh >> "$(PURRFILE_TEMP)"

# Remove comments/shebangs.
sed -i -e '/^[ \t]*#/d' "$(PURRFILE)"
sed -i -e '/^[ \t]*#/d' "$(PURRFILE_TEMP)"

# Add one shebang and the copyright notice.
# We need a temp file since cat can't do it in-place.
cat $(RESDIR)/header/purr_header.txt $(PURRFILE) > $(PURRFILE_TEMP)

# Undo the temp file swap
mv -f $(PURRFILE_TEMP) $(PURRFILE)
cat $(RESDIR)/header/purr_header.txt $(PURRFILE_TEMP) > $(PURRFILE)

# Grant execution permission.
chmod +rwx $(PURRFILE)
Expand All @@ -78,13 +83,48 @@ purr:

adb_mock:
mkdir -p $(OUTDIR)
mkdir -p $(OBJDIR)

echo "" > $(ADBMOCKFILE)
echo "" > $(ADBMOCKFILE_TEMP)

cat $(TESTDIR)/res/adb_log_example.sh >> "$(ADBMOCKFILE_TEMP)"
cat $(TESTDIR)/mocks/adb_mock.sh >> "$(ADBMOCKFILE_TEMP)"

cat $(TESTDIR)/mocks/adb_mock.sh >> "$(ADBMOCKFILE)"
# Remove comments/shebangs.
sed -i -e '/^[ \t]*#/d' "$(ADBMOCKFILE_TEMP)"

# Add one shebang and the copyright notice.
# We need a temp file since cat can't do it in-place.
cat $(RESDIR)/header/purr_header.txt $(ADBMOCKFILE_TEMP) > $(ADBMOCKFILE)

# Grant execution permission.
chmod +rwx $(ADBMOCKFILE)

.PHONY: file_tester

file_tester:
mkdir -p $(OUTDIR)
mkdir -p $(OBJDIR)

echo "" > $(FILETESTERFILE)
echo "" > $(FILETESTERFILE_TEMP)

cat $(TESTDIR)/res/adb_log_example.sh >> "$(FILETESTERFILE_TEMP)"
cat $(TESTDIR)/validators/file_validator.sh >> "$(FILETESTERFILE_TEMP)"

# Remove comments/shebangs.
sed -i -e '/^[ \t]*#/d' "$(FILETESTERFILE_TEMP)"

# Add one shebang and the copyright notice.
# We need a temp file since cat can't do it in-place.
cat $(RESDIR)/header/purr_header.txt $(FILETESTERFILE_TEMP) > $(FILETESTERFILE)

# Grant execution permission.
chmod +rwx $(FILETESTERFILE)

.PHONY: clean

clean:
[ -e $(OUTDIR) ] && rm -r $(OUTDIR) || true
[ -e $(OBJDIR) ] && rm -r $(OBJDIR) || true
7 changes: 5 additions & 2 deletions src/execution_loop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ while true; do

__purr_set_start_preview

# Starts and runs the actual fzf process.
if [ ! -z $cached_query ]; then
if [[ "$fzf_exec_flag" = "false" ]]; then # Don't exec fzf if in a testing session.
sleep 5
accepted=""
ret=$?
elif [ ! -z $cached_query ]; then # Starts and runs the actual fzf process.
accepted=$(FZF_DEFAULT_COMMAND="$load_input_stream" fzf $starter_preview_command $fzfp $fzf_prompt $bind_commands $start_command --query=$cached_query)
ret=$?
else
Expand Down
10 changes: 8 additions & 2 deletions src/shell/argument_parsing.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

REQUIRED_FZF_VERSION="0.40.0"

VERSION="2.0.1"
VERSION="2.0.2"

USAGE=("purr"
"\n[-q: Sets the default query]"
Expand Down Expand Up @@ -47,13 +47,19 @@ __purr_get_composite_version() {
# Parse argument flags.
instruction_flag=true
adb_cmd_loc="adb"
while getopts ':A:a:f:ivVq:' flags; do
delete_dir_flag=true
fzf_exec_flag=true
while getopts ':XA:D:a:f:ivVq:' flags; do
case $flags in
q) query_string="--query=${OPTARG}" ;;
a) custom_adb_params=${OPTARG} ;;
A) adb_cmd_loc=${OPTARG} ;;
D)
delete_dir_flag=false
dir_name=${OPTARG} ;;
f) custom_fzf_params=${OPTARG} ;;
i) instruction_flag=false ;;
X) fzf_exec_flag=false ;;
v)
echo $VERSION
exit 0
Expand Down
6 changes: 5 additions & 1 deletion src/shell/shell_env_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

dir_name=$(mktemp -d /tmp/purr.XXXXXXXXXX)
if [ -z $dir_name ]; then
dir_name=$(mktemp -d /tmp/purr.XXXXXXXXXX)
else
mkdir -p $dir_name
fi

# Run cleanup if we exit abnormally.
trap "__purr_cleanup $dir_name" INT TERM
Expand Down
2 changes: 1 addition & 1 deletion src/threads/thread_interface.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ __purr_cleanup() {
fi

# Delete all of the cached state files.
if [ -d $dir_name ]; then
if [ -d $dir_name ] && [[ $delete_dir_flag = "true" ]]; then
rm -r $dir_name &>/dev/null
fi
}
Expand Down
23 changes: 5 additions & 18 deletions tests/mocks/adb_mock.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
#!/usr/bin/env zsh

if grep -q "devices" <<< $@; then
if grep -q "devices" <<<$@; then
echo "List of devices attached"
echo "emulator-5554 device"
elif grep -q "wait-for-device" <<< $@; then
sleep 0.01;
elif grep -q "logcat" <<< $@; then
cat <<-END
--------- beginning of system
11-30 11:51:17.111 520 565 V DisplayPowerController2[0]: Brightness [0.39763778] reason changing to: 'manual', previous reason: 'manual [ dim ]'.
11-30 11:51:17.111 520 565 I DisplayPowerController2[0]: BrightnessEvent: disp=0, physDisp=local:4619827259835644672, brt=0.39763778, initBrt=0.05, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=0, thrmMax=1.0, powerFactor=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false, strategy=InvalidBrightnessStrategy
--------- beginning of main
11-30 11:51:17.159 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff101010
11-30 11:51:17.186 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff111111
11-30 11:51:17.197 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff121212
11-30 11:51:17.214 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff131313
11-30 11:51:17.231 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff141414
11-30 11:51:17.247 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff151515
11-30 11:51:17.264 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff161616
11-30 11:51:17.281 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff171717
END
elif grep -q "wait-for-device" <<<$@; then
sleep 0.01
elif grep -q "logcat" <<<$@; then
echo $mocked_adb_output
sleep 9999999
fi
31 changes: 31 additions & 0 deletions tests/res/adb_log_example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env zsh

# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

mocked_adb_output=$(cat <<-END
--------- beginning of system
11-30 11:51:17.111 520 565 V DisplayPowerController2[0]: Brightness [0.39763778] reason changing to: 'manual', previous reason: 'manual [ dim ]'.
11-30 11:51:17.111 520 565 I DisplayPowerController2[0]: BrightnessEvent: disp=0, physDisp=local:4619827259835644672, brt=0.39763778, initBrt=0.05, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=0, thrmMax=1.0, powerFactor=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false, strategy=InvalidBrightnessStrategy
--------- beginning of main
11-30 11:51:17.159 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff101010
11-30 11:51:17.186 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff111111
11-30 11:51:17.197 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff121212
11-30 11:51:17.214 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff131313
11-30 11:51:17.231 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff141414
11-30 11:51:17.247 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff151515
11-30 11:51:17.264 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff161616
11-30 11:51:17.281 397 397 I android.hardware.lights-service.example: Lights setting state for id=1 to color ff171717
END
)
Loading

0 comments on commit edf73db

Please sign in to comment.