From abfade611aaf9f1bf05f6385c6b6cf6c2666ca19 Mon Sep 17 00:00:00 2001 From: Mabel Zhang Date: Tue, 7 Jun 2022 04:04:39 -0400 Subject: [PATCH 1/5] add bash completion Signed-off-by: Mabel Zhang --- CMakeLists.txt | 1 + src/CMakeLists.txt | 13 +++++++++ src/ign_TEST.cc | 32 +++++++++++++++++++++ src/launch.bash_completion.sh | 53 +++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 src/launch.bash_completion.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index bdf38ce3..c62f4451 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ set(IGN_PLUGIN_MAJOR_VER ${ignition-plugin1_VERSION_MAJOR}) ign_find_package(ignition-tools REQUIRED PKGCONFIG "ignition-tools") +set(IGN_TOOLS_VER 1) #-------------------------------------- # Find ignition-transport diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d4fa818e..1b061248 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,3 +94,16 @@ set(ign_library_path "${CMAKE_BINARY_DIR}/test/lib/ruby/ignition/cmdlaunch${PROJ configure_file( "launch.yaml.in" "${CMAKE_BINARY_DIR}/test/conf/launch${PROJECT_VERSION_MAJOR}.yaml" @ONLY) + +#=============================================================================== +# Bash completion + +# Tack version onto and install the bash completion script +configure_file( + "launch.bash_completion.sh" + "${CMAKE_CURRENT_BINARY_DIR}/launch${PROJECT_VERSION_MAJOR}.bash_completion.sh" @ONLY) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/launch${PROJECT_VERSION_MAJOR}.bash_completion.sh + DESTINATION + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/gz/gz${IGN_TOOLS_VER}.completion.d) diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index e2d13c61..68170135 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -21,6 +21,7 @@ #include +#include #include "ignition/launch/test_config.hh" // NOLINT(build/include) ///////////////////////////////////////////////// @@ -72,3 +73,34 @@ TEST(CmdLine, EchoSelf) std::string output = customExecStr(cmd); EXPECT_EQ(filePath, output) << output; } + +////////////////////////////////////////////////// +/// \brief Check --help message and bash completion script for consistent flags +TEST(CmdLine, HelpVsCompletionFlags) +{ + // Flags in help message + std::string helpOutput = customExecStr("ign launch --help"); + + // Call the output function in the bash completion script + std::string scriptPath = ignition::common::joinPaths( + std::string(PROJECT_SOURCE_PATH), + "src", "launch.bash_completion.sh"); + + // Equivalent to: + // sh -c "bash -c \". /path/to/launch.bash_completion.sh; _gz_launch_flags\"" + std::string cmd = "bash -c \". " + scriptPath + "; _gz_launch_flags\""; + std::string scriptOutput = customExecStr(cmd); + + // Tokenize script output + std::istringstream iss(scriptOutput); + std::vector flags((std::istream_iterator(iss)), + std::istream_iterator()); + + EXPECT_GT(flags.size(), 0u); + + // Match each flag in script output with help message + for (std::string flag : flags) + { + EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; + } +} diff --git a/src/launch.bash_completion.sh b/src/launch.bash_completion.sh new file mode 100644 index 00000000..8cfed743 --- /dev/null +++ b/src/launch.bash_completion.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2022 Open Source Robotics Foundation +# +# 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 +# +# http://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. +# + +# bash tab-completion + +# This is a per-library function definition, used in conjunction with the +# top-level entry point in ign-tools. + +GZ_LAUNCH_COMPLETION_LIST=" + -v --verbose + -h --help + --force-version + --versions +" + +function _gz_launch +{ + if [[ ${COMP_WORDS[COMP_CWORD]} == -* ]]; then + # Specify options (-*) word list for this subcommand + # NOTE: In Fortress+, add --headless-rendering. + # Update ../ign_TEST.cc accordingly. + COMPREPLY=($(compgen -W "$GZ_LAUNCH_COMPLETION_LIST" \ + -- "${COMP_WORDS[COMP_CWORD]}" )) + return + else + # Just use bash default auto-complete, because we never have two + # subcommands in the same line. If that is ever needed, change here to + # detect subsequent subcommands + COMPREPLY=($(compgen -o default -- "${COMP_WORDS[COMP_CWORD]}")) + return + fi +} + +function _gz_launch_flags +{ + for word in $GZ_LAUNCH_COMPLETION_LIST; do + echo "$word" + done +} From 9a6ad0785f2a61b538d64f6d6577813881c9a45c Mon Sep 17 00:00:00 2001 From: Mabel Zhang Date: Tue, 7 Jun 2022 04:06:47 -0400 Subject: [PATCH 2/5] copy paste error Signed-off-by: Mabel Zhang --- src/launch.bash_completion.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/launch.bash_completion.sh b/src/launch.bash_completion.sh index 8cfed743..0a6e4843 100644 --- a/src/launch.bash_completion.sh +++ b/src/launch.bash_completion.sh @@ -31,8 +31,6 @@ function _gz_launch { if [[ ${COMP_WORDS[COMP_CWORD]} == -* ]]; then # Specify options (-*) word list for this subcommand - # NOTE: In Fortress+, add --headless-rendering. - # Update ../ign_TEST.cc accordingly. COMPREPLY=($(compgen -W "$GZ_LAUNCH_COMPLETION_LIST" \ -- "${COMP_WORDS[COMP_CWORD]}" )) return From dd6e112b673f009bf8ea830483acf5966b37b8ef Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Tue, 14 Jun 2022 17:21:17 -0700 Subject: [PATCH 3/5] Note and const ref Signed-off-by: Louise Poubel --- CMakeLists.txt | 2 ++ src/ign_TEST.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c62f4451..796f9541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,8 @@ set(IGN_PLUGIN_MAJOR_VER ${ignition-plugin1_VERSION_MAJOR}) ign_find_package(ignition-tools REQUIRED PKGCONFIG "ignition-tools") +# Note that CLI files are installed regardless of whether the dependency is +# available during build time set(IGN_TOOLS_VER 1) #-------------------------------------- diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index 68170135..3728eda7 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -99,7 +99,7 @@ TEST(CmdLine, HelpVsCompletionFlags) EXPECT_GT(flags.size(), 0u); // Match each flag in script output with help message - for (std::string flag : flags) + for (const auto &flag : flags) { EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; } From 8b0bedd2033ed82f2a177c2dd68727e66c48849b Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Tue, 14 Jun 2022 17:34:12 -0700 Subject: [PATCH 4/5] Fix tests Signed-off-by: Louise Poubel --- CMakeLists.txt | 1 + src/CMakeLists.txt | 15 +++++++++++++++ src/ign_TEST.cc | 7 +++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 796f9541..ddaea83d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ ign_find_package(ignition-tools PKGCONFIG "ignition-tools") # Note that CLI files are installed regardless of whether the dependency is # available during build time +find_program(HAVE_IGN_TOOLS ign) set(IGN_TOOLS_VER 1) #-------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b061248..a168daf5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,21 @@ ign_build_tests(TYPE UNIT SOURCES ${gtest_sources} ignition-common${IGN_COMMON_MAJOR_VER}::ignition-common${IGN_COMMON_MAJOR_VER} ) +if(TARGET UNIT_ign_TEST) + # Running `ign launch` on macOS has problems when run with /usr/bin/ruby + # due to System Integrity Protection (SIP). Try to find ruby from + # homebrew as a workaround. + if (APPLE) + find_program(BREW_RUBY ruby HINTS /usr/local/opt/ruby/bin) + endif() + + target_compile_definitions(UNIT_ign_TEST PRIVATE + "BREW_RUBY=\"${BREW_RUBY} \"") + + target_compile_definitions(UNIT_ign_TEST PRIVATE + "IGN_PATH=\"${HAVE_IGN_TOOLS}\"") +endif() + # Generate a the ruby script. # Note that the major version of the library is included in the name. # Ex: cmdlaunch0.rb diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index 3728eda7..ff82e1bf 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -24,6 +24,10 @@ #include #include "ignition/launch/test_config.hh" // NOLINT(build/include) +static const std::string kIgnCommand( + std::string("IGN_CONFIG_PATH=") + IGN_CONFIG_PATH + " " + + std::string(BREW_RUBY) + std::string(IGN_PATH) + " launch "); + ///////////////////////////////////////////////// std::string customExecStr(std::string _cmd) { @@ -49,8 +53,7 @@ std::string customExecStr(std::string _cmd) ///////////////////////////////////////////////// TEST(CmdLine, Ls) { - std::string cmd = std::string("IGN_CONFIG_PATH=") + IGN_CONFIG_PATH + - " ign launch " + + std::string cmd = kIgnCommand + std::string(PROJECT_SOURCE_PATH) + "/test/config/ls.ign"; std::cout << "Running command [" << cmd << "]" << std::endl; From 2937d5db88ee759b27671f6d769c45c63f1159b1 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Tue, 14 Jun 2022 17:35:31 -0700 Subject: [PATCH 5/5] more kIgnCommand Signed-off-by: Louise Poubel --- src/ign_TEST.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index ff82e1bf..a9af15e9 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -70,8 +70,7 @@ TEST(CmdLine, EchoSelf) std::string filePath = std::string(PROJECT_SOURCE_PATH) + "/test/config/echo.ign"; - std::string cmd = std::string("IGN_CONFIG_PATH=") + IGN_CONFIG_PATH + - " ign launch " + filePath; + std::string cmd = kIgnCommand + filePath; std::string output = customExecStr(cmd); EXPECT_EQ(filePath, output) << output; @@ -82,7 +81,7 @@ TEST(CmdLine, EchoSelf) TEST(CmdLine, HelpVsCompletionFlags) { // Flags in help message - std::string helpOutput = customExecStr("ign launch --help"); + std::string helpOutput = customExecStr(kIgnCommand + "--help"); // Call the output function in the bash completion script std::string scriptPath = ignition::common::joinPaths(