diff --git a/CMakeLists.txt b/CMakeLists.txt index ce2bae341c..a566322711 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ set(IGN_MSGS_VER ${ignition-msgs8_VERSION_MAJOR}) #-------------------------------------- # Find ignition-common # Always use the profiler component to get the headers, regardless of status. -ign_find_package(ignition-common4 VERSION 4.4 +ign_find_package(ignition-common4 VERSION 4.5.1 COMPONENTS profiler events @@ -161,6 +161,9 @@ set(IGN_MATH_VER ${ignition-math6_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) #-------------------------------------- # Find ignition-utils diff --git a/Changelog.md b/Changelog.md index 52d7e7e82b..79ee4ec6a0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1901,7 +1901,62 @@ ## Ignition Gazebo 3.x -### Ignition Gazebo 3.X.X (20XX-XX-XX) +### Ignition Gazebo 3.13.0 (2022-06-01) + +1. Extruded 2D polyline geometries + * [Pull request #1456](https://github.com/gazebosim/gz-sim/pull/1456) + +1. Add elevator system + * [Pull request #535](https://github.com/gazebosim/gz-sim/pull/535) + +1. Add desktop entry and svg logo + * [Pull request #1411](https://github.com/gazebosim/gz-sim/pull/1411) + * [Pull request #1430](https://github.com/gazebosim/gz-sim/pull/1430) + +1. Delete unused `gazebo.hh.in` + * [Pull request #1490](https://github.com/gazebosim/gz-sim/pull/1490) + +1. Add repo specific issue templates + * [Pull request #1461](https://github.com/gazebosim/gz-sim/pull/1461) + +1. Added user command to set multiple entities' poses + * [Pull request #1394](https://github.com/gazebosim/gz-sim/pull/1394) + +1. Component inspector: refactor Pose3d C++ code into a separate class + * [Pull request #1400](https://github.com/gazebosim/gz-sim/pull/1400) + +1. Added more sensor properties to `scene/info` topic + * [Pull request #1344](https://github.com/gazebosim/gz-sim/pull/1344) + +1. `JointStatePublisher` publish parent, child and axis data + * [Pull request #1345](https://github.com/gazebosim/gz-sim/pull/1345) + +1. Removed unused variables in shapes plugin + * [Pull request #1321](https://github.com/gazebosim/gz-sim/pull/1321) + +1. Log an error if `JointPositionController` cannot find the joint. (citadel retarget) + * [Pull request #1314](https://github.com/gazebosim/gz-sim/pull/1314) + +1. `Buoyancy`: fix center of volume's reference frame + * [Pull request #1302](https://github.com/gazebosim/gz-sim/pull/1302) + +1. Remove `EachNew` calls from sensor PreUpdates + * [Pull request #1281](https://github.com/gazebosim/gz-sim/pull/1281) + +1. Prevent `GzScene3D` 💥 if another scene is already loaded + * [Pull request #1294](https://github.com/gazebosim/gz-sim/pull/1294) + +1. Add `project()` call to examples + * [Pull request #1274](https://github.com/gazebosim/gz-sim/pull/1274) + +1. Implement `/server_control::stop` + * [Pull request #1240](https://github.com/gazebosim/gz-sim/pull/1240) + +1. 👩‍🌾 Make depth camera tests more robust + * [Pull request1257](https://github.com/gazebosim/gz-sim/pull/1257) + +1. Make tests run as fast as possible + * [Pull request #1194](https://github.com/gazebosim/gz-sim/pull/1194) ### Ignition Gazebo 3.12.0 (2021-11-11) diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index a1ff8091c4..11e7ef7e00 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -117,3 +117,25 @@ set(ign_model_ruby_path "${cmd_model_script_generated_test}") configure_file( "model.yaml.in" "${CMAKE_BINARY_DIR}/test/conf/model${PROJECT_VERSION_MAJOR}.yaml" @ONLY) + +#=============================================================================== +# Bash completion + +# Tack version onto and install the bash completion script +configure_file( + "gazebo.bash_completion.sh" + "${CMAKE_CURRENT_BINARY_DIR}/gazebo${PROJECT_VERSION_MAJOR}.bash_completion.sh" @ONLY) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/gazebo${PROJECT_VERSION_MAJOR}.bash_completion.sh + DESTINATION + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/gz/gz${IGN_TOOLS_VER}.completion.d) + +configure_file( + "model.bash_completion.sh" + "${CMAKE_CURRENT_BINARY_DIR}/model${PROJECT_VERSION_MAJOR}.bash_completion.sh" @ONLY) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/model${PROJECT_VERSION_MAJOR}.bash_completion.sh + DESTINATION + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/gz/gz${IGN_TOOLS_VER}.completion.d) diff --git a/src/cmd/cmdgazebo.rb.in b/src/cmd/cmdgazebo.rb.in index dfb46fec7b..a8937648b0 100755 --- a/src/cmd/cmdgazebo.rb.in +++ b/src/cmd/cmdgazebo.rb.in @@ -73,8 +73,6 @@ COMMANDS = { 'gazebo' => " enable console logging to a console.log \n"\ " file in the specified path. \n"\ "\n"\ - " --headless-rendering Run rendering in headless mode \n"\ - "\n"\ " --record-resources Implicitly invokes --record, and records \n"\ " meshes and material files, in addition to \n"\ " states and console messages. \n"\ @@ -109,6 +107,8 @@ COMMANDS = { 'gazebo' => " --playback [arg] Use logging system to play back states. \n"\ " Argument is path to recorded states. \n"\ "\n"\ + " --headless-rendering Run rendering in headless mode \n"\ + "\n"\ " -r Run simulation on start. \n"\ "\n"\ " -s Run only the server (headless mode). This \n"\ @@ -160,7 +160,9 @@ COMMANDS = { 'gazebo' => " locate system plugins. \n\n"\ " IGN_GAZEBO_SERVER_CONFIG_PATH Path to server configuration file. \n\n"\ " IGN_GUI_PLUGIN_PATH Colon separated paths used to locate GUI \n"\ - " plugins. \n"\ + " plugins. \n\n"\ + " GZ_GUI_RESOURCE_PATH Colon separated paths used to locate GUI \n"\ + " resources such as configuration files. \n\n" } # diff --git a/src/cmd/gazebo.bash_completion.sh b/src/cmd/gazebo.bash_completion.sh new file mode 100644 index 0000000000..72ad2ac6ff --- /dev/null +++ b/src/cmd/gazebo.bash_completion.sh @@ -0,0 +1,75 @@ +#!/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_SIM_COMPLETION_LIST=" + -g + --iterations + --levels + --network-role + --network-secondaries + --record + --record-path + --record-resources + --record-topic + --log-overwrite + --log-compress + --playback + --headless-rendering + -r + -s + -v --verbose + --gui-config + --physics-engine + --render-engine + --render-engine-gui + --render-engine-server + --version + -z + -h --help + --force-version + --versions +" + +# TODO(anyone): In Garden+, replace `gazebo` in function name to align with +# subcommand, for ign-tools/etc/ign.bash_completion.sh to find this function. +function _gz_gazebo +{ + if [[ ${COMP_WORDS[COMP_CWORD]} == -* ]]; then + # Specify options (-*) word list for this subcommand + COMPREPLY=($(compgen -W "$GZ_SIM_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_sim_flags +{ + for word in $GZ_SIM_COMPLETION_LIST; do + echo "$word" + done +} diff --git a/src/cmd/model.bash_completion.sh b/src/cmd/model.bash_completion.sh new file mode 100644 index 0000000000..6ddc4f4128 --- /dev/null +++ b/src/cmd/model.bash_completion.sh @@ -0,0 +1,55 @@ +#!/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_MODEL_COMPLETION_LIST=" + --list + -m --model + -p --pose + -l --link + -j --joint + -h --help + --force-version + --versions +" + +function _gz_model +{ + if [[ ${COMP_WORDS[COMP_CWORD]} == -* ]]; then + # Specify options (-*) word list for this subcommand + COMPREPLY=($(compgen -W "$GZ_MODEL_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_model_flags +{ + for word in $GZ_MODEL_COMPLETION_LIST; do + echo "$word" + done +} diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index 5c3bcf6f7c..fbf01162bf 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include @@ -29,6 +31,8 @@ static const std::string kBinPath(PROJECT_BINARY_PATH); static const std::string kIgnCommand( std::string(BREW_RUBY) + std::string(IGN_PATH) + "/ign gazebo -s "); +static const std::string kIgnModelCommand( + std::string(BREW_RUBY) + std::string(IGN_PATH) + "/ign model "); ///////////////////////////////////////////////// std::string customExecStr(std::string _cmd) @@ -161,3 +165,65 @@ TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(ResourcePath)) EXPECT_EQ(output.find("Unable to find file plugins.sdf"), std::string::npos) << output; } + +////////////////////////////////////////////////// +/// \brief Check --help message and bash completion script for consistent flags +TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(GazeboHelpVsCompletionFlags)) +{ + // Flags in help message + std::string helpOutput = customExecStr(kIgnCommand + " gazebo --help"); + + // Call the output function in the bash completion script + std::string scriptPath = ignition::common::joinPaths( + std::string(PROJECT_SOURCE_PATH), + "src", "cmd", "gazebo.bash_completion.sh"); + + // Equivalent to: + // sh -c "bash -c \". /path/to/gazebo.bash_completion.sh; _gz_sim_flags\"" + std::string cmd = "bash -c \". " + scriptPath + "; _gz_sim_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 (const auto &flag : flags) + { + EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; + } +} + +////////////////////////////////////////////////// +/// \brief Check --help message and bash completion script for consistent flags +TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_WIN32(ModelHelpVsCompletionFlags)) +{ + // Flags in help message + std::string helpOutput = customExecStr(kIgnModelCommand + " --help"); + + // Call the output function in the bash completion script + std::string scriptPath = ignition::common::joinPaths( + std::string(PROJECT_SOURCE_PATH), + "src", "cmd", "model.bash_completion.sh"); + + // Equivalent to: + // sh -c "bash -c \". /path/to/model.bash_completion.sh; _gz_model_flags\"" + std::string cmd = "bash -c \". " + scriptPath + "; _gz_model_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 (const auto &flag : flags) + { + EXPECT_NE(std::string::npos, helpOutput.find(flag)) << helpOutput; + } +} diff --git a/test/integration/log_system.cc b/test/integration/log_system.cc index 975def19dd..233ae638fa 100644 --- a/test/integration/log_system.cc +++ b/test/integration/log_system.cc @@ -334,8 +334,7 @@ TEST_F(LogSystemTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LogDefaults)) // Test case 1: // No path specified on command line. This does not go through - // ign.cc, so ignLogDirectory() is not initialized (empty string). Recording - // should not take place. + // ign.cc, recording should take place in the `.ignition` directory { // Load SDF sdf::Root recordSdfRoot; @@ -355,8 +354,12 @@ TEST_F(LogSystemTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LogDefaults)) recordServer.Run(true, 200, false); } - // Check ignLogDirectory is empty - EXPECT_TRUE(ignLogDirectory().empty()); + // We should expect to see "auto_default.log" and "state.tlog" + EXPECT_FALSE(ignLogDirectory().empty()); + EXPECT_TRUE(common::exists( + common::joinPaths(ignLogDirectory(), "auto_default.log"))); + EXPECT_TRUE(common::exists( + common::joinPaths(ignLogDirectory(), "state.tlog"))); // Remove artifacts. Recreate new directory this->RemoveLogsDir();