katratxo on Software Development

tail -f /var/log/brain | grep -i software

Openbravo Mobile: Technical Overview and Roadmap

leave a comment »

Have you seen the power of Openbravo Mobile already? As you may have read in a previous post, we have been looking for the best HTML5 framework for Openbravo Mobile. After several months of researching, prototyping and testing we have decided that Enyo is our best option.

What’s Enyo?

Enyo is an object-oriented JavaScript application framework emphasizing modularity and encapsulation.

Back in January, HP announced the new version of Enyo, the framework powering webOS applications, but this time, a cross-browser solution optimized for mobile devices and released under the Apache license.

Since this initial announcement we have been tracking the evolution of the framework on every release. In February I posted a very simple example on how to consume Openbravo JSON REST WebServices, using Enyo (core).

In July the first non beta version was a released, by then we knew that Enyo was a real option for us.

Our experience with Enyo

We’ve been working with Enyo for several of months now and we are really pleased and enjoying the experience.

After investing time in prototypes and getting to know Enyo, our first real work was the code refactor using Enyo abstractions (Kind, Component, Control, Event) in Openbravo Web POS.

Openbravo Web POS – Powered by Enyo

The experience and result of this process gave us enough knowledge and confidence to decide and go for it:

Enyo is the right framework for Openbravo Mobile, as it provides the building blocks for developing a modular, extensible, thin, and fast mobile applications

In Openbravo Mobile we’ll use the full suit of Enyo, core, onyx and layout. Here you have some examples of the output of this great framework.

Grid View – Purchase Order Lines

Form View – Purchase Order (Processing)

The Data Model

We’ll also use Backbone.js Models and Collections for representing the entities declared in the Application Dictionary and Enyo will provide the UI widgets for manipulating those collections and models.

In the back-end we’ll use the same modular architecture in Openbravo 3.

Openbravo Mobile Architecture

Openbravo Mobile Architecture

The Roadmap

The main goal of Openbravo Mobile is to deliver the framework for developing mobile applications by the end of Q4-2012, with a few milestones in between:

  • Basic infrastructure (Login + Workspace): Be able to login using a mobile device, and open a window
  • Standard Windows: Support for windows declared in the Application Dictionary
  • Processes and Reports: Support for launching reports and processes from a mobile device
  • Support for Manual Windows: Support for View Implementations (aka Manual Windows)
  • Fine-tune Functional Flows: Revisit the flows and usability in a mobile device (Q1-2013)

I hope this gives you an overview on what has being going on in Openbravo Mobile, the Roadmap and milestones of this project. To know more about Enyo visit http://enyojs.com

Written by katratxo

October 8, 2012 at 11:37 am

Wow! 2 billion order lines per year, really? How much of that data can be stored offline?

with 2 comments

My colleague Antonio explained in his post the performance of the server side component in the Openbravo solution for Retail. Now let’s take a look on the client side part, What happens when you’re selling and your network goes down? How much time can you work in offline mode?

Imagine you have a store in Pamplona’s city center, and during San Fermín festival you sell all the required clothing for the festival: White shirt and pants, the red handkerchief and belts, bota bags, etc.

Now imagine you’re on July 5th, the day before the Chupinazo, your store is crowded by foreigners trying to buy the outfit and equipment for the festival; you have a lot of them in the queue waiting to pay. Everything is going so well, you’re selling a lot, but suddenly your network goes down, your internet connection is lost, you’re in panic!!, you start asking yourself: “Am I able to keep selling without internet connection?”Of course! You’re using Openbravo Web POS.

Remember what Antonio mentioned:

The POS terminals can work in two different modes: online mode, and offline mode. When they are online, and a sales order is created, the terminal sends this order to the Openbravo instance … If the terminal is offline, however, the order cannot be immediately sent. In this case, the order is stored in a database inside the POS terminal. Once the terminal returns to online mode, the POS terminal sends a batch which contains all stored orders to the Openbravo instance.

This is a nice feature but: How many order can I process in offline mode? How much time do I have before my POS terminal gets full?

The answer is: It depends on the processing rate (orders per minute) and the average order size (lines per order) of your store.

Let’s take the best scenario for your Pamplona store on July 5th as example. Let’s imagine that you’re are able to process 4 orders with 10 lines each every 60 seconds. That is, with a single POS terminal, you’re selling to 4 different customers every minute, without stopping a second. (This is almost physically impossible, but during Sanfermines you never know).

Some numbers (the geeky stuff)

An order with 10 lines is 3 KB of data in the POS terminal cache. If you are serving 4 customers each minute with a single POS terminal; you’re generating 720 KB per hour (nice speed). Notice that this is an ideal situation: 4 customers with 10 different products every minute without stopping.

At this frenetic rate, in a 12 hour shift without internet connection, and just before the party starts, you have stored 8.44 MB of data in your POS terminal offline cache.

While you were selling at the rate of 4 orders per minute, your colleague have called the Internet provider and reported the network problem. 12 hours later and just before closing the day, the internet connection has been restored and the terminal has sent all the 2880 orders that you have produced during the offline period.

The best thing is that you have provided all the required equipment to almost three thousand foreigners eager for party.

Don’t worry, the only limit is the physical space in your mobile device

If you are using an Android device like a Samsung Galaxy Tab 10.1 or a fully fledged Windows 7 tablet like the Asus Eee Slate EP121, your database will silently grow, allowing you to keep selling in offline mode.

At the rate of 4 orders per minute, it will take you more than 2 years to fill 10GB on your Samsung Galaxy Tab, or more than 4 years to fill 25GB on your Asus Eee Slate EP121, and remember, selling without stopping a second!!

The iPad limits

Unfortunately the previous statement is not true for the Safari browser on iOS. The Apple guys have set a 50MB limit for offline storage, but this quota is more than enough space for the normal operation of Openbravo Web POS with a very high order processing rate.

Openbravo Web POS supports enormously high processing rate

Under normal operation (online mode) every order is sent to the server immediately just after closing it. Openbravo Web POS allows you to work in offline mode but this is a fall back mode.

There are several benefits of immediately sending the orders to the server:

  1. Updated warehouse stock
  2. Generate a Sales Invoice when you specify it
  3. Any other retail related process you have implemented in your Openbravo instance

Working in offline mode shouldn’t be your normal operation mode, but even in some unusual situations where you have 1-2 days or even a week without network connection, Openbravo Web POS will support your operation without any issue.

What about Master Data?

When you login into an Openbravo Web POS terminal the required master data it is also stored in the offline cache. By master data I mean: Products (with images), Prices, Business Partners, Tax Rates, etc.

Caching master data will take space from your offline cache, but it is required to be able to have a fully working offline mode. In another post I’ll give you more detailed description of how much the master data takes in the database, but to give you a rough estimation: caching 1000 products with images and prices is about 22 MB of data. Remember the only device that enforces the 50MB quota is the iPad, on Android and Windows devices, the database will grow silently.

Conclusions

  • Openbravo Web POS supports high activity rate even without connection to the server
  • The number of orders you can process in offline mode depends on your selling rate (number of orders per minute) and the order size (average number of lines per order)
  • If you have a constant selling rate of 4 orders per minute (very unlikely), in 12 hours of offline mode you have produced 2880 orders and only filled the 17% of the initial database size
  • The only limit is your device storage space on Android and Windows devices. The database will grow silently if you reach the initial 50MB size. It will take you more than 2 years in the Samsung Galaxy Tab and more than 4 in the Windows 7 device
  • On the iPad you have a fixed quota of 50MB but you’ll have to remain selling for 3 days in offline mode (at constant rate of 4 orders per minute) to fill the database
  • If you think you’ll have huge amount of master data (products, business partners, etc) and long offline periods, you must use an Android or Windows device
  • Offline mode is an exceptional fall back mode, it shouldn’t be your normal operation mode. In online mode, every closed order is sent to the server immediately. The server will process that order and update stock and execute any other retail related process

I hope this post can clarify the most common question we often get about offline operation of Openbravo Web POS. As mentioned before, I’ll write another post more technical on master data cache.

.

Written by katratxo

July 16, 2012 at 6:18 pm

How to build a Manual Window in Openbravo 3

with 7 comments

Here you have the recorded session on “How to build a View Implementation” in two parts.

I. The basics

II. Adding a button and an Action Handler

Timeline

  • 35m28s: I said “punto” that means “dot” in Spanish. A few seconds later I say “chuleta” that means “cheat sheet” in Spain.
  • 45m55s: I started talking on “Don’t be fooled by console.log
  • 52m02s: The importance of using OB.Constants.FIELDSEPARATOR and OB.Constants.IDENTIFIER
  • 57m15s: An idea on how to support a dynamic generation of a Selector in a view implementation

You can get the code of this example at: https://bitbucket.org/iperdomo/org.openbravo.training.manualwindow

Written by katratxo

May 18, 2012 at 11:45 am

Re-introduction to JavaScript and Openbravo 3 Architecture

with 2 comments

Yesterday we had a session with the Development Team on Re-introduction to JavaScript and Openbravo 3 Architecture.

Some of the topics covered in this talk:

  • What happens when I login into Openbravo
  • What’s a Component Provider or a Component
  • What’s a Data Source
  • Which are the JavaScript classes behind a Openbravo window
  • When I need to compile or just restart Tomcat server

You can watch them online at:

Enjoy!

Written by katratxo

March 2, 2012 at 11:48 am

Testing Backbone.js and Enyo

with 3 comments

As you may know we are iterating over several JavaScript frameworks to find the most appropriate for the mobile version of Openbravo 3.

As Salvador mentioned in the Open Discussions forum, Backbone.js + Twitter’s Bootstrap is a valid combination for a mobile application.

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface …

On the other hand, Enyo

Enyo is an open source object-oriented JavaScript framework emphasizing encapsulation and modularity. Enyo contains everything you need to create a fast, scalable mobile or web application:

Built from the ground-up for mobile first – Enyo powers webOS, and was designed from the beginning to be fast and work great on mobile devices …

How easy is to create a plain product list using Backbone.js or Enyo? I wanted to give it a try. With a few lines of code I was able to make a REST call to Openbravo’s REST JSON Webservices and render a list of products.

Backbone.js

var Product = Backbone.Model.extend({});

  var ProductList = Backbone.Collection.extend({
    model: Product,
    url: '../../org.openbravo.service.datasource/Product',
    parse: function (response, error) {
      if (response && response.response) {
        return response.response.data;
      }
    }
  });

  var Products = new ProductList;

  var ProductsView = Backbone.View.extend({
    el: '#products',
    
    tag: 'ul',
    
    tpl: "<% _.each(models, function(product) { %> <li><%= product.attributes._identifier %></li> <% }); %>",
    
    initialize: function () {
      Products.bind('all', this.render, this);
      Products.fetch();
    },

    render: function (event, collection, error) {
      $(this.el).html('<ul>' + _.template(this.tpl, collection) + '</ul>');
      return this;
    }    
  });

  var App = new ProductsView;

Enyo

enyo.kind({
  name: 'ProductList',
  kind: enyo.Control,  
  components: [
      {name: 'btn', content: 'Load Products', ontap: 'loadProducts', tag:'button'},
      {name: 'list', tag: 'ul'}
  ],  
  loadProducts: function() {
      new enyo.Ajax({
        url: '../../org.openbravo.service.datasource/Product'
      })
      .go()
      .response(this, 'processResponse');
  },
  processResponse: function(inSender, inResponse) {
    var data = (inResponse && inResponse.response && inResponse.response.data), i;
    if(!data) {
      return;
    }
    for(i = 0; i < data.length; i++) {
      this.$.list.addChild(new enyo.Control({
        tag: 'li',
        content: data[i]._identifier
      }));
    }
    this.$.list.render();
  }
});
var products = new ProductList().renderInto(document.body);

I have packaged this code examples as a module. You can install it by cloning the repository and running smartbuild:

openbravo$ cd modules
openbravo/modules$ hg clone https://bitbucket.org/iperdomo/com.wordpress.katratxo.mobile.sample1
openbravo/modules$ cd ..
openbravo$ ant smartbuild -Dlocal=no

Note: openbravo is the root of your Openbravo sources

This examples doesn’t handle authentication, so in order to test them, first login into Openbravo and then visit the urls:

  • /openbravo/web/com.wordpress.katratxo.mobile.sample1/backbone.html
  • /openbravo/web/com.wordpress.katratxo.mobile.sample1/enyo.html

Conclusion

You can see that the Openbravo REST Web Services, provides a powerful layer for building alternative user interfaces for Openbravo.

We’ll keep iterating over the list of available JavaScript frameworks for Openbravo Mobile. If you have experience with Mobile Web Development, share your experience in the Open Discussions thread.

Written by katratxo

February 24, 2012 at 9:47 am

Choosing a HTML5 framework for Openbravo Mobile

with 6 comments

Openbravo 3 is a great product built on top of SmartClient library. SmartClient is a great framework that provides a set of UI components for building enterprise size, data driven applications, but it targets desktop browsers and is not well suited for mobile devices. You could make it work on a tablet device with some simplification of the UI you’re building, but when it comes to a smartphone, is way too heavy.

One of the key projects of Openbravo in 2012, is the support for mobile devices. In the last few weeks I’ve been doing some research on the available frameworks for mobile web development.

You can make a list of available HTML5 frameworks from developer community driven sites like Stack Overflow
or Hacker News:

We can complete the previous list with other libraries targeting mobile devices like:

Splitting the list in two groups

The list of available frameworks can be divided in two groups based on their approach to solve the problem:

  1. You need to generate HTML code and the library is just an abstraction on top of the DOM that helps you with the user interaction (gestures, tapping, etc)
  2. You rely and “talk” JavaScript then the framework takes care of generating the necessary HTML code for building the UI component, plus helping with the user interaction (capturing events, etc)

From our experience in building Openbravo 3, the latter approach is preferred. It’s easier to write something like isc.Window.create({width: 600, height: 400}); than building the tree structure of DIVs for building a window, apply CSS styles and then test in the different supported browsers.

I went through the list of available frameworks. For example, jQuery Mobile takes the first approach. You need to create HTML tags and annotate them with some attributes like data-role in a list.

On the other hand, with Sencha Touch you “talk JavaScript” and the library takes care of building the UI component. Unfortunately Sencha Touch is released under GPLv3 license and is not compatible with Openbravo Public License (OBPL), so Sencha Touch is not an option.

For the same licensing reason Kendo UI and DHTMLX Touch discarded too.

Other libraries

There are other interesting libraries like Bakbone.js or Ember.js.

Backbone.js “gives structure to web applications” and is usually used with jQuery or Zepto, and Ember.js (previously SproutCore 2.0) aims to eliminate “boilerplate and provides a standard application architecture”. A comparison between the two libraries can be found on Backbone and Ember

Other Approaches

There are other attempts to use Google Web Toolkit combined with PhoneGap to build mobile applications. You can check the Webcast made by O’Reilly Creating Mobile Apps with GWT and PhoneGap.

Conclusion

We haven’t decided yet which framework we’ll use, but we prefer to use a library that will help us eliminating the need of generating HTML code.

We are still iterating over the available choices, but probably we’ll make a decision in a few weeks.

If you have experience in mobile web development and want to give us a hint, we’ll love to hear from you. Drop us a line in our Open Discussion forum thread.

Written by katratxo

February 17, 2012 at 4:53 pm

Posted in Openbravo

Tagged with , , ,

Development tips – Part III

with one comment

FreeMarker syntax highlighting

As you may know, we are using Freemarker as templating engine to produce code. By default, you don’t have syntax highlighting in Eclipse, but you can fix this limitation installing JBoss Tools.

Since we are using Eclipse Indigo, you need use the Development Release

.

FreeMarker IDE plugin

After installing the plugin and restarting Eclipse, you’ll have some colored syntax when opening a .ftl file

ob-view-form.js.ftl

Identifying field names

A very common question is how to identify the name of the INPUT that is used when sending requests to the server. In 2.50 was quite easy, you just had to check the generated HTML code and search for an input tag and check the name attribute. This name is that one you use as request parameter in your servlet (e.g. a Callout).

In Openbravo 3, the code is generated in the client side by SmartClient, and most of the time you don’t have control over it. However you can use Elements tab in Chrome Dev Tools to check the resulting code.

Business Partner field name

You’ll find that wrapping the actual INPUT there are several DIVs and TDs. This wrapping code contains references to JavaScript variables you can use to access some properties, e.g. In the image above, the Business Partner selector has refereces to isc_OBSelectorItem_1.

If you use the console, you can access the JavaScript object and some of the properties:

isc_OBSelectorItem_1.name
"businessPartner"
isc_OBSelectorItem_1.inpColumnName
"inpcBpartnerId"

For backward compatibility, each field has a inpColumnName that can be used as request parameter in your servlet.

Choosing the proper Java package name

This section of the article goes mainly to Openbravo core developers. It’s important to know that that org.openbravo.* is reserved for Openbravo developments.

I started a sample module and picked the Java package, org.openbravo.test.security, after that I registered a ComponentProvider and some Component generating some JavaScript response. When I tried the code it didn’t work. After more than one hour trying to figure out what’s going on, I read the following:

Weld will analyze the classpath to find components which have specific annotations. To prevent searching all classes specific exclusion filters have been specified. They can be found in the META-INF/beans.xml file in the Weld module.

Bingo! To avoid trying to analyze the JUnit test cases in the org.openbravo.test package, we exclude any package that contains org.openbravo.**.test.** pattern.

Removing the test part of my test module Java package solved the problem.

Written by katratxo

September 6, 2011 at 9:50 am

Posted in Openbravo

Tagged with , , ,

Finding and fixing memory leaks in a SmartClient based application

leave a comment »

Finding memory leaks in a Web Application can be difficult, fortunately the tools for Web Development are getting better and better. You can read the post Finding memory leaks by Tony Gentilcore, where he explains how you can use Chrome Dev Tools Timeline and Heap Profiler to diagnose if your application is leaking memory.

In the case of a SmartClient application, you should know that when you create a new object, instance of a Class, the library pollutes the global namespace (window) with a global variable using the pattern: isc_TypeOfClass_Index e.g. If you execute the following code, you’ll end up with a new global variable isc_VLayout_0

var l = isc.VLayout.create({width: '100%', height: '100%'});

When you destroy an object, the global variable gets nullified:

l.destroy();
isc_VLayout_0 === null // true - still exists but its value is null

Taking this as a base, you could identify if your SmartClient application is leaking memory with the following procedure:

  • Take a snapshot of the current state of the global namespace
  • Perform the action you think causes the leak
  • Take a second snapshot of the global namespace and compare them
  • Every not null entry in the second snapshot that is not present in the first one, is a leak

Keep this strategy in mind.

Although most of the cases SmartClient handles objects lifecycle automatically, there are cases in which you need to destroy objects manually. Let’s take a look when this is required.

SmartClient handles child objects automatically

If you check the documentation, SmartClient has the concept of AutoChild that are subcomponents part of of a main object that gets automatically managed.

An example is the Window component and its subcomponent the “header” …
By default any auto-children created by canvas.addAutoChild or
canvas.createAutoChild will be destroyed when the canvas that created them is destroyed

Your child objects will be automatically destroyed if SmartClient knows about them, e.g. Using

Some code:

var l = isc.Window.create({
  width: '600',
  height: '400',
  items: [
    isc.Label.create({
      contents: 'Hello World'
    })
  ]
});

When you execute this code, you’ll have a lot of new global variables:

isc_Label_0
isc_Window_0
isc_EdgedCanvas_0
isc_Window_0_shadow
isc_Window_0_header
isc_Window_0_headerBackground
isc_Window_0_headerIcon
isc_Canvas_0
isc_Window_0_headerLabel
isc_Window_0_minimizeButton
isc_Window_0_closeButton
isc_Window_0_body

If you call the destroy method of the Window, the isc_Window_0 variable remains in the global namespace but with null value. The rest of variables are deleted.

isc_Window_0 === null // true

SmartClient doens’t handle objects that are not AutoChild

When dealing with complex composed widgets and if those subcomponets are not added using the AutoChild pattern, is quite easy to create memory leaks. An Openbravo example of this is the SelectorItem, a widget commonly used (Business Partner, Product selectors). This widget is a composite of a ComboBoxItem, a magnifier image and a ListGrid embeded in a Window that, is hidden by default, and shown when clicking the magnifier icon.

When destroying a SelectorItem you need to manually take care of destroying the associated objects.

SmartClient doesn’t destroy the dataSource object associated to a DataBound component

Another case is when SmartClient doesn’t destroy the associated dataSource object of a ListGrid.
This case is also present in the SelectorItem, since the selector Window contains a ListGrid with an associated DataSource.

The example below creates a new DataSource and a ListGrid bounded to it. The ListGrid is then added as item of a Window which is a member of a Layout that also contains a destroy Button. When the user clicks the button, the expected result is that all objects get destroyed in cascade.

As you can see the dataSource requires to get destroyed explicitly.

isc.DataSource.create({
  ID: "countryDS", // manually defining the global ID
  fields:[
    {name:"countryCode", title:"Code"},
    {name:"countryName", title:"Country"},
    {name:"capital", title:"Capital"}
  ],
  clientOnly: true,
  testData: countryData // sample data previously defined
});

isc.ListGrid.create({
  ID: "countryList",
  width: '100%', 
  height: '100%', 
  alternateRecordStyles:true, 
  showAllRecords:true,
  dataSource: countryDS,
  autoFetchData: true,
  destroy: function () { // 'overriding' destroy method
    if(this.dataSource) {
      this.dataSource.destroy(); // needs to be done manually
  }
  this.Super('destroy', arguments);
  }
});

isc.VLayout.create({
  height: 400, width: 600
})
.addMember(isc.Window.create({
  width: '100%',
  heigth: '100%',
  items: [countryList] // ListGrid gets destroyed
}))
.addMember(isc.Button.create({
  title: 'destroy',
  action: function () {
    this.parentElement.destroy();
}
}));

The Openbravo Case

In Openbravo 3 there were few places with some composed components, that child/related objects were not destroyed when destroying the main component.

Previous to the upcoming 3.0MP3 if you close a window (e.g. Sales Order), some objects were not getting destroyed, resulting in memory consumption increase. After working with the application a couple of hours (opening and closing several windows) the user got strange behavior like: slow reponse to user actions, slow repaint process, etc.

Some of the components that were not properly managed are:

  • LinkedItems section (section in Form view that shows you the related records)
  • SelectorItem (the component behind Product, Business Partner selector)
  • StatusBar (the component in the upper part of the Form view)
  • Loading Tab (temporary tab shown when requesting a View definition to the server)

Linked Items

Linked Items

The Linked Items section contains two ListGrids and a DataSource each one of them. When destroying the Form, you need to manually destroy the ListGrid and DataSource associated.

Selector

Selector

As explained before, the Selector is one of the most commonly used widget. When destroying the Form, you need to manually destroy the Window that contains a ListGrid and the associated DataSource.

Status Bar

Status Bar

The StatusBar contained some images not added using the AutoChild pattern and required to be manually destroyed when destroying the StatusBar.

Loading Tab

Loading Bar

When opening a window, a Loading Tab is shown in the TabSet. After the window gets created the Tab content is replaced using TabSet.updateTab. The documentation clearly states, “NOTE: the old pane for the tab is not destroyed”, you need to manually destroy the Loading Tab.

The Fix

Using scopeleaks

If we use the strategy described at the begining, we need to take a snapshot of the global namespace, perform the leaky action (open/close a window), take a second snapshot and compare.

We have used and modified scopeleaks, a utility tool created by Rui Lopes. The tool is intended for detecting leaks of variables to the global namespace. Since we now that SmartClient always leaks variables, we have modified it to only check for instances of a class, meaning any new global variable starting with isc_ that is not null.

Detecting leaks

The steps to detect a leak:

  • Login into the application

  • Open Web Dev Tools

  • Take a first snapshot of the global namespace

    var s1 = scopeleaks.snapshot();
  • Open and close a window (e.g. Sales Order)

  • Take a second snapshot and compare

    var leaks = scopeleaks.leaks(s1); // leaks will have an array with all the global variables that are not null

Repeating this flow, you could detect if a user interaction, creates new objects that are never released.

If you are interested in checking all the changes made on the components mentioned before, check the Issue 18227.

Conclusions

Solving simple memory leaks in a SmartClient based application is straight forward if you use this strategy. Note that we are only fixing the most obvious ones.

SmartClient is a great library, but even SmartClient code could cause memory leaks.

You need to learn and know the framework you’re using. You cannot go blindly creating objects here and there and expecting that everything will automatically collected when is not needed.

Use all tools available and measure memory consumption when using the application.

Written by katratxo

August 25, 2011 at 12:16 pm

Posted in Openbravo

Tagged with , , ,

Improved JSLint check on Mercurial

with 2 comments

We have been working with the previous version of the Mercurial JSLint precommit hook for several months now, and we pretty happy with the results, it catches the most common JavaScript pitfalls.

However this hook was not smart enough, it checked all the modified JavaScript files even if they were not part for the commit, and this situation annoyed some experienced developers:

I have unfinished JavaScript changes, but I’m committing a Java files!! Why this hook is checking files that are not part of the commit!?? I need to do this Java changes now … I’ll disable this hook.

The Solution

The solution is to run the check on the pretxncommit hook, where you have already the list of files that are part of the commit. You can check the modified JavaScript files and if JSLint complains, the transaction is rolled back.

The Code

The changes are simple. Use hg log to get the list of files from $HG_NODE and pass them through JSLint.

Update: The previous version of the script was not working on every case. The problem is that hg log –template ‘{files}’ outputs all the modified files in a single line. That output saw used as input of awk, that was not filtering properly. I found a workaround, perhaps is not the nicest script, but is working.

#!/bin/sh
# Mercurial pretxncommit hook
for i in $(hg log -r $HG_NODE --template '{files}'); do echo $i | awk '/.js$/ | xargs -rn1 /path/to/jslint || exit 1; done;

Credits

As many times, thanks to Juan Pablo and the Mercurial Community for providing the way to check only the files part of the changeset.

Written by katratxo

July 30, 2011 at 8:55 am

Posted in Openbravo

Tagged with , , ,

Openbravo 3 Developer’s Guide

with one comment

We have been working hard to finish the new Developer’s Guide targeting Openbravo 3. This guide contains information on how to change, extend and build further the application providing valuable information for starting developers, medium experienced and Openbravo experts.

The New Structure

Following best practices we are now using Categories as the way to structure our documentation. An overview of the categories is shown in the following diagram:

Developer's Guide Categories

  • Concepts: Contains documents that aim to explain core concepts behind Openbravo architecture.
  • HowTo: Step by step actions to achieve a goal, e.g. How to create and package a Module
  • Data_Model: Automatic generated documentation that contains the Database and Entity Model
  • Example: Documents that explain code present in the product that could be used as base for our developments
  • Reference:The hibernate mapping, REST XML Schema among other reference documents

Feedback

If you find a document that contains something wrong, outdated or not properly explained, please fix it, after all is a wiki. Note: If you want to make a large change in a document, please contact the original author explaining your proposed changes.

You could also log a defect or feature request in the issue tracker in the Documentation project. Remember to pick the right category: ERP Developers Guide.

I’ve also started a forum thread to collect your feedback and ideas on the Developers Guide.

That’s all folks!

Written by katratxo

July 14, 2011 at 12:41 pm

Posted in Openbravo

Tagged with ,