Showing posts with label Orion. Show all posts
Showing posts with label Orion. Show all posts

Wednesday, February 02, 2011

Embedding the Orion Editor

[Edit Jan 3, 2012: Orion has evolved significantly since this post was first written a year ago. Please see this post written by Felipe for an update.]

Yesterday I wrote a blog post which contains a few snippets of Ant code. If you have java-script enabled, those snippets should be nicely formatted with line numbers and some basic syntax highlighting.

Those code snippets are actually being shown using the Orion Editor embedded into my blog post. Granted, using the full editor here is a little over-kill since we aren't doing very much with it, but this was an interesting exercise.

Here is the javascript I wrote to do this:

/*******************************************************************************
 * Copyright (c) 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
function findOrionElements(tagName){
   var elements = [];
   var tags=document.getElementsByTagName(tagName);
   for(var i=0;i<tags.length;i++) {
      if(tags[i].getAttribute('name')==='orion') {
         elements.push(tags[i]);
      }
   }
   return elements;
}

function createEditors() {
   //find all pre elements named 'orion'
   var elements = findOrionElements('pre');

   
   for(var i=0; i < elements.length; i++) {
      var element = elements[i];

      //extract the text from inside the pre
      var text = "";
      for( var j=0; j < element.childNodes.length; j++ ) {
         var nodeName = element.childNodes[j].nodeName;
         if (nodeName === "#text")
            text += element.childNodes[j].nodeValue;
         else if (nodeName === "BR" )
          text += '\n';
      }
      
      /* Create the editor: 
          - parent is the containing div element
          - readonly by default, but can specify class="writable"
          - use the given stylesheet  */
      var parentNode = element.parentNode;      
      var elementClass = element.getAttribute('class');
      var editor = new eclipse.Editor({
         parent: parentNode, 
         readonly: !(elementClass && elementClass.indexOf('writable') > -1),
         stylesheet: "http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/editor.css"
      });

      // use javascript styler for now, there is no html/xml syntax highlighting yet
      var styler = new eclipse.TextStyler(editor, "js");
      // add a ruler with line numbers to the left side
      var lines = new eclipse.LineNumberRuler("left", {styleClass: "ruler_lines"}, {styleClass: "ruler_lines_odd"}, {styleClass: "ruler_lines_even"});
      editor.setText(text);
      editor.addRuler(lines);

      //fix the height of the containing div
      parentNode.style.height = (editor.getLineHeight() * (editor.getModel().getLineCount() + 1)) + 2 + 'px';  
   }
}


This code is looking for all <pre name='orion'> elements and creating editors to replace them. These elements should generally be contained inside a <div> element. HTML for a replaceable section would look like this:

<div><pre name="orion" class="writable">
   var hello = "Hello World!";
   alert(hello);
</pre></div>

This example above was made writable by adding "class='writable'" to the <pre/> element. Inside the <pre> element, all '<' should be escaped as '&lt;' and all '>' as '&gt;'.

As a final step, to get this working on blogger.com, I combined my javascript together with:
org.eclipse.orion.client.editor/web/js/editor.js
org.eclipse.orion.client.editor/web/js/model.js
org.eclipse.orion.client.editor/web/samples/rulers.js
org.eclipse.orion.client.editor/web/samples/styler.js
and minified it all using the Google Closure compiler. I hosted the resulting .js file on download.eclipse.org and added the following lines to the bottom of my blog post:

<script type="text/javascript" src="http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/orion-editor.js"></script>
<script type="text/javascript">document.onload=createEditors();</script>


If someone visits the post without javascript enabled, then they don't get the nice formatting on the code snippets, but at least they are still inside <pre> elements which give them some basic formatting.


Thursday, January 27, 2011

Building from Git

Git was introduced at Eclipse about a year ago. Projects are slowly migrating over to use git as the SCM system instead of CVS or SVN. When IBM made its initial contribution for the new Orion project, we migrated from internal CVS servers to git at eclipse.org. This post will give an overview of the changes I had to make to our releng setup to start building from git.

There have been a few PDE/Build bug fixes in 3.7 to support building from Git. I recommend using a recent 3.7 build as your base builder. 3.7M5 is due out this week.

General Setup

The Orion releng build is a relatively standard p2 enabled PDE/Build product build.

There are a few things that need to be done to get the build working with git:
  1. Bootstrapping the builder
  2. Getting map files
  3. Fetching source from Git
The e4 builds consume source code from git repositories, but the releng project and map files are still in CVS. Only the 3rd step here was required for e4. The entire Orion project including releng project and mapfiles is in git so we need all three.

Bootstrapping the Build

The Orion releng builds run via cron job on build.eclipse.org. We need a small shell script that can get the Orion releng project from git and start everything off. We do this using the git archive command:
git archive --format=tar --remote=/gitroot/e4/org.eclipse.orion.server.git master
 releng/org.eclipse.orion.releng | tar -xf -
The build machine has local access to the git repository, if we were running from somewhere else, this would change to something like --remote=ssh://user@dev.eclipse.org/gitroot/...

This will get the releng project into the current working directory, at which point we can invoke ant on it.

Getting map files from Git

PDE/Build uses map files to fetch our code from source repositories. The first step to this is getting the map files themselves.

PDE/Build comes with default support to fetch map files from CVS which is controlled by a few properties (see Fetch phase Control). This obviously doesn't apply here. However, this step is fully customizable using the customTargets.xml file.

All we need to do is copy the org.eclipse.pde.build/templates/headless-build/customTargets.xml file into our builder and modify the getMapFiles target. We can then use the git archive command to get our map files. It would look something like this:
<target name="getMapFiles"  unless="skipMaps">
 <mkdir dir="${buildDirectory}/maps" />
 <exec executable="git" dir="${buildDirectory}/maps"
     output="${buildDirectory}/maps/maps.tar">
    <arg line="archive -format=tar" />
    <arg line="--remote=/gitroot/e4/org.eclipse.orion.server.git" />
    <arg line="master releng/org.eclipse.orion.releng/maps" />
 </exec>
 <untar src="${buildDirectory}/maps/maps.tar" dest="${buildDirectory}/maps" />
</target>
Because the "| tar -xf -" we used earlier is a redirection done by the shell, that doesn't work when we invoke git from ant. Here we specify a file to hold the output of the archive command, this ends up being a tar file which we can just untar.

Fetching source from Git

PDE/Build has an extension point where fetch script generators for different repositories can be plugged in. The EGit project provides an implementation for this extension point.
The org.eclipse.egit.fetchfactory bundle is available from the http://download.eclipse.org/egit/pde/updates-nightly p2 repository. Install that bundle into the eclipse install that is used to run your build.

Git Map Files

Once we have the egit fetchfactory, all we need to do is update our map files with entries for GIT. Here is an example map file entry from Orion:
plugin@org.eclipse.orion.client.core=GIT,tag=v20110125-1800,\
       repo=dev.eclipse.org:/gitroot/e4/org.eclipse.orion.client.git,\
       path=bundles/org.eclipse.orion.client.core
  • tag is the tag to use when fetching the bundle from git
  • repo is the path to the git repository. In order to omit the user from the repository path, the build needs to run as a user who has ssh access to the git repo at dev.eclipse.org
  • path is the path within the git repository to the project we are interested in.

Final Details

  • The EGit fetch factory works by cloning the git repository to a local directory, checking out the tag and then copying the project over to the build Directory. Builders can set the fetchCacheLocation property to specify a local directory where the git clones can be kept. This location may be reused from build to build to avoid having to re-download the entire repository each build.
  • "Nightly" builds are set up to build the latest code from HEAD. For CVS, this is usually accomplished by setting "fetchTag=HEAD" to override the map file entries. For Git you would use "fetchTag=origin/master". If you are using both CVS and GIT you can set both with "fetchTag=CVS=HEAD,GIT=origin/master".
  • The Eclipse Platform team uses the releng tool plugin to manage their map files in CVS, there is not yet an equivalent tool for git. See the Orion Releng and E4/Git wiki pages for instruction on how to manage map files.