Overview ======== This guide should give you a clear understanding of what Sensei is and how to configure it. The overview will explain some key concepts and guide you to create your first recipe. How does Sensei work? --------------------- Sensei is an IDE plugin that performs on the fly code analysis. This behavior is configured in what we call 'recipes'. A recipe consists of four sections. .. glossary:: Metadata This section contains the metadata of the recipe, e.g. name, description, category, etc. Most of the information in this section is used to describe a recipe rather than to configure its behavior. Search This section describes the behavior of the recipe, i.e. what code to look for. Fix This section contains all the possible quick fixes (suggestions) for a single recipe. This behavior is invoked when a user places their cursor at a piece of marked code, and clicks on the light bulb or presses the quick fix menu shortcut. Documentation To make sure your recipe informs the developers that use it, you can add a detailed description in this final section. A good description contains an example of what code the search can find, how the quick fix is applied and some references to elaborate further on the topic of the recipe. How are recipes stored? ----------------------- Recipes are stored in what we call 'cookbooks'. Technically, a cookbook is simply a directory that contains a configuration file and recipes, with optionally subdirectories to group recipes and to store descriptions. Cookbooks can be either in the form of a directory or that of a ZIP file depending on where these are loaded from. This leads directly to our second topic: recipe distribution. Cookbooks can be stored in numerous places. - Local Path - HTTP(S) server - Git repository - Inside the project .. note:: In the tutorials, recipes will always be stored inside the project. Configuring which cookbooks Sensei should load, can be done locally or remotely (if you have company administrator rights at ``_). During IntelliJ startup both of these configurations are read. Afterwards, Sensei itself will load the recipes from these locations. This implies that you can remotely configure to load local recipes. .. note:: Free authenticated Sensei users will have the "Basic Protection Cookbook" configured as a default remote cookbook named ``basic-protection-set``. Non-authenticated users will have the "Basic Protection Cookbook" configured as a default remote cookbook named ``basic-protection-set``. .. glossary:: Local settings Open your IDE and navigate to :guilabel:`Tools | Sensei | Cookbook Manager`. Remote settings As mentioned before, this requires company administration access to find and tweak these settings. If you have administrator rights, these settings can be found by logging in at the Secure Code Warrior portal and navigating to :guilabel:`Administration | Preferences | Rule Settings`. .. seealso:: For more information, see :doc:`/topics/distribution` What to search for? ------------------- To understand how the search engine works, we'll start by explaining some key concepts. .. code-block:: yaml search: # start of our recipe methodcall: # example of a target name: "equals" # example of an option The above example is a very simple recipe that you can write in Sensei. The first keyword of every recipe should be ``search``. This tells the engine that we will be searching for a specific target. In this example, we are looking for a ``methodcall``. Each target can also be configured to match only specific elements. In this case, only method calls that have the name ``equals`` will match the configured recipe. .. seealso:: The list of available targets can be found at :doc:`reference > targets `. Each option has its own way of being configured. Some of these will require you to simply specify a string or a boolean value. Others will expect another *target* configuration. For example: .. code-block:: yaml search: methodcall: name: "equals" on: # example of an option that expects a target configuration methodcall: # second configured target name: "toLowerCase" # option of our second target .. seealso:: All these options are described in the reference section for each of the available targets. To find the list of available options for the target used, visit :doc:`reference > targets > methodcall `. A quick recap of what we've learned. 1. Recipes start with the keyword ``search`` 2. Next, specify what you are looking for by choosing one of the available **targets** 3. Finally, targets can be configured using the available **options**. Some of these options expect primitives values, while others expect other target configurations. How to make suggestions? ------------------------ Suggestions can be configured in the fix tab. Any recipe has the ability to configure multiple suggestions. Each of these consist of the name that will be shown to the user and a list of actions that will be performed when invoking the quick fix. .. code-block:: yaml availableFixes: # List of all suggestions - name: "Remove statement" # Name that will be shown to the user actions: - remove: # currently only a single action will be performed .. seealso:: The list of available actions can be found at :doc:`reference > actions`. These actions will by default operate on the element that matches the target specification. In the majority of cases, you'll want to perform multiple actions that modify other parts of the file. .. code-block:: yaml availableFixes: - name: "Use instance variable" # Name that will be shown to the user actions: - rewrite: # First action that will be performed to: "this.heavyObject" - addField: # Second action that will be performed field: "Heavy heavyObject;" target: "parentClass" # Tells the action to operate on the class To recap, each recipe can have multiple suggestions. Each suggestion has a ``name`` that is shown to the user, and a list of ``actions``. These actions operate by default on the matched element, but this behavior can be changed by specifying the ``target``. Let's get practical ------------------- Now that the basic concepts have been covered, we can go through a few examples that explain certain details a bit more in-depth. We will address the following topics: 1. What element should I look for? 2. How the search influences the quick fix actions 3. Making recipes more generic by using regular expressions and logical operators. 4. Narrowing down when a recipe should trigger by scoping Continue with: :doc:`/intro/tutorial01`