May 20, 2010

Surround SCM: We've Got an API for That

Surround SCM
CLI parsing got you down? Good news, we've got an API for that. We introduced a cross-platform C API with Java and .NET wrappers in the Surround SCM 2010.0 release. All three versions of the API have the same functionality - anything you can do from the C API you can do from either Java or .NET. "What can I do with the API?", you ask. Well,  you can Add a file, Checkin, Checkout, Get, Undo Checkout, Search, Create repository, Create branch, Promote, Rebase, Manage labels, Add user, Rollback files, Share, Break share, and much more. Getting started with the API is easy. For the C API, all you need is the header file and libsscmapi. For the Java API, you'll need the JAR and libsscmapi. For the .NET API, you'll just need libsscmapi. Regardless of which language you choose, everything you'll need can be found in your "Surround SCM/API" directory (if the directory is missing, try re-running the installer, make sure you select the option to install the API). You will also find the API documentation there ("Surround SCM/API/docs"). Can't think of anything to do with the API? Here's a few ideas to get you started:
  • DIY Webclient: Both .NET and Java have rich web application frameworks.
  • Cronjob: The CLI would work fine for this, but you're a programmer and code rules!
  • Automation: Find yourself performing the same set of SCM tasks? Automate it.
  • GUI Plugin: If you didn't already know, you can add menu options to the SCM GUI. When clicked, the menu option will launch your executable. Use the API to combine a 2 or 3 step process into a single step.
Here is an example of getting a file from Surround SCM (shown in all three APIs). C API:
//////////////////////////////////////////////////////
#include <stdio.h>
#include "sscmapi.h"

int main(int argc, char *argv[])
{
   struct SSCMContext context;
   context.cbSize = sizeof(struct SSCMContext);

   SSCMResult result = sscm_connect("localhost",     // Server address
                                    4900,            // Port number
                                    "Administrator", // Username
                                    "adminIS1337",   // Password
                                    &context);
   if (SSCM_API_OK == result)
   {
      context.pBranch = "Branch";
      context.pMainline = "Mainline";

      unsigned int version = 0;
      result = sscm_get_file(&context,
                                      "Mainline/Repo1",
                                      "test.c",
                                      "/tmp",
                                      currentDate,
                                      &version,
                                      0);

      if (SSCM_API_OK == result)
         printf("Retrieved file version: %dn", version);

      sscm_disconnect(&context);
   }
   else
   {
     char *pError = sscm_get_last_error(result);
     printf("Unable to connect: %sn", pError);
     sscm_free_string(pError);
   }
   return 0;
}
//////////////////////////////////////////////////////
C# API:
//////////////////////////////////////////////////////
using System;
using System.Text;
using Seapine.SurroundSCM.API;

static class SurroundSCMAPIExample
{
   static void Main()
   {
      SSCMContext context;

      SSCMResult result = SSCMAPI.Connect("localhost",     // Server Address
                                          4900,            // Port number
                                          "Administrator", // Username
                                          "adminIS1337",   // Password
                                          out context);
      if (result.IsOk())
      {
         context.SetBranch("Branch");
         context.SetMainline("Mainline");

         UInt32 version = 0;
         result = SSCMAPI.GetFile(context,
                                  "Mainline/Repo1",
                                  "test.c",
                                  "/tmp",
                                  TimestampType.CurrentDate,
                                  ref version,
                                  false);

         if (result.IsOk())
            Console.WriteLine("Retrieved file version: " + version);

         SSCMAPI.Disconnect(context);
      }
      else
      {
         String sError = SSCMAPI.GetLastError(result);
         Console.WriteLine("Unable to connect: " + sError);
      }
   }
}
//////////////////////////////////////////////////////
Java API:
//////////////////////////////////////////////////////
import com.seapine.surroundscm.api.*;

public class SurroundSCMAPIExample {
    public static void main(String[] args)
    {
        SSCMContext context = new SSCMContext();
        SSCMResult result = SSCMAPI.connect("localhost",     // Server Address
                                            4900,            // Port number
                                            "Administrator", // Username
                                            "adminIS1337",   // Password
                                            context);

        if(SSCMAPI.SSCM_API_OK == result.result)
        {
            context.Mainline = "Mainline";
            context.Branch = "Branch";
            SSCMGetFileResult getResult;
            getResult = SSCMAPI.getFile(context,
                                        "Mainline/Repo1",
                                        "test.c",
                                        "/tmp",
                                        SSCMAPI.eTimestampType.currentDate,
                                        0,
                                        false);

            if(SSCMAPI.SSCM_API_OK == getResult.result)
                System.out.println("Retrieved file version: " + getResult.version);

            SSCMAPI.disconnect(context);
        }
        else
        {
            String sError = SSCMAPI.getLastError(result.result);
            System.out.println("Unable to connect: " + sError);
        }
    }
}
//////////////////////////////////////////////////////
Any ideas you want to share? Leave a comment!