Development and Pipeline

Development and Pipeline

Development and Pipeline

Connecting mainframe application developers to discuss efficiently creating and maintaining z/OS applications

 View Only

Customizing a menu item in IDz on VS Code (Part 1)

By Lauren Li posted 27 days ago

  

While IBM® Developer for z/OS® (IDz) on Eclipse and IDz on VS Code are robust integrated development environments (IDEs) packed with useful features for z/OS application developers, sometimes the out-of-the-box functionality doesn't quite capture the more specific tasks a developer may want to perform. When considering the move from green screen to more modern IDEs such as IDz on Eclipse and IDz on VS code, z/OS application developers may be wondering if these newer tools will still allow them to customize menu options or shortcuts to execute JCL, REXX, and other processes on z/OS just like they could with ISPF.

For IDz on Eclipse, this is where the Menu Manager feature comes to the rescue, as it allows developers to add custom menu commands to the right-click contextual pop-up menus. In this blog series, we'll explore how to achieve a similar functionality in IDz on VS Code, using VS Code's built-in task functionality to create a menu item that can connect to z/OS and run custom tasks. We'll also check out a few handy VS Code extensions that can improve the usability and capabilities of running custom tasks from the IDE.

Today, in Part 1 of the series, we'll keep things fairly introductory with a brief contextual background on Menu Manager in IDz on Eclipse, followed by a conceptual overview of VS Code menu item customization and a tutorial to introduce the essentials of creating a customized VS Code task to interact with z/OS. In Part 2, things will get a bit more exciting as we explore how to apply the fundamental skills from today's tutorial to the more practical scenario of using a customized VS Code menu item to invoke JCL validation on a local JCL file.

Let's get started!

What is Menu Manager like in IDz on Eclipse?

Menu manager is an IDz on Eclipse feature for adding new menu commands to contextual pop-up menus for projects, subprojects, data sets, files, and JES jobs. As described in the IDz on Eclipse documentation for Creating menu actions in Menu Manager, examples of the range of IDE views and resources that these commands can interact with include, but are not limited to:

  • Local and remote files in the z/OS Projects view
  • Local and remote files in editors (including the COBOL, JCL, PL/I, and z Systems LPEX editors)
  • Resources in the Remote Systems view (including data sets, partitioned data set (PDS) members, JES jobs and job spool files, and z/OS UNIX System Services files)

Among other capabilities, these custom menu commands allow developers to:

  • integrate z/OS resources such as TSO/E commands, CLISTs, REXX execs, and ISPF edit macros into the IDz on Eclipse client user interface.
  • redefine existing actions to override or supplement their function, so that when a user requests the original action, the redefined action is called instead.
  • create actions that prompt users for input.

An example of TSO commands added to the context menu in IDz on Eclipse's Remote Systems view via the Menu Manager is shown in the following screenshot from the documentation:

Menu Manager screenshot from IDz on Eclipse

At this point, you might be wondering if the functionality described above is also possible using IDz on VS Code. Particularly for the local workspace, the short answer is yes, although the implementation looks a bit different from IDz on Eclipse. The remainder of this blog post focuses on how you can customize a menu item in IDz on VS Code to interact with z/OS, and shares a basic tutorial example to help get you started.

How does menu item customization in IDz on VS Code work?

Rather than directly porting IDz on Eclipse's Menu Manager feature to IDz on VS Code, we can use VS Code's built-in capabilities and rich ecosystem of VS Code extensions to associate a custom menu item with a task, and easily integrate that task with other editor-independent remote development solutions such as Zowe, Ansible, and more.

VS Code's built-in custom task configuration capability helps initiate the process of setting up a task, which you can then use to connect to z/OS and perform tasks and execute scripts on z/OS. At a high level, the basic steps to create this customized menu command in IDz on VS Code would be:

  1. In your VS Code workspace, create a basic custom task.
  2. Create a script that connects to z/OS and runs the task command with any necessary parameters (for example, if the task is a REXX file stored in a data set member on MVS).
  3. Customize the "command" in the VS Code tasks.json file to run the shell script from step 2 with its arguments (which can be variabilized).
  4. Run the task: There are several different ways you can run the task, including from the command palette, using hotkeys, or with buttons and controls added to VS Code's user interface via VS Code extensions such as Task Explorer.

The basic tutorial in the next section covers the steps outlined above in more detail, using the simple example of uploading the currently-active file in VS Code's editor window to a PDS member on z/OS. This simple example can then be used as a building block for more practical subsequent use cases, such as invoking z/OS-side JCL validation for a local JCL file (a bit of foreshadowing for Part 2).

Basic tutorial: Creating a custom task menu item in IDz on VS Code

This basic tutorial covers the scenario of the developer running a custom task from VS Code to connect to z/OS and upload a local file to a PDS member on z/OS.

Note: This tutorial assumes you are starting the task creation process from scratch, with no prior configuration of a VS Code tasks.json file.

Prerequisites

Prerequisites for the basic tutorial include the following items:

  • The latest versions of the following applications are installed and set up on your local workstation:
    1. VS Code with the Zowe Explorer VS Code extension: This allows you to connect and interact with z/OS via VS Code's user interface, and is recommended to be installed with the IBM Z® Open Editor extension or IDz on VS Code for additional z/OS application development capabilities. You can find the full installation instructions and prerequisites list for IDz on VS Code on its installation documentation page.
    2. Zowe CLI: This allows you to connect and interact with z/OS via the command line - an important part of the tutorial!

      • Installation instructions for Zowe CLI can be found in the Install Zowe CLI section of the IDz on VS Code documentation for setting up integrations to interact with z/OS.

    3. RSE API Plug-in for Zowe CLI (RSE CLI plug-in): This is required if using Remote System Explorer (RSE) to connect to z/OS.

      • Installation instructions for the RSE CLI plug-in can be found in Install IBM RSE API Plug-in for Zowe CLI section of the IDz on VS Code documentation for setting up integrations to interact with z/OS.

  • You should be able to connect to z/OS from your local workstation via Zowe, either via a Remote System Explorer (RSE) connection (supported in the main body of this tutorial), or through a z/OSMF connection (modifications detailed in the Appendix of this blog post).

    Note: This tutorial assumes that you will be running the tasks on z/OS using your default Zowe profile for the connection to z/OS. To test your connection with this profile, you can open your Terminal in VS Code, and enter the following command to list the files and folders under your z/OS UNIX System Services home directory, replacing <user> with your z/OS RACF ID:

        
            zowe rse list uss /u/<user>
        
    

Step 1: Create a basic task in VS Code

This section of the tutorial will introduce how to create and run a basic task in VS Code.

  1. Create a basic task.

    In your VS Code workspace, create a tasks.json file from a template. There are two ways to do this, which achieve the same outcome.

    (Note: If your workspace already has a tasks.json file in the .vscode folder, you can instead just modify that existing .vscode/tasks.json to add the generic template task shown as the outcome of this step.)

    • Option A: In the top menu of VS Code, select Terminal > Configure tasks… > Create tasks.json file from template" > Others.

      • Note: You can also select Configure tasks… directly from the VS Code Terminal itself, by clicking the dropdown next to the + icon.
    • Option B: Open the VS Code command palette (Windows: Ctrl+Shift+P; Mac: Cmd+Shift+P), and type tasks into the prompt. Select Tasks: Configure Task > Create tasks.json file from template > Others.

    Both methods will create a .vscode folder that contains a generic template tasks.json file that includes the following tasks content:

                        
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
        }
    ]
                        
                    

    This basic template task is named "echo" (the "label", which VS Code will display for the task in its user interface), and executes a shell task (the "type"), which is simply the command to echo Hello into the console.

  2. Test run the basic task.

    Before we get into customizing the task, let's test that we can run this basic task first. There are a couple different ways you can run a task from VS Code. The following two methods are built into VS Code:

    • A. From the VS Code's top menu bar, select Terminal > Run Task…, then select the new task echo that appears in the dropdown of the command palette. At the subsequent prompt to Select for which kind of errors and warnings to scan the task output, select Continue without scanning the task output.

      • Note: You can also select Run task… directly from the VS Code Terminal itself, by clicking the dropdown next to the + icon.
    • B. Use Quick Open (Windows: Ctrl+P; Mac: Cmd+P), type task followed by your task name (so in this basic example, task echo), then press Enter. At the subsequent prompt, select Continue without scanning the task output.

    Note: “Scanning the task output” refers to VS Code's ability to use problem matchers to scan the task output for known warning or error messages, and report these inline in the editor window and in the Problems panel. As we are not using problem matchers for this tutorial, we can select to continue running the task without scanning the task output. To configure your task so it doesn't prompt for this, you can add the following line to your task: "problemMatcher": []. For the example echo task, it would look like the following:

                        
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
            "problemMatcher": []
        }
    ]
                        
                    

    Regardless of which method is used to invoke the task, the task will run in VS Code's Terminal panel, printing Hello into the console.

  3. (Optional) Make the task available via a keyboard shortcut and on VS Code's Explorer view.

    To make your task more easily accessible and user-friendly, you can set up additional ways of running it. The following section explores how you can do this with a keyboard shortcut and with VS Code's Explorer view.


    Keyboard shortcut

    If you are configuring a task that you will be using frequently, you can bind it to a keyboard shortcut via your keybindings.json file. You can access this file from the Keyboard Shortcuts editor, which you can get to on Windows by navigating to File > Preferences > Keyboard Shortcuts. (On Mac, navigate to Code > Settings > Keyboard Shortcuts.) With the Keyboard Shortcuts editor open, click the icon in the upper right of the VS Code window for Open Keyboard Shortcuts (JSON):

    Screenshot of VS Code button to open the keybindings.json file

    This will open your VS Code user keybindings.json file. Now you can add a keyboard shortcut entry for your new task between the file's square brackets ([ ]) as follows:

                        
    {
        "key": "cmd+shift+O",
        "command": "workbench.action.tasks.runTask",
        "args": "echo"
    }
                        
                    

    The value of the "command" field to run a task will be "workbench.action.tasks.runTask", and you can customize the value of "key" to be whichever key/combination of keys works best for you (in this example, I've picked Cmd+Shift+O). The value of "args" here should match the value of the "label" field that you gave your command when you entered it in the tasks.json file (for example, in the above tutorial, it is "echo").

    To run the task via the keyboard shortcut, press the key or combination of keys you assigned to the task in your keybindings.json file.


    VS Code Explorer view

    To make the task more easily available to run directly from VS Code's user interface, we can use a task manager VS Code extension such as Task Explorer. Upon installing the Task Explorer VS Code extension, the Task Explorer view becomes available on the left side of VS Code's Explorer view (by default in the lower-left corner). If you expand the Task Explorer, you should be able to now see your new task, echo, in the vscode subfolder under your workspace folder name.

    To run the task from the Task Explorer panel, click on the "play" triangle to the right of the task name:

    Screenshot of the Run button in the Task Explorer VS Code extension

    These configured methods of invoking the task will have the same result as running the task via VS Code's built-in methods.

    Now that we have verified the basic task works, the next steps will focus on customizing the task.

Step 2: Create a shell script that connects to z/OS and runs the task command with the necessary parameters

In this section of the tutorial, we will create a shell script that will be called by the task once we customize the task in the following step.

  1. In your VS Code workspace, create a new shell script by right-clicking an empty spot in the Explorer view and selecting New File…. Enter a filename with the .sh extension to describe the task. (For this example, I will name it scripts/upload-file-zos.sh, to add my new upload-file-zos.sh file under a folder named scripts.) The new file should automatically open in VS Code's editor pane, but if not, you can double-click on the new file in VS Code's Explorer view to open it in the editor.

  2. Customize the new shell script for the task. The following sample shell script uploads a local file to a PDS member, then lists the contents of the remote destination PDS on z/OS via VS Code's Terminal to help you confirm the successful file upload.

    Note: The following shell script is only for the purposes of demonstrating the functionality in this example. For actual implementation usage, further logic should be added for input validation and error handling.

                        
    #!/bin/sh
    #========================
    # NAME: upload-file-zos.sh
    # DESCRIPTION: Script to upload a currently-active local file in VS Code's 
    #     editor to a z/OS PDS member on MVS.
    # USAGE: upload-file-zos.sh localFile pdsName memberName
    # PARAMETERS:
    #    localFile        - The filepath to the local file to upload.
    #    pdsName     - The name of the destination PDS.
    #    memberName  - The name of the destination PDS member.
    #========================
    
    # Constants and input
    localFile=$1
    pdsName=$2
    memberName=$3
    
    echo "Local file: ${localFile}"
    echo "Remote destination PDS name: ${pdsName}"
    echo "Remote destination PDS member name: ${memberName}"
    
    # Upload the local currently-open file to PDS member
    echo "Uploading file..."
    zowe rse upload file-to-data-set "${localFile}" "${pdsName}(${memberName})"
    
    # List the contents in the remote PDS
    echo "Listing files in ${pdsName}:"
    zowe rse list all-members "${pdsName}" 
                        
                    

    Note that the above script takes three arguments, with some of them requiring user input:

    • localFile: The filepath of the local file to upload. (We will set this to the currently-open local file in VS Code in the next step.)
    • pdsName: The name of the destination PDS.
    • memberName: The name of the destination PDS member.

    Using Zowe CLI with the RSE CLI plug-in, the script uploads a local file (localFile) to the user-designated destination PDS member location (pdsName(memberName)) and lists the members of the destination PDS.

    In the following section, we will see how to invoke the shell script we created in this step and prompt the user for inputs as part of the VS Code task customization.

Step 3: Customize the task

This section of the tutorial is where we will modify the task in the tasks.json file (in the .vscode folder) to run the shell script from Step 2 with its arguments. In the following updated tasks.json file snippet, the command has been updated to invoke the upload-list-zos.sh script we created in the previous step. The value of "label" has also been updated* to better represent what the task will do: "Upload open file to z/OS":

            
"tasks": [
    {
        "label": "Upload open file to z/OS",
        "type": "shell",
        "command": "scripts/upload-list-zos.sh",
        "problemMatcher": [],
        "args": ["${file}", "${input:pdsName}", "${input:memberName}"]
    }
]
            
        

Notably, a new line for "args" has been added to the task above. This is how the task will get the arguments it needs to run its command that invokes our script. In this example, this is how we will pass in the three arguments needed to run the "upload-list-zos.sh" script.

The first argument, "${file}", is a predefined variable that represents the currently-active file open in VS Code's editor. This predefined variable is one of several that VS Code supports in its tasks.json file. You can check out the VS Code documentation for additional information on variable substitution and predefined variables.

The second and third arguments, "${input:pdsName}" and "${input:memberName}" are VS Code input variables that will prompt the user for information. Within VS Code's "${input:…}" syntax, pdsName represents the name of the PDS to upload to, while memberName represents the name of member within the PDS that the task will upload the file to. Note that the mention of these input variables in the "tasks" property is only a reference. In order to define these input variables so they can be used in the task, we will need to add an "inputs" property alongside the "tasks" property as follows:

            
"tasks": [
    {
        "label": "Upload open file to z/OS",
        "type": "shell",
        "command": "scripts/upload-file-zos.sh",
        "problemMatcher": [],
        "args": ["${file}", "${input:pdsName}", "${input:memberName}"]
    },
],
"inputs": [
    {
        "id": "pdsName",
        "type": "promptString",
        "description": "Name of destination PDS"
    },
    {
        "id": "memberName",
        "type": "promptString",
        "description": "Name of destination PDS member"
    }
]                
            
        

Each of the entries in "inputs" has three basic configuration attributes:

  • "id": This must match the input variable name you are referencing in the "tasks" property (in this example, "pdsName" or "memberName").
  • “type”: The type of input variable. In our case, "promptString" will present an input box to the user, in which they can enter a string.
  • “description”: This is the text that will show in the input box to give the user context about the input they are being prompted for.

For more information about input variables and customizing them, you can refer to VS Code's Input variables documentation.

*Note: If you assigned a keyboard shortcut to your task earlier in the tutorial and still want that keyboard shortcut to work with this customized task, you will need to update its entry in your keybindings.json file so that its value of "args" matches the task's new "label" value from the tasks.json file. (For the example in this tutorial, you would need to update the keybindings.json entry's "args" value from "echo" to "Upload open file to z/OS".)

Step 4: Run the task

As previously described in Step 1 of this tutorial, you can run your task a few different ways. With a file open and active (in-focus) in your VS Code editor window (because the task is for uploading an open file to z/OS, after all), some of the ways you can test your newly-customized task include:

  • A. Use Quick Open (Windows: Ctrl+P; Mac: Cmd+P), then start typing task followed by your task name (for example, task Upload open file to z/OS). To help prevent you from needing to type out the whole task name, VS Code will start offering matching suggestions from your available tasks as you type, which you can use the up/down arrow keys to navigate through or press Enter to select.

  • B. If you set a keyboard shortcut for your task, you can press the key or combination of keys that you assigned to the task. (If you used the same key combination as in this tutorial's example, you would press Cmd+Shift+O.)

  • C. If you set up the Task Explorer VS Code extension, in the Task Explorer panel, click on the "play" triangle to the right of the task named "Upload open file to z/OS":

    Screenshot of Run button in Task Explorer VS Code extension

If the task runs successfully, you should be prompted for a PDS name followed by a member name, and the file opened in your editor should then be uploaded to the specified PDS member on z/OS. The console log output will look similar to the following screenshot, where a local file named test.jcl was uploaded to the PDS member LAURENL.TEST.JCL(TEST):

Output of the 'Upload open file to z/OS' task

In addition to viewing the result of this upload task in the console output, you can also check the result by searching for and opening the newly-uploaded PDS member via the Zowe Explorer VS Code extension's Data Sets view:

Checking the uploaded file via the Zowe Explorer VS Code extension's Data Sets view

Conclusion

In this blog post, we have just scratched the surface of how you can create and customize menu items in IDz on VS Code to connect to z/OS and perform tasks and execute scripts on z/OS. Stay tuned for Part 2 of Customizing a menu item in IDz on VS Code, where we will take this a step further with a more practical applied use case: customizing a menu item to perform JCL validation on a local JCL file - now available at an IBM Development and Pipeline Community near you!


Resources

The following resources are listed in order of first appearance as grouped by product family.

IDz on VS Code resources

VS Code and third-party VS Code extension resources

IDz on Eclipse resources


Appendix: Connecting with z/OSMF instead of RSE

If you are connecting to z/OS with z/OSMF instead of RSE, you can test your connection with your z/OSMF profile by opening your Terminal in VS Code, and entering the following command, replacing <user> with your z/OS RACF ID:

zowe files list uss /u/<user>

To have the upload-list-zos.sh shell script in the tutorial example use a z/OSMF connection rather than RSE, you can modify the following lines:

  • Replace zowe rse upload file-to-data-set, with zowe files upload file-to-data-set
  • Replace zowe rse list all-members, with zowe files list all-members

You can find additional commands for both RSE and z/OSMF connections in the IBM Z Open Editor reference documentation for IBM RSE CLI plug-in commands.

0 comments
49 views

Permalink