Code Monkey home page Code Monkey logo

code-templates's Introduction

QCR Code Templates

QUT Centre for Robotics Open Source Primary language License

Demo of the ros_package template

This repository defines shared templates for commonly performed actions within the QUT Centre for Robotics (QCR). We've made this project public as most of the templates have a general use case, and aren't directly tied to QCR.

Templates can be used through a single script, and new templates are created by writing some basic template script in a new folder. The template 'engine' is ~250 lines of (admittedly terse) Bash.

How to use a template

Note: QCR members can access templates directly using the qcr script from our tools

Clone this Git repository:

git clone https://github.com/qcr/code_templates

And add the qcr_templates script to your path somewhere if you'd like to use from any directory. We recommend adding it to ~/bin directory as follows:

mkdir ~/bin
ln -s /path/to/code_templates/qcr_templates ~/bin/

Your new projects can be created from a template simply by making a new folder and running the script with your chosen template inside that folder. For example:

qcr_templates ros_package

This will retrieve the template, and start a prompt asking you for values for your project. In general, it's best to use snake_case for programming variable values (i.e. my_variable_value not myVariableValue as our modification function assumes snake_case).

How templates work

We use a very basic custom templating method in this project, with templates being declared by creating a new folder in this repository. Templates are defined using named variables, the user is prompted at runtime for values for these variables, and then a project is created from the template with the runtime values applied. Variable values can be used to:

  • replace in-file values in code / text
  • conditionally include blocks of code / text in files
  • generate filenames based on variables
  • conditionally create files

Template variable names are typically upper snake case (i.e. MY_VARIABLE), can have default values which will be shown in the prompt, and are evaluated using Bash. This means that any variable with no value is considered false, and all other values considered true. A current limitation is that variables with default values cannot be changed to have no value by the user at runtime.

Variables are declared in a special file called .variables.yaml at the root of each template, with their syntax described below.

In-file text replacement

Variables are replaced in text using their runtime value, with the __CAMEL and __PASCAL modifiers supported. For example, the following Python template:

class MY_VARIABLE__PASCAL:

  def __init__(self):
    self._MY_VARIABLE = None

def MY_VARIABLE__CAMEL():
  print("Hi")

when given MY_VARIABLE='obstacle_detector', would produce:

class ObstacleDetector:

  def __init__(self):
    self.obstacle_detector = None

def obstacleDetector():
  print("Hi")

Conditional in-file blocks

Variables can also be used to declare whether blocks of code should be included in the output. Blocks begin with a TEMPLATE_START variable_1 variable_2 ... line, and end with a TEMPLATE_END line. The block is included if any of variable_1 variable_2 ... have a value, and will only be excluded if all are empty. For example, the following CMake template:

catkin_package(
  TEMPLATE_START ADD_MSGS ADD_SERVICES ADD_ACTIONS
  CATKIN_DEPENDS message_runtime
  TEMPLATE_END
  )

includes a dependency on message_runtime if any of ADD_MSGS, ADD_SERVICES, ADD_ACTIONS have a value. The TEMPLATE_* lines are removed from the result, with the output being:

catkin_package(
  CATKIN_DEPENDS message_runtime
  )

The opposite relationship (include if all have a value) isn't yet supported, but should be supported in the future.

Variable file names

File names can be given variable values simply by using the variable name in the filename. For example, a file called MY_VARIABLE.cpp with a runtime value of MY_VARIABLE='object_detector' would be renamed to object_detector.cpp.

Conditional file existence

Another special file called .files.yaml marks files which should only exist under certain conditions. It's syntax is based on very basic key-value pairs (filename: variable_1 variable_2 ...), with the filed included if any of variable_1 variable_2 ... have a value. See existing templates for examples.

Creating your own templates

Creating your own templates is almost as simple as using templates. To create your own template:

  1. Clone this repository locally:

    git clone https://github.com/qcr/code_templates
    
  2. Make a new folder with the name of your template. For example, a template called my_new_template is denoted by a folder called my_new_template.

  3. Create a .variables.yaml file in your new folder. The format is the following:

    VARIABLE_NAME:
      text: "Text to be displayed to user in prompt"
      default: "Default static value"
    VARIABLE_WITH_DYNAMIC_DEFAULT:
      text: "Variable with default value determined at runtime"
      default: $(echo "This Bash code will be executed")
    OPTIONAL_VARIABLE:
      text: "Variable will be left blank if the user provides no input"
      default: ""
  4. Create the files for your template, taking advantage of whichever variable features your template requires.

  5. Test your template locally before pushing to master (as soon as it's pushed everyone can use it). Test locally by directly running the use_template script with local files instead of the remote:

    LOCAL_LOCATION=/path/to/local/clone/of/this/repo ./use_template my_new_template
    
  6. Once it works, push to the master branch. Done!

Please note: a very crude YAML parser is written in use_template to keep the dependencies of this software as low as possible. I emphasise, crude. You should not expect full YAML functionality (keep values on same line as key, don't use line breaks, no escape characters, etc.).

code-templates's People

Contributors

btalb avatar dasguna avatar jmount1992 avatar stevencolinmartin avatar tobias-fischer avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

tobias-fischer

code-templates's Issues

Bugs in python_package

In setup.py

  • URL should not be included
  • Only include license if a license file is generated
  • Review classifiers

In prompts:

  • Provide a 2 list example/default for package dependencies

Skipping all selections produces error in `ros_package`

ben@ben-meshify:~/tmp/template$ qcr_templates ros_package

--------------------------------------------------------------------------------
--------------------------- Getting latest templates ---------------------------
--------------------------------------------------------------------------------
Cloning into '/tmp/qcr_templates'...
remote: Enumerating objects: 41, done.
remote: Counting objects: 100% (41/41), done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 41 (delta 0), reused 26 (delta 0), pack-reused 0
Unpacking objects: 100% (41/41), 13.79 KiB | 882.00 KiB/s, done.
Done

--------------------------------------------------------------------------------
--------------------------- Prompting user settings ----------------------------
--------------------------------------------------------------------------------
Package name (template): 
Package version (0.1.0): 
Author's name (Ben Talbot): 
Author's email ([email protected]): 
License type (BSD): 
Add a custom C++ ROS node with name (leave blank to skip): 
Add a custom Python ROS node with name (leave blank to skip): 
Add custom ROS message definition with name (leave blank to skip): 
Add custom ROS service definition with name (leave blank to skip): 
Add custom ROS action definition with name (leave blank to skip): 

--------------------------------------------------------------------------------
------------------------ Creating project from template ------------------------
--------------------------------------------------------------------------------
sending incremental file list
./
.files.yaml
.variables.yaml
CMakeLists.txt
README.md
package.xml
setup.py
action/
action/ADD_ACTIONS.action
include/
include/PACKAGE_NAME/
include/PACKAGE_NAME/ADD_CPP_NODE.h
msg/
msg/ADD_MSGS.msg
scripts/
scripts/ADD_PY_NODE
src/
src/ADD_CPP_NODE.cpp
src/PACKAGE_NAME/
src/PACKAGE_NAME/ADD_CPP_NODE.cpp
src/PACKAGE_NAME/ADD_PY_NODE.py
src/PACKAGE_NAME/__init__.py
srv/
srv/ADD_SERVICES.srv

sent 10,369 bytes  received 344 bytes  21,426.00 bytes/sec
total size is 8,988  speedup is 0.84
removed '.variables.yaml'
removed '.files.yaml'

--------------------------------------------------------------------------------
---------------------- Applying user settings to template ----------------------
--------------------------------------------------------------------------------
Remove unnecessary files based on file requirements map:
removed './action/ADD_ACTIONS.action'
removed directory './action/'
removed './include/PACKAGE_NAME/ADD_CPP_NODE.h'
removed directory './include/PACKAGE_NAME'
removed directory './include/'
removed './msg/ADD_MSGS.msg'
removed directory './msg/'
removed './scripts/ADD_PY_NODE'
removed directory './scripts/'
removed './src/ADD_CPP_NODE.cpp'
removed './src/PACKAGE_NAME/ADD_PY_NODE.py'
removed './src/PACKAGE_NAME/ADD_CPP_NODE.cpp'
removed './src/PACKAGE_NAME/__init__.py'
removed directory './src/PACKAGE_NAME'
removed directory './src/'
removed './srv/ADD_SERVICES.srv'
removed directory './srv/'
	Done

Renaming directories and files:
	Done

Resolving in-file template chunks:
sed: can't read 113,122d: No such file or directory

Port BASH to Python

The BASH script may be better suited in a different language as the complexity of this template repository grows. As suggested in #17

Create template README.md

Would be nice to have a README.md template created so that it has a consistent format with other QCR repositories.

Make ros_package template pass catkin_lint

As an example, currently fails with:

ben@ben-precision-3630:~/blah$ catkin_lint 
catkin_lint: neither ROS_DISTRO environment variable nor --rosdistro option set
catkin_lint: unknown dependencies will be ignored
blah: CMakeLists.txt: error: unconfigured message dependency 'actionlib_msgs'
blah: CMakeLists.txt(37): error: package 'actionlib_msgs' must be in CATKIN_DEPENDS in catkin_package()
blah: CMakeLists.txt(37): error: package 'std_msgs' must be in CATKIN_DEPENDS in catkin_package()
blah: CMakeLists.txt(37): error: target 'blah_node' depends on target 'blah' which is not installed
blah: package.xml: error: missing build_depend on 'std_msgs'
blah: package.xml: error: missing build_export_depend on 'actionlib_msgs'
blah: package.xml: error: missing build_export_depend on 'std_msgs'
catkin_lint: checked 1 packages and found 7 problems
catkin_lint: option -W2 will show 3 additional notices

Adding new components after creation

Potentially out of scope but it would be good to add in other bits after creating the initial package.

Things that would be nice to add

  • a new node cpp or python
  • new msg/service or action

Enumerate templates when none/invalid provided

Replace:

ERROR: Invalid template provided (''). Please select one of:
	ros_package

with:

Valid template not provided, please select from a list below:
[1] ros_package
[2] other...
Select: 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.