diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7aa80d0b..705db4f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 - name: Compile and test id: ci - uses: ignition-tooling/action-ignition-ci@master + uses: ignition-tooling/action-ignition-ci@bionic with: codecov-token: ${{ secrets.CODECOV_TOKEN }} focal-ci: diff --git a/Changelog.md b/Changelog.md index 45be3290..766c3d8a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,12 @@ ## Ignition Launch 3.x -### Ignition Launch 3.X.X (20XX-XX-XX) +### Ignition Launch 3.1.1 (2021-01-08) + +1. All changes up to and including those in version 2.2.1. + +### Ignition Launch 3.1.0 (2020-12-10) + +1. All changes up to and including those in version 2.2.0. ### Ignition Launch 3.0.0 (2020-09-30) @@ -20,11 +26,17 @@ ## Ignition Launch 2.x +### Ignition Launch 2.2.1 (2021-01-08) + +1. Fix env parsing by placing it before executable parsing. + * [Pull request 81](https://github.com/ignitionrobotics/ign-launch/pull/81) + * [Pull request 82](https://github.com/ignitionrobotics/ign-launch/pull/82) + ### Ignition Launch 2.2.0 (2020-10-14) -* All changes up to and including those in version 1.10.0 +1. All changes up to and including those in version 1.10.0 -* Added a tutorial. +1. Added a tutorial. * [Pull request 48](https://github.com/ignitionrobotics/ign-launch/pull/48) ### Ignition Launch 2.1.0 (2020-05-21) @@ -66,6 +78,9 @@ 1. Add support for specifying topics to record * [Pull Request 54](https://github.com/ignitionrobotics/ign-launch/pull/54) +1. Fix race condition in websocket server. + * [Pull Request 68](https://github.com/ignitionrobotics/ign-launch/pull/68) + ### Ignition Launch 1.9.0 (2020-08-13) 1. Added HTTP handling support to websocket server and a metrics HTTP endpoint diff --git a/Migration.md b/Migration.md index 836a6ead..7d5de6f4 100644 --- a/Migration.md +++ b/Migration.md @@ -5,4 +5,11 @@ Deprecated code produces compile-time warnings. These warning serve as notification to users that their code should be upgraded. The next major release will remove the deprecated code. +## Ignition Launch 2.2.2 + +- Environment variable `IGN_LAUNCH_CONFIG_PATH` started to be treated as a path + list (colon-separated on Linux, semicolon-separated on Windows). Before, only + a single path could be set here, and setting a path list would break the whole + launch file lookup functionality. + ## Ignition Launch 0.X to N.M diff --git a/README.md b/README.md index 2b331d62..97303075 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Build | Status -- | -- -Test coverage | [![codecov](https://codecov.io/gh/ignitionrobotics/ign-launch/branch/master/graph/badge.svg)](https://codecov.io/gh/ignitionrobotics/ign-launch) -Ubuntu Bionic | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_launch-ci-master-bionic-amd64)](https://build.osrfoundation.org/job/ignition_launch-ci-master-bionic-amd64) -Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_launch-ci-master-homebrew-amd64)](https://build.osrfoundation.org/job/ignition_launch-ci-master-homebrew-amd64) -Windows | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_launch-ci-master-windows7-amd64)](https://build.osrfoundation.org/job/ignition_launch-ci-master-windows7-amd64) +Test coverage | [![codecov](https://codecov.io/gh/ignitionrobotics/ign-launch/branch/main/graph/badge.svg)](https://codecov.io/gh/ignitionrobotics/ign-launch) +Ubuntu Bionic | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_launch-ci-main-bionic-amd64)](https://build.osrfoundation.org/job/ignition_launch-ci-main-bionic-amd64) +Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_launch-ci-main-homebrew-amd64)](https://build.osrfoundation.org/job/ignition_launch-ci-main-homebrew-amd64) +Windows | [![Build Status](https://build.osrfoundation.org/job/ign_launch-ci-win/badge/icon)](https://build.osrfoundation.org/job/ign_launch-ci-win/) Ignition Launch, a component of [Ignition Robotics](https://ignitionrobotics.org), provides a command line interface @@ -137,7 +137,7 @@ necessary prerequisites followed by building from source. # Usage -Sample launch configuration files are in the [examples directory](https://github.com/ignitionrobotics/ign-launch/blob/master/examples/). +Sample launch configuration files are in the [examples directory](https://github.com/ignitionrobotics/ign-launch/blob/main/examples/). **Example** @@ -244,13 +244,12 @@ ign-launch # Contributing -Please see -[CONTRIBUTING.md](https://github.com/ignitionrobotics/ign-gazebo/blob/master/CONTRIBUTING.md). +Please see the [contribution guide](https://ignitionrobotics.org/docs/all/contributing). # Code of Conduct Please see -[CODE_OF_CONDUCT.md](https://github.com/ignitionrobotics/ign-gazebo/blob/master/CODE_OF_CONDUCT.md). +[CODE_OF_CONDUCT.md](https://github.com/ignitionrobotics/ign-gazebo/blob/main/CODE_OF_CONDUCT.md). # Versioning @@ -258,4 +257,4 @@ This library uses [Semantic Versioning](https://semver.org/). Additionally, this # License -This library is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). See also the [LICENSE](https://github.com/ignitionrobotics/ign-launch/blob/master/LICENSE) file. +This library is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). See also the [LICENSE](https://github.com/ignitionrobotics/ign-launch/blob/main/LICENSE) file. diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 4afc98bd..0d4693fe 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -44,7 +44,7 @@ pipelines: # # Ignition msgs (uncomment if a specific branch is needed) # - apt install -y # libprotobuf-dev protobuf-compiler libprotoc-dev - # - git clone http://github.com/ignitionrobotics/ign-msgs -b master + # - git clone http://github.com/ignitionrobotics/ign-msgs # - cd ign-msgs # - mkdir build # - cd build @@ -54,7 +54,7 @@ pipelines: # # Ignition transport (uncomment if a specific branch is needed) # - apt install -y # libzmq3-dev uuid-dev libsqlite3-dev - # - git clone http://github.com/ignitionrobotics/ign-transport -b master + # - git clone http://github.com/ignitionrobotics/ign-transport # - cd ign-transport # - mkdir build # - cd build @@ -65,7 +65,7 @@ pipelines: # - apt install -y # libxml2-utils # libtinyxml-dev - # - git clone http://github.com/osrf/sdformat -b master + # - git clone http://github.com/osrf/sdformat # - cd sdformat # - mkdir build # - cd build @@ -75,7 +75,7 @@ pipelines: # Ignition Rendering from source - apt install -y libogre-1.9-dev libogre-2.1-dev libglew-dev libfreeimage-dev freeglut3-dev libxmu-dev libxi-dev uuid-dev xvfb - - git clone https://github.com/ignitionrobotics/ign-rendering -b master + - git clone https://github.com/ignitionrobotics/ign-rendering - cd ign-rendering - mkdir build - cd build @@ -97,7 +97,7 @@ pipelines: qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtgraphicaleffects - - git clone https://github.com/ignitionrobotics/ign-gui -b master + - git clone https://github.com/ignitionrobotics/ign-gui - cd ign-gui - mkdir build - cd build @@ -111,7 +111,7 @@ pipelines: # libdart6-dev # libdart6-utils-urdf-dev # libbenchmark-dev - # - git clone https://github.com/ignitionrobotics/ign-physics -b master + # - git clone https://github.com/ignitionrobotics/ign-physics # - cd ign-physics # - mkdir build # - cd build @@ -119,7 +119,7 @@ pipelines: # - make install # - cd ../.. # Ignition Sensors from source - - git clone https://github.com/ignitionrobotics/ign-sensors -b master + - git clone https://github.com/ignitionrobotics/ign-sensors - cd ign-sensors - mkdir build - cd build @@ -127,7 +127,7 @@ pipelines: - make install - cd ../.. # Ignition Gazebo from source - - git clone https://github.com/ignitionrobotics/ign-gazebo -b master + - git clone https://github.com/ignitionrobotics/ign-gazebo - cd ign-gazebo - mkdir build - cd build diff --git a/plugins/websocket_server/WebsocketServer.hh b/plugins/websocket_server/WebsocketServer.hh index e95d2977..2a04c22c 100644 --- a/plugins/websocket_server/WebsocketServer.hh +++ b/plugins/websocket_server/WebsocketServer.hh @@ -130,7 +130,7 @@ namespace ignition /// /// `ign launch -v 4 websocket.ign` /// - /// 3. Open the [index.html](https://github.com/ignitionrobotics/ign-launch/blob/master/plugins/websocket_server/index.html) webpage. + /// 3. Open the [index.html](https://github.com/ignitionrobotics/ign-launch/blob/main/plugins/websocket_server/index.html) webpage. /// class WebsocketServer : public ignition::launch::Plugin { diff --git a/src/Manager.cc b/src/Manager.cc index 2ab11e1c..dc554ff8 100644 --- a/src/Manager.cc +++ b/src/Manager.cc @@ -521,6 +521,9 @@ bool ManagerPrivate::ParseConfig(const std::string &_config) ignerr << "Invalid config file,m issing element\n"; return false; } + // Keep the environment variables in memory. See manpage for putenv. + this->envs = this->ParseEnvs(root); + this->SetEnvs(this->envs); // Parse and create all the elements. this->ParseExecutables(root); @@ -529,10 +532,6 @@ bool ManagerPrivate::ParseConfig(const std::string &_config) if (this->master) this->ParseExecutableWrappers(root); - // Keep the environment variables in memory. See manpage for putenv. - this->envs = this->ParseEnvs(root); - this->SetEnvs(this->envs); - // Parse and create all the elements. if (this->master) { diff --git a/src/Manager_TEST.cc b/src/Manager_TEST.cc index 56883ca7..abc9ff05 100644 --- a/src/Manager_TEST.cc +++ b/src/Manager_TEST.cc @@ -17,8 +17,46 @@ #include #include +#include + +#include + +#include + #include "Manager.hh" +static constexpr char kTestScriptPath[] = "/tmp/ign-launch.sh"; + +///////////////////////////////////////////////// +bool RemoveTestScript() +{ + // Remove the file if it already exists + if (ignition::common::isFile(kTestScriptPath)) + { + if (!ignition::common::removeFile(kTestScriptPath)) + { + return false; + } + } + return true; +} + +///////////////////////////////////////////////// +bool WriteTestScript() +{ + if (!RemoveTestScript()) + return false; + + // Write a simple script and mark it executable + std::ofstream ofs(kTestScriptPath); + ofs << R"(#!/usr/bin/env bash +echo $TEST_VAR +touch $TEST_VAR +)"; + chmod(kTestScriptPath, S_IRWXU); + return true; +} + ///////////////////////////////////////////////// TEST(Ignition_TEST, RunEmptyConfig) { @@ -81,6 +119,73 @@ TEST(Ignition_TEST, RunLs) EXPECT_TRUE(mgr.RunConfig(config)); } + +///////////////////////////////////////////////// +TEST(Ignition_TEST, IGN_UTILS_TEST_DISABLED_ON_WIN32(RunEnvPre)) +{ + // Test that environment is applied regardless of order + std::string testPath = "/tmp/ign-launch-env-test-pre"; + + if (ignition::common::isFile(testPath)) + { + ASSERT_TRUE(ignition::common::removeFile(testPath)); + } + + ASSERT_TRUE(WriteTestScript()); + + std::string config = R"( + + + TEST_VAR + )" + testPath + R"( + + + /tmp/ign-launch.sh + + +)"; + + ignition::launch::Manager mgr; + + EXPECT_TRUE(mgr.RunConfig(config)); + EXPECT_TRUE(ignition::common::isFile(testPath)); + EXPECT_TRUE(ignition::common::removeFile(testPath)); + EXPECT_TRUE(RemoveTestScript()); +} + +///////////////////////////////////////////////// +TEST(Ignition_TEST, IGN_UTILS_TEST_DISABLED_ON_WIN32(RunEnvPost)) +{ + // Test that environment is applied regardless of order + std::string testPath = "/tmp/ign-launch-env-test-post"; + + if (ignition::common::isFile(testPath)) + { + ASSERT_TRUE(ignition::common::removeFile(testPath)); + } + + ASSERT_TRUE(WriteTestScript()); + + std::string config = R"( + + + /tmp/ign-launch.sh + + + TEST_VAR + )" + testPath + R"( + + +)"; + + ignition::launch::Manager mgr; + + EXPECT_TRUE(mgr.RunConfig(config)); + EXPECT_TRUE(ignition::common::isFile(testPath)); + EXPECT_TRUE(ignition::common::removeFile(testPath)); + EXPECT_TRUE(RemoveTestScript()); +} + ///////////////////////////////////////////////// int main(int argc, char **argv) { diff --git a/src/cmdlaunch.rb.in b/src/cmdlaunch.rb.in index 6d872c05..45f1b005 100755 --- a/src/cmdlaunch.rb.in +++ b/src/cmdlaunch.rb.in @@ -159,26 +159,35 @@ class Cmd end if options.key?('file') - # Check if the passed in file exists. + # Check if the passed in file exists. + path = '' if File.exists?(options['file']) path = options['file'] + end # If not, then first check the IGN_LAUNCH_CONFIG_PATH environment # variable, then the configuration path from the launch library. - else + if path.empty? configPathEnv = ENV['IGN_LAUNCH_CONFIG_PATH'] - if !configPathEnv.nil? && - File.exists?(File.join(configPathEnv, options['file'])) - path = File.join(configPathEnv, options['file']) - # get the configuration path from the launch library. - else - Importer.extern 'char *configPath()' - path = File.join(Importer.configPath().to_s, options['file']) - if !File.exists?(path) - puts "Unable to find file " + options['file'] - exit(-1) + if !configPathEnv.nil? + configPaths = configPathEnv.split(File::PATH_SEPARATOR) + for configPath in configPaths + filePath = File.join(configPath, options['file']) + if File.exists?(filePath) + path = filePath + break + end end end end + # get the configuration path from the launch library. + if path.empty? + Importer.extern 'char *configPath()' + path = File.join(Importer.configPath().to_s, options['file']) + end + if path.empty? or !File.exists?(path) + puts "Unable to find file " + options['file'] + exit(-1) + end # ERB parse the file with the variable bindings begin diff --git a/tutorials.md.in b/tutorials.md.in index 0b62683d..0247b72a 100644 --- a/tutorials.md.in +++ b/tutorials.md.in @@ -6,6 +6,8 @@ Ignition @IGN_DESIGNATION_CAP@ library and how to use the library effectively. **Tutorials** +1. \subpage basics "Ignition launch tutorial" + ## License The code associated with this documentation is licensed under an [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tutorials/tutorial.md b/tutorials/tutorial.md index 5e72eacf..42e3d0a3 100644 --- a/tutorials/tutorial.md +++ b/tutorials/tutorial.md @@ -1,4 +1,4 @@ -# Ignition launch tutorial +\page basics Ignition launch tutorial Ignition Launch is used to run and manage plugins and programs. A configuration script can be used to specify which programs and plugins to execute. Alternatively, individual programs and plugins can be run from the command line. @@ -55,3 +55,17 @@ The [worldName] command line argument is optional. If left blank, or not specifi Example to load `the shapes.sdf`: `ign launch gazebo_plugins.ign worldName:=shapes` + +## Launch file lookup + +There is a lookup process happening if the specified file is not an absolute +path. It searches for a file with the given name in paths as follows: + +1. current directory +1. all paths specified in environment variable `IGN_LAUNCH_CONFIG_PATH` +1. a hardcoded install location (usually + `/usr/share/ignition/ignition-launchN/configs/`) + +The `IGN_LAUNCH_CONFIG_PATH` environment variable can contain either a single +path or a path list (_new since 2.2.2_). Path list is a colon-separated (on +UNIX) or semicolon-separated (on Windows) list of absolute paths. \ No newline at end of file