July 22, 2015

Custom Client Menus: A Hidden Gem in Surround SCM

Surround SCM
Surround SCM client-side plug-ins allow you to create custom client menus to launch external processes, like a build process. This post describes the plug-in architecture options, then walks through a simple Hello World example to help you get started. [caption id="attachment_3511" align="aligncenter" width="360"] Examples of custom menu options[/caption]

Architecture

A custom menu plug-in consists of the following items:
  • An XML file, which defines the menu and launch behavior of the plug-in
  • An executable application or script, launched from the new menu item
  • An optional menu icon, presenting a custom graphic in the menu for your plug-in

Installation

The Surround SCM client looks for plug-ins in the plugins folder, under the client installation path. By default on Windows, that directory is C:\Program Files\Seapine\Surround SCM\plugins. You can view the status of existing plug-ins and add additional plug-in directories from the Tools > User Options menu, under the Plug-ins folder.

Note: You could setup a network share to centralize storage and loading of client plug-ins for all of your users.

Example: Hello World

Now let's walk through the process of creating a plug-in. You can download all the sample files here: http://downloads.seapine.com/pub/software_extras/scmsamples/CustomMenus_HelloWorld.zip

Create XML File

To get started, we need to create an xml file named HelloWorld.xml and populate it with the following: <Surround-Plugin version="1.0" author="aadams@wysicorp.com"> </Surround-Plugin>

Define Menu Item

Next, we need to define the menu item for our example. Everything but name is optional, but if you don't specify an icon, it won't have one when viewed from the client. <menu-item name="Hello World" icon="Hello Worldhelloworld.png">

Define Menu Locations

Where should we put this menu? At least one location must be specified, and multiple locations are supported. We're going to have our menu available on all three of the context menus—branch, repository, and file. (By the way, path is only required if you specify type = mainmenu.) <location type="contextbranch" /> <location type="contextrepository" /> <location type="contextfile" /> Here's our xml file so far:
<Surround-Plugin version="1.0" author="aadams@wysicorp.com">
   <menu-item name="Hello World" icon="Hello Worldhelloworld.png">
      <location type="contextbranch" />
      <location type="contextrepository" />
      <location type="contextfile" />
   </menu-item>
</Surround-Plugin>

Define Menu Visibility and Enablement

You can specify conditions for when the menu item is visible or enabled. Visibility and enabling are independent, meaning that either can be used to effectively prevent usage of the menu item. These are optional; if nothing is specified, the menu item will be visible and enabled at all times. Let's keep things simple and just require that something be selected if the menu is disabled. <enabling> <branch-selection required="true" /> <repository-selection required="true" /> <file-selection required="true" /> </enabling>

Define Menu Action

The last step in the process is to define what happens when a user clicks on the menu item. <action path="Hello WorldHello World.exe" wait-for-completion="true" timeout="60"> <return value="1"> <output location="activitylog" content="%stdoutput%" /> <output location="messagebox" content="Error performing operation. Check the activity log for more information." /> <force-refresh /> </return> </action> This one requires a more in-depth discussion.
  • <action> - We've specified that the Hello World.exe be launched when the menu item is clicked. We're going to wait up to 60 seconds for the application to respond before returning control to the Surround SCM client. Note that path can be absolute or relative; we're going to bundle our plug-in in a sub-folder, so a relative path works fine.
  • <return> - We've specified that an error message should be logged to the activity pane and a dialog prompt be sent to the user if the application returns a value of 1. Additionally, we've asked that the client refresh itself.

 Completed XML File

Here's what our final XML file looks like:
<Surround-Plugin version="1.0" author="aadams@wysicorp.com">
   <menu-item name="Hello World" icon="Hello Worldhelloworld.png">

      <location type="contextbranch" />
      <location type="contextrepository" />
      <location type="contextfile" />

      <enabling>
         <branch-selection required="true" />
         <repository-selection required="true" />
         <file-selection required="true" />
      </enabling>

      <action path="Hello WorldHello World.exe" wait-for-completion="true" timeout="60">
         <return value="1">
            <output location="activitylog" content="%stdoutput%" />
            <output location="messagebox" content="Error performing operation.Check the activity log for more information." />
            <force-refresh />
         </return>
      </action>

   </menu-item>
</Surround-Plugin>

Deploy Plug-in

Now that we have our xml file completed, deploying the plug-in is simply a matter of copying the necessary files to our Surround SCM client installation path.
  1. Browse to the plugin directory under your client installation folder.
    Ex: C:\Program Files\Seapine\Surround SCM\plugins
  2. Copy the xml file into the plugins folder.
  3. Create a folder called Hello World
  4. Copy helloworld.png into that folder.
  5. Copy Hello World.exe into that folder.
  6. Restart your Surround SCM client.
You can validate that your plug-in loaded successfully by going to Tools > User Options and clicking on the Plug-ins folder.

Set Menu Options

Now that the plug-in is deployed, all that's left to do is add it to a context menu. Go to Tools > User Options, and select one of the menu lists under the Source Tree folder. You should see the new menu item. Add it wherever you'd like, then click OK and start using it!

XML Syntax

The following tags and respective attributes are supported. Surround-Plugin: A required tag that defines and encapsulates the entire plug-in configuration for parsing by Surround SCM.
AttributeDescription
versionSpecifies the version of the XML syntax being used.
authorSpecifies the XML configuration file author. (Optional)
menu: Defines a menu to add to the Surround SCM menu bar. If items are not added to the defined menu, it is not created.
AttributeDescription
nameSpecifies the display text for the menu.
pathSpecifies the menu location of nested menus. The path can contain other menus defined in the configuration or existing Surround SCM menus. Nested menu paths are defined with a forward slash. For example, "Tools/Administration". If the path is invalid, the menu is added to the Surround SCM menu bar. (Optional)
menu-item: Defines and encapsulates an individual menu item configuration.
AttributeDescription
nameSpecifies the display text of the menu item.
tooltipSpecifies the tooltip text of the menu item. (Optional)
statustipSpecifies the status text of the menu item. (Optional)
iconSpecifies the path to the image file to use as the menu item icon. (Optional)
location: A required subtag that defines the location of a menu item. Multiple locations can be specified for the same menu item. For example, you can add menu items to the main Surround SCM menu and also add the same menu item to a context menu for users to access by right-clicking a file, repository, or branch.
AttributeDescription
typeSpecifies the location type of a menu item. Valid values include mainmenu, contextbranch, contextrepository, and contextfile.
pathSpecifies the path for the menu item. This attribute is required if the location type value is set to mainmenu. Nested menu paths are defined with a forward slash. For example, Tools/Administration.
enabling: Encapsulates the criteria for enabling the associated menu or menu item. Criteria can be set by the following subtags: branch-selection, repository-selection, file-selection, mainline-name, branch-name, repository-name, and file-name. If enabling criteria are not set, the menu or menu item is always enabled. branch-selection/repository-selection/file-selection: An optional subtag of the enabling or visibility tag that specifies if a branch, repository, or file must be selected in order to enable or show a menu item.
AttributeDescription
requiredValid values are true and false.
valueSpecifies the exact number of mainline, branch, repository, or files that must be selected to enable the menu.
greater-thanSpecifies the minimum number of mainline, branch, repository, or files that must be selected to enable the menu.
less-thanSpecifies the minimum number of mainline, branch, repository, or files that must be selected to enable the menu.
mainline-name/branch-name/repository-name/file-name: An optional subtag of the enabling or visibility tag that specifies the mainline branch, branch, repository, or file that must be selected in order to enable or show a menu item. If multiple name tags are defined, the menu item will be disabled or hidden if the selected name does not match any of the specified criteria.
AttributeDescription
valueSpecifies the mainline, branch, repository, or file name. Valid values include any string value. Wildcard characters are supported.
visibility: Encapsulates the criteria for showing the associated menu item. Criteria can be set by the following subtags: branch-selection, repository-selection, file-selection, mainline-name, branch-name, repository-name, and filename. If visibility criteria are not set, the menu item will always be visible. branch-selection/repository-selection/file-selection: See enabling (above). mainline-name/branch-name/repository-name/file-name: See enabling (above). action: A required subtag that specifies the action Surround SCM performs when users click the menu item. Only one action can be defined for each menu item. Environment variables can be used as parameters of the action's path. See Integration action environment variables (below).
AttributeDescription
pathSpecifies the path to the script and any parameters to pass in through the command line.
wait-for-completionSpecifies if Surround SCM should wait for the script to complete before continuing. True results in Surround SCM waiting for the script to complete. False launches the script without waiting. (Optional)
timeoutDefines the maximum number of seconds that Surround SCM should wait before continuing if the wait-for-completion attribute is set to true. The default value is 0, which will cause the client to wait forever. (Optional)
return: An optional subtag of the action subtag that specifies the response that Surround SCM should take when the script returns a response upon completion. The return tag is only applicable when the wait-for-completion attribute value is true. Multiple return tags can be defined for a single action, but no two return tags can be valid for the same return value.
AttributeDescription
valueSpecifies the return value from the script that is associated with this return definition. Multiple values can be defined with a comma-separated list of integers. A range can be defined using a hyphen.
greater-thanWhen setting this attribute, the return definition is used if the return value is more than the specified value.
less-thanWhen setting this attribute, the return definition is used if the return value is less than the specified value.
output: An optional subtag of the return subtag that specifies what the Surround SCM client should return to the user. Multiple output tags can be defined, but only the first defined output tag per location is used. Output for the activity log is added before displaying output in a message box.
AttributeDescription
locationSpecifies the location where the output should be returned to the user when the script completes. Valid values include messagebox and activitylog.
contentSpecifies the output value that should be returned to the user for this return value. Valid valuesinclude any string value. %stdoutput% is a special value that for this attribute that can be used to display all text that has been added to both the activity and error logs. This value can be used by itself or as part of a content string that is replaced with the output when the script runs.
force-refresh: An optional subtag of the return subtag that specifies if the Surround SCM client should refresh when the script returns the defined value.

Integration action environment variables

The following environment variables can be used as parameters for the action.
AttributeDescription
%SSCM_USER%Currently logged in user
%SSCM_CLIENTMACHINE%User’s computer name
%SSCM_MAINLINE%Selected mainline branch
%SSCM_BRANCH%Selected branch
%SSCM_BRANCHTYPE%Selected branch type
%SSCM_REPOSITORY%Selected repository
%SSCM_FILE%Selected file's name
%SSCM_FILEVERSION%Current version of the selected file
%SSCM_FILELINK%Link to the selected file in sscm:// format
%SSCM_LOCALFILE%Full path of the local file if a working directory is set
%SSCM_NUMFILES%Number of selected files
%SSCM_FILELIST%List of selected files
%SSCM_LOCALFILELIST%List of local file paths for the selected files if working directories are set