v1.0 Release – Expand/Collapse Functionality only for Merges with >5 Pushes

In my goals post I outlined that I wanted to take on a new bug. This bug outlines that only merges that have >5 pushes should be given expand/collapse functionality. Any merge that contains <5 pushes should be shown normally. I guess, when the original expand/collapse bug was fixed we all forgot about this little feature. No big deal though because I’m gonna fix it now.

The following is the current server-side code:

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
if id != lastid:
  lastid = id
  p = parity.next()
  entry["push"] = [{"user": user,
                  "date": localdate(date)}]
  if len([c for c in ctx.parents() if c.node() != nullid]) > 1:
    mergehidden = "hidden"
    entry["mergerollup"] = [{"count": 0}]
  else:
    mergehidden = ""
  currentpush = entry
else:
  entry["hidden"] = mergehidden
  if mergehidden:
    currentpush["mergerollup"][0]["count"] += 1
entry["parity"] = p
l.append(entry)

This is where the change will have to be made. Lets have a look here. On line 401 there’s an if statement that executes to true if the changeset has more than one parent, which means that it is a merge changeset. Then, the following lines setup the expand/collapse functionality. It is line 401 where I will make the change to implement this functionality.

A merge changset should have 2 parents. So, in order to find out how many pushes there are in the merge I just do a simple substraction between the rev number of parent 0 and the rev number of parent 1. The result will tell me how many pushes that merge contains. Only implement expand/collapse functionality for the merge if the result is greater than 5.

The new code:

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
if id != lastid:
  lastid = id
  p = parity.next()
  entry["push"] = [{"user": user,
                  "date": localdate(date)}]
  if len([c for c in ctx.parents() if c.node() != nullid]) > 1 and ctx.parents()[0].rev() - ctx.parents()[1].rev() > 5:
    mergehidden = "hidden"
    entry["mergerollup"] = [{"count": 0}]
  else:
    mergehidden = ""
  currentpush = entry
else:
  entry["hidden"] = mergehidden
  if mergehidden:
    currentpush["mergerollup"][0]["count"] += 1
entry["parity"] = p
l.append(entry)

As you can see above I only needed to change line 401 to implement this change. It’s always great to be able to add new functionality without needing additional lines of code. A win win!

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v1.0 Release – Expand/Collapse for the Files Touched Patch

In my goals blog post I stated that I wanted to add expand/collapse functionality to the files touched patch. Why you ask? Well the whole goal is to get the pushlog to show more information but in an unobtrusive manner. Right now this isn’t happening. Adding expand/collapse functionality will allow the user to decide when he wants to see the files and when he doesn’t.

I recently wrote a white paper on the ergonomics of touch screens. One thing that I learnt from that exercise is that it is the application’s job to adapt to the user and not the other way around. The application will not succeed if the user is forced to adapt to the application. I think this concept applies to this situation where the pushlog provides the user the ability to hide or show the files touched instead of always showing them, which forces the user to adapt to the new look of the pushlog.

The Implementation

The map file

pushlogentry = '<tr class="parity#parity# #hidden# id#id#"><td>#push%pushinfo#</td><td class="age"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td><td><strong class="filerow">#author|person# &mdash; #desc|strip|escape|buglink#</strong><span class="filetouch fileid#id#">{filesTouched}</span> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span>#mergerollup%mergehidden#</td></tr>n'

pushlog.tmpl

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  // hide files touched
  $('.filetouch').hide();
  // Add expand/collapse link
  $('.filerow').each ( function(i) {
    if($(this).next().html() != "") {
      var pushid = ($(this).next().attr("class")).match(/fileidd+/);
      $(this).html($(this).html() + "<br/><span class="filelink">hidden files <a class="expandfile fileid" + pushid + "" href="#">[Expand]</a></span>");
    }
  });
 
  // add click handler to unhide hidden things
  $('.expandfile').click(function () {
    if ($(this).text() == "[Expand]")
      $(this).text("[Collapse]");
    else
      $(this).text("[Expand]");
 
    var pushid = $(this).attr("class");
    pushid = '.' + pushid.match(/fileidd+/);
    $(pushid).toggle();
    return false;
  });

The above pushlog.tmpl code is placed inside $(document).ready(). As you can see I basically hide all the files touched data on line 40. Then, I go through each files touched span and create the appropriate expand/collapse link on line 42. Lastly, I have the click handler that is responsible for displaying or hiding the files touched span. One important thing to note is that I must have a unique id (“fileid” in this case) for each expand/collapse link so that I know which files touched span to toggle. Without this unique id clicking on any one link would cause all links to expand/collapse, which we obviously don’t want.

There we have it, a nice and easy solution to this problem.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | 1 Comment

v1.0 Release Goals

It’s that time now, time for my last release for the open source course at Seneca. I can’t believe how fast time has gone by. It just feels like yesterday that I had started out in the first version of the course and now it’s all almost over. Anyway, I’ll leave the reminiscing for later. Lets take a look at what my plans are for this release.

I will be revisiting one of my larger bugs. I’ll look to re-write the client-side code to make it compatible with the current version of hg_templates. Furthermore, I want to change the current code to take advantage of jquery and make the localize dates link work with the new entries loaded onScroll.  Also, I want to improve the bug link functionality so that bugs that only have 5 digits in them are properly converted into links. Next, I’ll look to add expand/collapse functionality to the files touched bug and take on a new bug. All in all quite a lot to do. The following are my goals for this release:

  • Load more entries on scroll – Make onScroll functionality work with the new hg_templates/pushlog.tmpl, re-write code to use jquery, make the localize dates link work with all new entries loaded on scroll and Improve bug functionality
  • Add expand/collapse to files touched
  • Fix expand/collapse functionality for merges (new bug) – Expand/collapse functionality should only be added to merges that contain >5 pushes

Well, there’s some hard work ahead and I need to work fast because I have exams next week as well so my work will have to be efficient. However, I’m sure that I will be able to manage this situation. Only one more week to go and then my time at Seneca will come to an end. Four years gone in the blink of an eye, amazing!

Please navigate to the project page for more details.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | 1 Comment

v0.9 Release Complete

All the goals for my v0.9 release have been accomplished and thus another release comes to an end. Looking back I ended up using quite a bit of jquery to fix my bugs. In the process I learnt some new things about the library that I didn’t know beforehand, such as how $(document).ready() works. The guys over at jquery have definitely done some good work.

Files touched

This patch had bitrotted as the pushlog had gone through a variety of changes since I had submitted it way back in 2008. Now, it is up to date and raring to go. I will most probably have another iteration for this patch though, where I add expand/collapse functionality to it. Although, I’ll have to get clearance from ted first though.

Changeset UI

Ted gave me an r- review since he didn’t like that I was removing what the user had entered in the text boxes if another item was selected from the drop down list. Also, he wanted the drop down list to remember which query type was last executed. I’ve managed to get both these features working and I also altered the code to take advantage of jquery, which is now available in hg_templates.

Line breaks turned into spaces

This was the new bug that I tackled this release. First of all I wanted to keep the line breaks instead of have them turned into spaces. I managed to do that. Next, I had to implement expand/collapse functionality for any commit messages that had more than one line break. Since I had experience doing this with another bug; I quickly managed to get this functionality working.

The following are the important links for this release:

The patches have been posted to their respective bug pages. Please view the project page for further details.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , | 1 Comment

v0.9 Release – Fix for the Line Break bug

In my previous blog post I explained the line break bug and how I would go about fixing it. I’ve managed to get the functionality up and running now. Lets have a look at the code:

// ellipsis for multi-line desc messages
$('.desc').each(function (i) {
  if($(this).html().indexOf("n") != -1) {
    $(this).html($(this).html().replace(/n/g, "
"));
    $(this).html(createEllipsis($(this).html(), ($(this).attr("class")).match(/idd+/) + i));
    $('.hide').hide();
  }
});
$('.ellipsisexpand').click(function () {
  var pushid = $(this).attr("class");
  pushid = 'span.' + pushid.match(/idd+/);
  $(pushid).toggle();
  return false;
});
function createEllipsis(html, pushid) {
  return html.substring(0, html.indexOf(""))
    + "<a class="&quot;ellipsisexpand" href="">[...]</a><span class="&quot;hide">"
    + html.substring(html.indexOf(""), html.length)
    + "</span>";
}

The map file:

<strong class="desc id#id#">#author|person# — #desc|strip|escape|buglink#</strong>

When using jquery you want to keep all your functionality within the $(document).ready function, which is what I have done. So, in the map file I gave the strong tag that contains the commit message a new class, called desc (see above). Then, I loop through each tag containing a class called desc with the code on line 36. Within the loop I replace all occurances of ‘n’ with ‘<br/>’.  Next I call createEllipsis() (line  39). This function rewrites the html within the strong tag to include an ellipsis link and puts all the lines that will get expanded/collapsed in a different span tag. Lastly, line 40 hides everything that should be hidden.

Next I have a click handler that expands/collapses any span tag with the class name ‘hide’. Within this function, I also uniquely identify which span tag to toggle. This is needed because there are can be more than one span tag with the class name, ‘hide’ on any given page. I set the pushid as one of the class names to uniquely identify each span tag. Thus, each span tag that should be hidden will have two class names, hide and the pushid. See the results below:

Collapsed Example

Expanded Example

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v0.9 Release – Contemplating the Implementation for the Line Break bug

As one of my goals for this release I wanted to take on a new bug. Now, the problem is that if there are line breaks in the commit message the pushlog will just turn them into spaces. Thus the message will become one big clump of text, which doesn’t look good.

The goal is to only show the very first line of the commit message if it has any line breaks in it. Then have an ellipsis link at the end that the user can click to expand/collapse the rest of the message. Also, when the message is expanded the line breaks should be displayed properly. For example:

Current Implementation

I am trying to fix a new bug 1) I will use jquery 2) I will finish it soon 3) 2 + 2 is 4

New Implementation while collapsed

I am trying to fix a new bug [...]

New Implementation while expanded

I am trying to fix a new bug [...]
1) I will use jquery
2) I will finish it soon
3) 2 + 2 is 4 or is it 22?

I will probably keep all the new code on the client side, implemented using jquery. Right now the line breaks are turned into spaces because they use the ‘n’ character instead of using ‘<br/>’. I want to change all the line breaks to ‘<br />’ and then add an ellipsis link to all the commit messages that need it.

I’ve added expand/collapse functionality to the pushlog before so this shouldn’t be very hard to do. Look out for my next blog post explaining my implementation.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v0.9 Release – Implementing changes to the Changset Query UI

In my goals blog post I outlined my revised plans for the changeset query UI. I wanted to make the use of jquery now that the library has been added to the repo. Also, the textbox value that the user enters for a query shouldn’t be removed or changed. Furthermore, I wanted to add the 3rd query supported by the pushlog, which takes in two pushids. Lastly, I also wanted the UI to remember the previously executed query (I forgot to specify this in my goals post). So, for example if I make a changeset query and the results are displayed, the selected item on the drop down should still be a changeset. I believe this is what ted wanted, if I understood him correctly.

Previous Implementation

Let me show you the old code to put things into perspective so that it’s easier to visualize what changes I have made:

function changeQueryType() 
{
  var queryType = document.getElementById("querytype");
  var fromBox = document.getElementById("from");
  var toBox = document.getElementById("to");
  if(queryType.value == "changeset") {
    fromBox.name = "fromchange";
    fromBox.value="#fromchange|escape#";
    toBox.name = "tochange";
    toBox.value="#tochange|escape#";
  } else {
    fromBox.name = "startdate";
    fromBox.value="#startdate|escape#";
    toBox.name = "enddate";
    toBox.value="#enddate|escape#";
}
<form action="{url}pushloghtml">
<div class="search">
<select id="querytype" onchange="changeQueryType()">
<option value="date">Date</option>
<option value="changeset">Changeset</option>
</select>&nbsp;&nbsp;&nbsp;
From:
<input id="from" type="text" name="startdate"  value="#startdate|escape#"/>
To:
<input id="to" type="text"name="enddate"  value="#enddate|escape#"/>
<input type="submit" value="Search"/>
</div>
</form>

Moving to jquery

As I mentioned before we are now using jquery in hg_templates. This is a great move as I love using this library. I’m still learning new things about it every time I try something. Here is what my code looks like with the jquery changes:

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// remember the previously selected query
var queryString = window.top.location.search.substring(1);
if(queryString != "") {
  if(queryString.indexOf("startdate") != -1)
    $(".querytype option[value='date']").attr('selected', 'selected');
  else if(queryString.indexOf("fromchange") != -1)
    $(".querytype option[value='changeset']").attr('selected', 'selected');
  else if(queryString.indexOf("startID") != -1)
    $(".querytype option[value='pushid']").attr('selected', 'selected');
}
//decide what query to execute
$('.querytype').change(function () {
  if($('.querytype option:selected').attr('value') == 'date') {
    $('.from').attr('name', 'startdate');
    $('.to').attr('name', 'enddate');
  }
  else if($('.querytype option:selected').attr('value') == 'changeset') {
    $('.from').attr('name', 'fromchange');
    $('.to').attr('name', 'tochange');
  }
  else {
    $('.from').attr('name', 'startID');
    $('.to').attr('name', 'endID');
  }
});
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<form action="{url}pushloghtml">
<div class="search">
<select class="querytype">
<option value="date">Date</option>
<option value="changeset">Changeset</option>
<option value="pushid">pushID</option>
</select>&nbsp;&nbsp;&nbsp;
From:
<input class="from" type="text" name="startdate"/>
To:
<input class="to" type="text" name="enddate"/>
<input class="submitquery" type="submit" value="Search"/>
</div>
</form>

Remembering the previously executed query

Now, this was a bit tricky. I experimented with 2 or 3 methods. There is the obvious method where I just read in whatever is entered and match it against a regex to see what type of query was executed. I decided not to take that approach. Then, I looked at using jquery to read the selected item in the drop down list when the search button gets clicked. That didn’t work for me. I ended up looking at the query string to find out what query got executed.

So in the above code (line 38) I just retrieve the query string and do an indexOf to find the query type. It ended up being pretty simple.

Don’t remove the values entered by the user

To improve usability, ted recommended that I shouldn’t reset the text box value when the drop down selection changes. First of all I decided to remove the default date that you currently find in the text boxes. This is because if I make a changeset query via the new UI, after the page loads the default date values re-appear in the text boxes since they are hard coded.

Now when the change event occurs I don’t set the value and so if the user decides to change the query type the values he entered will not change.

The 3rd pushlog query

There is another pushlog query that takes in a startID and an endID. I’ve added this new query option to the drop down menu as well.

Unfortunately for this patch showing screenshots won’t help at all since you have to try it out for yourself to see whether the implementation works correctly or not. I’ll be putting up the patch soon so whoever is interested can get it from the bug page and try it out for themselves.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v0.9 Release – Updating the Files Touched Patch

So, as I had mentioned in my goals blog post, I would be updating my files touched patch to work with the new code now found in the repo. First of all lets have a look at my old code:

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
def changelist(limit=0, **map):
  allentries = []
  lastid = None
  ch = None
  l = []
  for id, user, date, node in entries:
      filesTouched = ''
      ctx = web.repo.changectx(node)
      if len(ctx.files()) > 1:
        for f in ctx.files():
          filesTouched += f + '<br/>'
      else:
        for f in ctx.files():
          filesTouched += f
      if id != lastid:
          lastid = id
          l.append({"parity": parity.next(),
                    "user": user,
                    "date": localdate(date),
                    'numchanges': 0,
                    "changes": []})
          ch = l[-1]['changes']
      ctx = web.repo.changectx(node)
      n = ctx.node()
      ch.append({"author": ctx.user(),
                 "desc": ctx.description(),
                 "files": web.listfilediffs(tmpl, ctx.files(), n),
                 "rev": ctx.rev(),
                 "node": hex(n),
                 "tags": nodetagsdict(web.repo, n),
                 "branches": nodebranchdict(web.repo, ctx),
                 "inbranch": nodeinbranch(web.repo, ctx),
                 "parity": l[-1]["parity"],
                 "filesTouched": filesTouched
                 })
      l[-1]['numchanges'] += 1
 
  if limit > 0:
      l = l[:limit]
 
  for e in l:
      yield e
pushlogchange = '<td class="age"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td><td><strong>#author|person# &mdash; #desc|strip|escape|buglink#</strong><br/><span style="font-size: x-small; color: #996633; font-weight: bold">#filesTouched#</span> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></td></tr><tr class="parity#parity#">'

pushlog-feed.py has changed quite a bit since I submitted this patch a few months back. Thus, I’ll have to change my code a bit. Even the map file has changed but my code itself (for the map file) won’t be changing much. I’ll just be placing it in a different area. Also, as you can see above I have the CSS within the span tag. That has to be moved to the a stylesheet.

Lets look at my solution:

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
def changelist(limit=0, **map):
  # useless fallback
  listfilediffs = lambda a,b,c: []
  if hasattr(webutil, 'listfilediffs'):
      listfilediffs = lambda a,b,c: webutil.listfilediffs(a,b,c, len(b))
  elif hasattr(web, 'listfilediffs'):
      listfilediffs = web.listfilediffs
 
  allentries = []
  lastid = None
  ch = None
  l = []
  mergehidden = ""
  filesTouched = ""
  p = 0
  currentpush = None
  for id, user, date, node in query.entries:
      ctx = web.repo.changectx(node)
      n = ctx.node()
      entry = {"author": ctx.user(),
               "desc": ctx.description(),
               "files": listfilediffs(tmpl, ctx.files(), n),
               "rev": ctx.rev(),
               "node": hex(n),
               "tags": nodetagsdict(web.repo, n),
               "branches": nodebranchdict(web.repo, ctx),
               "inbranch": nodeinbranch(web.repo, ctx),
               "hidden": "",
               "push": [],
               "mergerollup": [],
               "filesTouched": filesTouched,
               "id": id
               }
      if id != lastid:
          lastid = id
          p = parity.next()
          entry["push"] = [{"user": user,
                            "date": localdate(date)}]
          if len([c for c in ctx.parents() if c.node() != nullid]) > 1:
              mergehidden = "hidden"
              entry["mergerollup"] = [{"count": 0}]
          else:
              mergehidden = ""
          currentpush = entry
 
 
 
      else:
          entry["hidden"] = mergehidden
          if mergehidden:
              currentpush["mergerollup"][0]["count"] += 1
      entry["parity"] = p
 
      for f in ctx.files():
        entry["filesTouched"] += '<br/>' + f
 
      l.append(entry)
 
  if limit > 0:
      l = l[:limit]
 
  for e in l:
      yield e
pushlogentry = '<tr class="parity#parity# #hidden# id#id#"><td>#push%pushinfo#</td><td class="age"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td><td><strong>#author|person# &mdash; #desc|strip|escape|buglink#</strong><span class="filetouch">{filesTouched}</span> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span>#mergerollup%mergehidden#</td></tr>n'
span.filetouch {
  font-family: sans-serif; 
  color: #996633; 
}

I have reduced the server side code a little but I’ve managed to retain the same functionality, which is always great. I moved the declaration of the filesTouched variable to the top where the rest of the variable declarations occur.

So, the entry dictionary holds the filesTouched key/value. I set the value in my for loop at line 415. In my previous code I had an if/else statement, which I have now removed. This is because before I had a static line break in the map file right before the files are displayed. I removed that and just decided to add a line break before each file is displayed (line 416). Now I don’t have to worry about whether there is only one file touched or more than one and add a line break accordingly (which is what the old if/else statement was for).

Also, as you can see the CSS now cleanly resides in the style-gitweb.css stylesheet. I still don’t know about the text color though. Does it match the color scheme of the gitweb_mozilla template? Not really but I couldn’t find any other color that was both readable and matched the theme. I guess I could have left the text black but I wanted to differentiate it somehow. I guess this is the difference between a programmer and a designer eh?

In the future (maybe my next release) I’ll look to add expand/collapse functionality for this bug since many times just one push can touch a large amount of files. For now, I hope this gets reviewed and approved soon so that people can start reaping its benefits.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v0.9 Release Goals

The end of the semester is approaching rapidly (only 2 weeks left) and so is my time here at Seneca. I can’t believe 4 years have gone by so fast. No time to think about my time after graduation though. I’m in engulfed in work right now, a typical situation this late in the semester. Anyway, it’s time for yet another release.

This time I’m not going to touch my major bug. Instead, I’ll be making changes to three other bugs this time around. I’ll be revisting one of the bugs that I fixed last semester (files touched). It had been approved for a long time now but the patch never got applied to the repo and it seems to have bitrotted now. The next bug I will be tackling is the changesetUI one for which I need to make some changes. Last but not the least, I’ll will take on a new bug regarding line breaks for long messages. The following are the goals for this release:

  • Files touched – Update the patch to make it work with the new code in hgpoller and hg_templates. Also move the all the css to a stylesheet.
  • Changeset UI – ted reviewed the patch that I submitted for this bug and he doesn’t want me to set the value when the drop down changes. This would mean that whatever the user has already entered would be overwritten. I guess it makes sense, since you want to avoid that from a usability standpoint. Also I will look to re-write the code to take advantage of jquery which has been added to the repo now. Furthermore, there is another query for the pushlog that takes in two pushids. I will be adding that to the drop down list as well.
  • Line breaks turned into spaces – When a long message is displayed in the pushlog the linebreaks are not registered. My goal is to only show the first line and then show an ellipsis link that the user can click to show/hide the rest of the message that has the line breaks.

Fun stuff! Time to get to work!

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , | 1 Comment

v0.8 Release Complete

I’ve finished another release for DPS911. I’m glad that I got to work on something different this time around along with the older stuff that I have been trying to improve.  The changeset query is quite useful but very hidden right now. I think with the fix for this bug more people should start using it. I’ve also made some major changes to my onScroll patch. I think the code is looking much better now. Readability has definitely increased, at least from my point of you.

Furthermore, I tackled a major problem with displaying merge changesets. Earlier, I had thought that it wasn’t occuring because of my code but I was wrong. I’ve put out a fix which seems to fix the issue. I’ll have to wait for a final word from ted to know for sure though, since he has more knowledge than me when it comes to how merges work in Mercurial. Anyway, without further adieu the following are the important links from this release:

The patches have been posted, a total of three. More information can be found on the project page.

Posted in DPS911, Mercurial Project, Open Source | Tagged | Leave a comment