← Back to team overview

quickly-talk team mailing list archive

Proposal: Abstract hosting service from project templates.

 

Hi,

Further to discussion in #quickly earlier, here is my proposal for why
I believe that hosting service (eg Launchpad or Github or Sourceforge
etc) and the corresponding VCS stuff should be abstracted from the
project templates by more than just the simple inheritance we have
now. This is mostly counters to objections raised...



Summary:

When making a new project with Quickly, it should pull in two
templates instead of one. The first template should be selected by the
user exactly like it is now. The second template should silently
default to "ubuntu-hosting" and it should contain the implementation
of Quickly commands which deal with project hosting only, and no
boilerplate code. The second template can be overridden by the user to
select a different hosting service.

To a user who is ignorant of the various hosting services, this is
completely invisible. This does not change the functionality of
Quickly at all, as it can already support different hosting services.
This proposal only makes it easier for template developers to support
different hosting services without duplicating work. In turn that
should increase the number of templates available for users.


I can:

quickly create <any-template>
     make a launchpad backed <any-template>-type project.
quickly release
     ask for my launchpad credentials and upload code to my bzr repo
     and deb to my PPA

I should also be able to:

quickly create <any-template> --hosting=github
     make a github backed <any-template>-type project.
quickly release
     ask for my github credentials and upload code to my git repo and
     deb to downloads area.



Quickly templates and why they should be split into two parts:

Quickly has a template system which serves as a basis for new
projects. I can fork the base template and change it to use git/github
or hg/bitbucked instead of bzr/launchpad. That's not a problem even
under the existing Quickly template system[1]. The problem comes in
maintaining templates that inherit from base. For every template the
inherits directly or indirectly from base, I have to maintain an exact
copy which inherits from my fork. This literally means a 1 line change
and then keeping the rest of the files in sync forever. That's
basically not going to happen, so in the current system, the user's
choice of templates is limited by their choice of hosting service.

[1] see https://github.com/ali1234/quickly-git-templates

Currently the inheritance tree looks like this (fixed width font required):

         ubuntu-app
        /  |  |  | \
ubuntu-cli |  |  |  |
  ubuntu-html |  |  bitbucket-app...
    ubuntu-flash |
                 github-app
                 |  |  |
        github-cli  |  |
          github-html  |
            github-flash

github-cli is an exact copy of ubuntu-cli except for 1 line, but is
not able to inherit anything from it, and does not even know that it
exists. Also note that this inheritance tree grows exponentially as
the number of hosting systems and project types increases. To support
3 hosting servies and 3 project types you need 9 templates and a large
amount of duplicated template code.

Now supposing I make some unique template. Since I like git, I'll base
it off my forked github templates. The majority of Quickly users who
are using Launchpad will not be able to use my work. I don't want
that, but I am not willing to maintain two copies of 99% identical
code, and so I'm going to just make the version that I need. It
doesn't have to be this way.


How it should work instead:

Hosting type:          Project Type:

ubuntu-hosting              generic-app
     |                       |  |  |
github-hosting     generic-cli  |  generic-html
                          generic-flash

When creating a project you select the hosting type and project type you want:

ubuntu-hosting + generic-app = ubuntu-app
github-hosting + generic-cli = github-cli
... or any other combination you want!

If you didn't ask for a specific hosting type, you would get
Ubuntu/Launchpad/bzr hosting. So the result would be exactly the same
as it is now. It is just much less of a headache for template
developers. To support 3 hosts and 3 project types you only need 6
"half" templates. They are "half" because 3 of them only deal with
hosting and 3 only deal with project types. There is no duplicated
code.



Why should it be split this way? Why not abstract build system, or
packaging system?

To date no template (that I know of, and except for my own
proof-of-concept fork) has modified the hosting and VCS commands. This
just goes to show that there is clear separation between the hosting
system and the project files/boilerplate/build system parts of the
template.

Changing the build system necessitates changing the project
boilerplate - that is eg. switching between make and cmake requires
CMakelists.txt instead of Makefile. Changing the packaging system has
similar requirements. Changing the hosting service or VCS type does
not affect the contents of the repository at all.

Also, if there were a split between project type and build system,
then not all combinations could work together. A C++ project built by
a setup.py makes no sense. Same for packaging: a Windows C
application[2] packaged in an RPM makes no sense. However, any hosting
service can host any type of project, so any hosting-template should
be compatible with any project-template.

Even if Quickly did support multiple packaging types (and I'm not
suggesting it should or shouldn't), I wouldn't want to pick just one.
I would want to build packages for as many different systems as my
project can support. Again, that's strongly coupled to the
project-type, and so this belongs with the other project-specific
code, not in a separate user-selectable template.

[2] Yes, even the existing Quickly implementation could easily support
a template for developing Windows C applications under Ubuntu.



What about release/submitubuntu?

Any code hosting provider has a system for hosting compiled binaries
which can handle debs, tarballs or whatever you want. It's not a PPA,
but it is functionally equivalent for the purposes of what Quickly
actually does, which is upload the deb somewhere where other people
can get at it. This doesn't have to be specific to sites like github
or sourceforge even. A template could push code to a remote VCS,
upload the deb, and kick off makerepo, all over ssh to your own
personal webserver, for a totally self-hosted solution.

That would work with all existing Quickly commands except for one:
submitubuntu. That is going to be harder to implement for other
hosting providers, but not impossible. However, since nothing depends
on submitubuntu, there's no reason why hosting templates other than
launchpad-hosting would even need to implement it. There's certainly
nothing in the existing Quickly templates that requires all templates
to implement all commands...



But VCS abstraction is doomed to failure.

It does not need to be a complete perfect abstraction of all VCS
systems. It is only necessary to abstract the subset of features which
Quickly actually uses, which is a fairly small subset. Quickly is
already a VCS abstraction in this sense because you don't need to do
any direct VCS commands to use it.



"do not make the template more difficult to write/maintain"

It does not. All you have to do is move some commands into a different
template, one time, for the base template. After that, writing new
templates is easier if you don't want to use Launchpad, or exactly the
same if you do.



"do not ask additional question to the users"

It does not. User won't even know this feature exists unless they
specifically request it when creating a project.

Contrast with how it works now: User already has to choose a hoster
but it is an implicit choice, and it requires the user to find a
template which has the right combination of host and project type that
they want. So currently this is a question which Quickly puts to the
user, but which is difficult for the user to answer (or even realise
they are even being asked.) Under my proposal the choice would be
explicit but optional instead of implicit but mandatory, and all
possible selections would be available for all project types.



"do not prevent some integration"

This does not prevent any template from implementing any commands that
it wants to, as long as there are no conflicts, and some bare minimum
requirements are implemented - eg save, build etc. - things that all
templates should have anyway.



Final Thought: Make it easy or make it impossible.

If you still don't want to support different hosting systems, then
fine. In that case it should be moved out of the project templates and
hardcoded into Quickly core - but doing that would require creating an
abstraction layer virtually identical to the one I am proposing.


-- 
Alistair Buxton
a.j.buxton@xxxxxxxxx


Follow ups