luni, 9 septembrie 2013

#11 - C implementation of command server API

Using the approach that I mentioned in the last blog post I was able to finish
the implementation for all mercurial commands (the implementation for level 1).

The code has grown fast and now it’s time to start the refactoring to make it
clearer and easier to understand.

Also I have to create some automatic tests to make the API stronger and to proof
that you can use the code without any risks. Until now I tested the code into a
main function, using some system calls to create the repository and to test my
commands. The verification was just visual.

This is not enough to show the correctness but more ample tests will follow
soon.

luni, 2 septembrie 2013

#9-10 - C implementation of command server API

In the last two weeks, I focused on building a strong environment for level 1 of
hglib API. I exchanged communication with the interested peers to find the best
architecture and style that will fit with my project. We chatted a lot on the
IRC channel and I also got reviews on my patchbombs from dev-list.
In the end we decided to split this level in two, using two models to implement
the mercurial commands.
""""
There are two possibilities on how level 1 commands can behave:
(1) Return immediately after having sent the command to commandserv,  just
wrapping a call to hg_rawcommand().
   Other API functions are provided to retrieve:
   (a) the data sent in response by the commandserv, in parsed (structured) form
   (b) the exitcode, i.e. the content of the 'r' channel after all things  have
happened.
(2) Wait for the commandserv to complete *all* its actions in response to the
issued command, which is cached in the commandserv response somewhere, and
return the actual exitcode (channel 'r' from commandserv) as the result of the
chglib API call
"""
Using this idea I sketched those two models.
I associated the hg_log command to model 1, because this command will handle a
huge amount of data. In this way, the problem of overflowing my memory was
bypassed. Also for this model I implemented a mechanism that we called
iterator-like mechanism, from where the user will get some parsed data in a
predefined structure. In this way the user will get his desired data in a more
easier way.
For model 2 I sketched the hg_add command, because the add command and more
other mercurial commands, are not performing any kind of parse data. The most
important thing on those commands is the exitcode, even if everything works well
or not. Also we can have errors for those kind of commands, errors that some
users will be interested in. To give users the possibility to handle those
errors we use a callback function, created and passed by users to those
commands.
After sketching those two models, it was a short time where I was waiting to
receive review to know if the implementation is the waiting one. Meanwhile I
made a list with all mercurial commands to know with which of those what model
will fit.
Until now, I implemented a good part of mercurial commands but still have a lots
of work. Probably at the end of this week I will finish the implementation for
all mercurial commands and will start to make a big refactoring.

joi, 15 august 2013

#7-8 - C implementation of command server API

There have been almost two weeks since my last blog post.

During this time I changed level 0 implementation after some advice, I built a
sketch for level 1 and started implementing some level 1 commands. Also I built
a doxygen documentation for project.

After sending the patchbomb to mercurial dev list, I got some reviews and new
ideas about level 0 implementation. I changed the rawcommand function to receive
the argument list that will terminate by a NULL pointer instead of counting and
passing the size of argument list.

Concerning the sketch for level 1 I got some reviews and we made an agreement on
how this level must work. We made a list of commands that I will would like to
build first (add, commit, push, pull, log, import/export, merge, verify).

One of those first commands that I already implemented is the log command which
has to handle huge mass of data. In my implementation I used an iterator-like
mechanism which gets from cmd-server a change set in one call and returns in a
structure the parsed data.

Meanwhile I started to build the doxygen documentation for a better concept
understanding. I think that it's a good way to navigate through the c-hglib API,
and an easier way to find the needed function.

joi, 1 august 2013

#6 - C implementation of command server API

With the midterm closing by, last week I had tried to show to the
mercurial community my work. From my point, the work on level 0 hglib
has come to an end. A confirmation from mercurial crew is still
required, so I am currently waiting for it.

To show the functionality for level 0 API, I followed all the stories
that Matt asked for, and I built those stories using just level 0 API.
Giovanni gave me some advice on how to build a switch case on main
file and to use system calls to create the proper environment where
the stories will be tested.

After I finished to build all those examples, I entered on refactoring
phase, to find and change the code before sending a patchbomb to
mercurial dev.
The patchbomb was sent and now I am waiting for the confirmation.
Meanwhile I will start sketching some ideas for level 1, command level
(function per command, returns results in native C datatypes).

miercuri, 24 iulie 2013

#5 - C implementation of command server API

It was a long week with lots of commits and changes on my project. I
almost finished the level 0 implementation. Right now with those basic
prototypes a client can handle and implement almost all the mercurial
commands.  Now he can easily establish the connection with mercurial
command server and then send and receive data through this connection.

On our weekly meeting, my mentor, Giovanni taught me a lesson about
the ‘log’ issue, how I must handle the huge mass of data, and how to
deliver this data through the pipe, directly to the user. We agreed
that we must use a ‘trunk’ to carry the data. This ‘trunk’ will have a
fixed capacity and will not carry the entire data in one delivery.

After this short lesson, Giovanni asked me to implement some 
mercurial commands with my level 0 API, to show its purpose and 
mechanism.

Here are some examples for those commands:

- init command:

hg_handle *hg_init_by_hand()
{
pid_t cpid;
int status;
hg_handle *handle;
char command[50];
sprintf(command, "hg init %s", INIT_REPO);
if((cpid = fork()) < 0) {
printf("Fork failed\n");
return NULL;
} else if(cpid == 0) {
execl("/bin/sh", "sh", "-c", command, NULL);
printf("dadads\n\n");
} else {
waitpid( cpid, &status, 0);
}
handle = hg_open(INIT_REPO, "");
return handle;
}

- log command:

int hg_log_by_hand(hg_handle *handle)
{
char buff[4096];
char *comm[] = {"log", "-v"};
int exitcode;
hg_rawcommand(handle, comm, 2);
while(hg_rawread(handle, buff, 4096)){
printf("%s", buff);
}
if(hg_channel(handle) == 'r'){
exitcode = hg_exitcode(handle);
printf("exitcode = %d\n", exitcode);
}
return exitcode;

}

- verify command:

int hg_verify_by_hand(hg_handle *handle)
{
int exitcode = 0;
char *comm[] = {"verify"};
char buff[4096];
hg_rawcommand(handle, comm, 1);
while(hg_channel(handle) != 'r'){
if(hg_channel(handle) == 'o'){
hg_rawread(handle, buff, 4096);
printf("out = %s", buff);
}
else if(hg_channel(handle) == 'e'){
hg_rawread(handle, buff, 4096);
printf("err = %s", buff);
}
}
if(hg_channel(handle) == 'r'){
exitcode = hg_exitcode(handle);
printf("exitcode = %d\n", exitcode);
}
return exitcode;
}

You can find more of those commands on my bitbucket repository:

marți, 16 iulie 2013

#4 - C implementation of command server API

Last week I did a new brainstorming session and came up with a new API
header for the level 0, I wrote documentation for the functions,
explained for what arguments are needed and what the return value of
those functions is.


Meanwhile a new idea came up for some special commands which will be
implemented in the future, and how the level 0 function will handle
those commands. I believe that this will help me and lead me in the
same time towards a better viewpoint from where I´ll implement the API
easier.

At the end of the week I started again the implementation of the level
0 functions, according to the new API header.

I think that I am on the right path and will progress faster in the
upcoming weeks.

luni, 8 iulie 2013

#3 - C implementation of command server API

There was some progress last week on my project, but it's still a long
way to the finish. I started the week with some code refactoring and
with a new improvement: the runcommand can handle option arguments
now.

After I've sent a patchbomb to the mercurial-dev list, Matt asked me
to answer some questions and to think about some special commands
(log, merge and import), because those ones are a bit special. A
brainstorming session followed where I made a proposal, for how I
would like to deal with those commands.
At the end of the week I was waiting for some replies. In the meantime
I started to solve some issues from Bugzilla list of the mercurial
main project.