Forums | Admin

Discussion Forums: open-discussion

Start New Thread Start New Thread


By: Tom Copeland
RE: add functional layer to rubyforge api [ reply ]  
2009-09-03 20:26
Hi 7rans -

I agree completely. I was emailing with the gentoo guys and they're using Net::HTTP to hit /mirrors to get the mirror list. But it would be so much nicer if they could just do:"user","pass").mirrors

and get back a nice Hash.

I'm not sure whether this would be a new gem or a refactoring of the current rubyforge gem. I'd prefer the latter for the nice gem name...



By: 7rans
add functional layer to rubyforge api [ reply ]  
2009-08-28 02:00
Looked over the rubyforge api code a few days back. I'm glad to see this is coming along.

I have one significant issue I'd like to see addressed. I'd like to see an extra layer of code separation in the design. Right now the calls are tightly tied into how rubyforge qua execuable handles configuration. In other words I'd like to see a clean functional layer below the current one --something others can use to easily interact with Rubyforge if they wish to do so in a way other then how the rubyforge program does.

Let me give an specific example to be clear. In the code:

def add_release(group_id, package_id, release_name, *files)
group_id = lookup "group", group_id
package_id = lookup "package", package_id
release_date = @userconfig["release_date"]
release_notes = @userconfig["release_notes"]
release_changes = @userconfig["release_changes"]
preformatted = @userconfig["preformatted"]

Notice the settings release_* are being pulled from @userconfig. This function ends by calling #run. In #run we see:

def run(page, form, extheader={}) # :nodoc:
uri = self.uri + page
puts "client.post_content #{uri.inspect}, #{form.inspect}, #{extheader.inspect}" if $DEBUG
response = client.post_content uri, form, extheader, @userconfig
puts response if $DEBUG

And here we see the whole of @userconfig being passed to the backend client. This is tight coupling, as well as redundant. It would be cleaner to create a completely separate layer as a superclass of the current one that defines something like:

def add_release(group_id, package_id, release_name, config, *files)
group_id = group_id
package_id = package_id
release_date = config["release_date"]
release_notes = config["release_notes"]
release_changes = config["release_changes"]
preformatted = config["preformatted"]

And likewise for #run, that does not depend on any global config, but rather must receive all relevant parameters via the method interface.

The separation should be clean enough that conceivably we could create a 'rubyforge-api' gem that the 'rubyforge' gem depends on (though separate gems are not necessary, I'm just clarifying the point about the clean code separation).