Using ProjectBuilder

From ControlTier

Jump to: navigation, search

Contents

Overview

Watch a short screencast on how to get started!

ProjectBuilder is a Builder used to manage Project Content for users that prefer to maintain the project as a set of text-based source files maintained in an SCM repository. You can use ProjectBuilder to define types and build module libraries, load resource data, even generate a Forrest documentation site.

For type and module development, ProjectBuilder supports a typical edit, build, test methodology familiar to most developers wherein, a set of source files maintained in a source code repository are developed using familiar text editing tools, and ProjectBuilder builds and deploys them, so that the results can be distributed and used.

Note:

The diagram below shows ProjectBuilder in the context of an SCM repository and the ControlTier server. By issuing the Build command to the ProjectBuilder resource, a developer drives the project build life cycle: sources for model artifacts are checked out of the SCM, they are compiled, packaged and uploaded to the server, and finally are deployed to a working context where the artifacts can be used.

Pb-overview.png

ProjectBuilder is designed to support iterative development, where there are cycles of revision to the types and resource model of the project.

Since resource definition dominates the project development process, you will become most familiar with ProjectBuilder's load-resources command. This command reads an XML file containing resource definitions and processes it into a set of CTL resource definitions.

The project development cycle is undertaken in several rough steps:

  1. Choose or create a project. (See: Project setup)
  2. Source directory structure created. The ProjectBuilder commands work relative to this base directory.
  3. Define resources. Each type module can contain files that define type instances. resources can be defined in XML (project.xml) and uploaded to the server via load-resources.
  4. Optionally, create and build a type. Types can be defined in XML (type.xml) and built, uploaded to the server and locally deployed via the build-type command.
  5. Build the whole project. Process all the type and resource definitions using the Build workflow command.

Setting up

With the essential terms and concepts out of the way, this section turns to a practical discussion about setting up ProjectBuilder to develop an example project. The setup begins after the ControlTier server and client software have been installed and you can login to Workbench.

Note

Choose or create a project

For these examples, let us assume we'll create a project called "demo".

Note

See the Project setup page for instructions to create the project.

Establish Source Structure

Project source files should be organized in a standard structure. Below is a diagram showing the typical convention:

src
 |
 |--doc      ;# Populated by the ProjectBuilder "generate-forrest-docs" command
 |--jobs     ;# Job sources go here 
 |--modules  ;# Module sources go here and are organized by Type name
 `--resources  ;# resource definition files reside here (see Resource Naming Convention below)

Make the directory hierarchy:

mkdir -p $HOME/tutorial/src 
mkdir $HOME/tutorial/src/doc
mkdir $HOME/tutorial/src/jobs;
mkdir $HOME/tutorial/src/modules;
mkdir $HOME/tutorial/src/resources;
mkdir -p $HOME/tutorial/target;

Once completed you should have a structure like so:

tutorial
|-- src
|   |-- doc
|   |-- jobs
|   |-- modules
|   `-- resources
`-- target

Resource Naming Convention Tips

ProjectBuilder Directories

Most of the ProjectBuilder commands work relative to a directory that contains the source files of the project. This directory is referred to as basedir. A second directory must be identified where the ProjectBuilder's build artifacts will be written. That directory is referred to as targetdir.

Setup the SCM repo

Setup for the SCM involves:

This example uses cvs for the source code repository.

The source files will be maintained in a local CVS repository. Run the following commands to create the CVS instance and import the sources created above:

export CVSROOT=$HOME/tutorial/cvsroot; # local CVS repo path
cvs -d $CVSROOT init;                  # create the repository
cd $HOME/tutorial/src;                 # change directory and import the sources
cvs import -m "Importing tutorial example" src tutorial start; 
cd ..; rm -r $HOME/tutorial/src;       # remove the original copy.
cvs co src;                            # check out the src dir

Define the ProjectBuilder resource

There are important details about the ProjectBuilder that you can define in an XML file, details like the directories mentioned above, source code management configuration, build setup, etc.

The file listing below describes the ProjectBuilder resource using this XML format. Cut and paste its content and save it in $HOME/tutorial/src/resources/ProjectBuilder.tutorial.xml.

File listing: $HOME/tutorial/src/resources/ProjectBuilder.tutorial.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project PUBLIC "-//ControlTier Software Inc.//DTD Project Document 1.0//EN" "project.dtd">
<project>
  <!--
      **
      ** Builder settings definitions go here:
      ** 
  -->
  <setting type="BuilderScmModule" name="tutorial" 
	   description="The tutorial project source module" 
	   settingValue="src"/>
  <setting type="BuilderScmBinding" name="tutorial"
	   description="This is configured to use CVS"
	   settingValue="cvs"/>
  <setting type="BuilderScmConnection" name="tutorial"
	   description="The project source repository connection string" 
	   settingValue="${user.home}/tutorial/cvsroot"/>	
  <setting type="BuilderBuildstamp" name="tutorial" 
	   description="The initial buildstamp value"
	   settingValue="0"/>
  <!--
      **
      ** Define the tutorial ProjectBuilder deployment :
      **
  -->
  <deployment 
      name="tutorial" type="ProjectBuilder"
      description="A ProjectBuilder to maintain the project"
      basedir="${user.home}/tutorial/src"
      installRoot="${user.home}/tutorial/target"      
      >
    <!--
	**
	** References where the ProjectBuilder is hosted: 
	**       (replace strongbad with the name of your node)
    -->
    <referrers replace="false">
      <resource type="Node" name="strongbad"/>
    </referrers>

    <!--
	**
	** Setting references go here:
	** 
    -->
    <resources replace="true">
      <resource type="BuilderBuildstamp" name="tutorial"/>
      <resource type="BuilderScmBinding" name="tutorial"/>
      <resource type="BuilderScmModule" name="tutorial"/>
      <resource type="BuilderScmConnection" name="tutorial"/>
    </resources>

  </deployment>
</project>

Now load the definition using load-resources as shown below.

	
ctl -p demo -m ProjectBuilder -c load-resources -- \
  -filename $HOME/tutorial/src/resources/ProjectBuilder.tutorial.xml

You have just run one of the most common ProjectBuilder commands used to maintain projects!

As a best practice, add and commit this file to the SCM:

cd $HOME/tutorial/src/resources
cvs add ProjectBuilder.tutorial.xml
cvs commit -m "new ProjectBuilder definition" ProjectBuilder.tutorial.xml 

Define a job

Part of any project, will be the definition of various jobs. This is done in XML via job.xml. The listing below describes a very trivial example that calls the who command.

Save the content to: $HOME/tutorial/src/jobs/job.xml

File listing: $HOME/tutorial/src/jobs/job.xml

<joblist>
  <job>
    <name>who's logged in?</name>
    <description>Run the unix who command</description>
    <additional/>
    <group>sysadm/users</group>
    <context>
      <depot>demo3</depot>
    </context>
    <exec>who</exec>
    <dispatch>
      <threadcount>1</threadcount>
      <keepgoing>true</keepgoing>
    </dispatch>
  </job>
</joblist>

Add and commit this file to the SCM:

cd $HOME/tutorial/src/jobs
cvs add job.xml
cvs commit -m "new job definition" job.xml

Define a type

You might develop your own custom types to override or add to one of the existing ones supplied in the ControlTier solution library. Though not shown here you would use create-type to define a new one. The create-type command generates sources files into the "modules" directory: basedir/modules/type.

If you choose to create types, be sure you add them to the SCM repository, as well.

See: First CTL module for examples on creating your own custom type.

Install the ProjectBuilder resource

With the initial project source files created and the ProjectBuilder instance defined, you are ready to install the ProjectBuilder resource to CTL so you can run the ProjectBuilder commands.

Use the "install" action in ctl-project as shown below to install the ProjectBuilder resource:

ctl-project -p demo -a install
.
.
.
"Install" command running for resource: (ProjectBuilder) tutorial

The ctl-project command installs all the resources assigned to this Node.

You can now run its commands via the shell like so: ctl -p demo -t ProjectBuilder -r tutorial -c command

Noteworthy settings

Reviewing the steps taken in preparing this source tree a few noteworthy details should be highlighted:

Setting Example Description
SCM connection $HOME/tutorial/cvsroot path to the source in the source code repository. (used by scmCheckout)
SCM module src module to checkout of the repository (used by scmCheckout)
source base directory (aka basedir) $HOME/tutorial/src directory where checked out source resides (used by scmCheckout and runBuildScript)

The project build cycle

The ProjectBuilder Build command runs the normal Builder command workflow that includes the runBuildScript command to invoke the build tool, build file and build target. ProjectBuilder provides a basic build that will process the source artifacts you maintain under basedir.

ProjectBuilder contains an Ant build.xml file that defines the following targets:

ProjectBuilder is configured by default to call the "all" target which ensures all the targets are called. You can customize the project build cycle, by creating your own build.xml file and specify your own buildTarget.

ProjectBuilder build tool configuration is done via these settings:

Customized build

ProjectBuilder defines defaults for the build.xml and target but you can specify your own in the project.xml you use to define your ProjectBuilder resource. Below is an XML snippet for the needed Setting definitions:

<setting type="BuilderBuildFile" name="tutorial" 
	   description="The path to the build file"
	   settingValue="/path/to/my/ProjectBuilder/build.xml"/>
<setting type="ProjectBuilderBuildTarget" name="tutorial" 
	   description="The build target to call"
	   settingValue="all"/>	

Run the Build cycle

The project build cycle is driven by the Build workflow command. This command goes through the normal set of steps: checking out the project sources, recording the buildstamp, calling the build script and then import the produced artifacts to the repository.

The example below shows the Build command called with "123" as the specified buildstamp:

ctl -p demo -t ProjectBuilder -r tutorial -c Build -- -buildstamp 123

You should see output like below. The output messages show each step of the workflow command:

Start: "Run the build cycle." commands: scmCheckout,setBuildstamp,runBuildScript,repoImport
begin workflow command (1/4) -> "scmCheckout -buildstamp 123" ...
scmCheckout parameters: {basedir="/Users/alexh/tutorial/src", connection="/Users/alexh/tutorial/cvsroot", module="src", label="", scmcommand="checkout" }
cvs -d/Users/alexh/tutorial/cvsroot checkout src
[command.timer.Builder.scmCheckout: 0.093 sec]
end workflow command (1/4) -> "scmCheckout -buildstamp 123"
begin workflow command (2/4) -> "setBuildstamp -buildstamp 123" ...
Using provided buildstamp "123"
[command.timer.Builder.setBuildstamp: 0.235 sec]
end workflow command (2/4) -> "setBuildstamp -buildstamp 123"
begin workflow command (3/4) -> "runBuildScript -buildstamp 123" ...
runBuildScript parameters: {basedir="/Users/alexh/tutorial/src", targetdir="/Users/alexh/tutorial/target", buildstamp="123", buildfile="/Users/alexh/ctier/ctl/projects/demo/modules/ProjectBuilder/lib/build.xml", target="all" }
Cleaning targetdir: /Users/alexh/tutorial/target
Deleting directory /Users/alexh/tutorial/target
Created dir: /Users/alexh/tutorial/target
Building type library ...
Building library from modules in opts.basedir: /Users/alexh/tutorial/src/modules
setting property seed.build.name to tutorial-seed
Created dir: /Users/alexh/tutorial/target/modules
processing modules in directory: /Users/alexh/tutorial/src/modules
converting type.xml for module: blah
generating handlers...
packaging module: blah
Copying 1 file to /Users/alexh/tutorial/src/modules/blah
Copying 1 file to /Users/alexh/tutorial/src/modules/blah
Deleting: /Users/alexh/tutorial/src/modules/blah/module.properties.temp
Building jar: /Users/alexh/tutorial/target/modules/blah-1.jar
 seed.build.name=tutorial-seed
 generating tutorial-seed.jar
Building jar: /Users/alexh/tutorial/target/tutorial-seed.jar
Uploading module jar: "/Users/alexh/tutorial/target/tutorial-seed.jar" ...
Imported types defined in library: /Users/alexh/tutorial/target/tutorial-seed.jar
Building docs ...
Defaulting filtersfile to: /Users/alexh/ctier/ctl/projects/demo/modules/ProjectBuilder/type.properties
opts{docbase=/Users/alexh/tutorial/src/doc, targetdir=/Users/alexh/tutorial/target, forresthome=/usr/local/apache-forrest-0.8}
.
.
.
Building zip: /Users/alexh/tutorial/target/site.zip
Site generation completed. Visit file:////Users/alexh/tutorial/src/doc/build/site/index.html
Loading resources located in /Users/alexh/tutorial/src/resources...
Loading "/Users/alexh/tutorial/src/resources/ProjectBuilder.tutorial.xml" ...
.
.
.
Executing batch update ...
Loading jobs located in /Users/alexh/tutorial/src/jobs...
Succeeded creating/updating 1 Jobs:
	1: who's logged in? [1] </jobcenter/scheduledExecution/show/1>
end workflow command (3/4) -> "runBuildScript -buildstamp 123"
begin workflow command (4/4) -> "repoImport -buildstamp 123" ...
.
.
.
Uploading: tutorial-seed.jar
Puted 1 file to http://strongbad:8080/jackrabbit/repository/controltier/projects/pkgs/demo/jar/jars/tutorial-seed-123.jar
.
.
.
Completed: execution time: 50.366 sec

Some of the output was left out for the sake of brevity but you should see output messages corresponding to each build target described in the section above.

Summary

ProjectBuilder supports users that want to maintain their project content using a set of text-based source files and a typical build life cycle methodology.

ProjectBuilder provides a Build life cycle that supports processing and loading of the normal ControlTier artifacts: types, resources, and jobs.

You can extend the build process by defining your own build.xml file and configuring your ProjectBuilder resource to use it. You can also subtype ProjectBuilder and define new commands and even define a different build life cycle process by overriding the Build workflow command.

Personal tools
Namespaces
Variants
Actions
Navigation
Communication
Development
Toolbox
Print/export