/* archive-setup.c:
*
* vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2
****************************************************************
* Copyright (C) 2003 Tom Lord
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "hackerlab/bugs/panic.h"
#include "hackerlab/bugs/exception.h"
#include "hackerlab/arrays/ar.h"
#include "hackerlab/char/str.h"
#include "hackerlab/vu/safe.h"
#include "libawk/associative.h"
#include "libarch/chatter.h"
#include "libarch/namespace.h"
#include "libarch/archive.h"
#include "libarch/tag.h"
#include "libarch/archive-cache.h"
#include "libarch/archive-setup.h"
/* __STDC__ prototypes for static functions */
static struct arch_archive * find_archive (struct arch_archive ** archs, t_uchar * name);
void
arch_setup_archive_simple (int chatter_fd,
t_uchar * archive_spec,
t_uchar * revision_spec)
{
rel_table wants = 0;
rel_add_records (&wants, rel_make_record (archive_spec, revision_spec, 0), 0);
arch_setup_archive (chatter_fd, wants, arch_archive_setup_no_tags, 0);
rel_free_table (wants);
}
/**
* \brief setup a branch in an archive somewhere
*
* TODO: FIXME-REMOVENAME give .._ext url + namespace elements,
* not registered-names. then we can change registered_name to location
* below
*/
void
arch_setup_archive_simple_ext (int chatter_fd,
struct arch_archive * arch,
t_uchar * revision_spec)
{
rel_table wants = 0;
rel_add_records (&wants, rel_make_record (arch->registered_name, revision_spec, 0), 0);
arch_setup_archive_ext (chatter_fd, wants, arch_archive_setup_no_tags, 0, arch);
rel_free_table (wants);
}
void
arch_setup_archive (int chatter_fd, rel_table wants, enum arch_archive_setup_tag_op tag_op, int archive_cache)
{
arch_setup_archive_ext (chatter_fd, wants, tag_op, archive_cache, NULL);
}
static void
arch_archive_populate_fqcategory_exists (struct arch_archive *arch, assoc_table * fqcategory_exists)
{
int c;
rel_table categories = arch_archive_categories (arch);
for (c = 0; c < rel_n_records (categories); ++c)
{
t_uchar * cat = 0;
cat = arch_fully_qualify (arch->official_name, categories[c][0]);
assoc_set (fqcategory_exists, cat, "yes");
lim_free (0, cat);
}
rel_free_table (categories);
}
void
arch_setup_archive_ext (int chatter_fd, rel_table wants, enum arch_archive_setup_tag_op tag_op, int archive_cache, struct arch_archive * initial_arch)
{
t_uchar * errstr = 0;
struct arch_archive ** archs = 0;
assoc_table fqcategories_checked = 0;
assoc_table fqbranches_checked = 0;
assoc_table fqcategory_exists = 0;
assoc_table fqbranch_exists = 0;
assoc_table fqversion_exists = 0;
int x;
if (initial_arch)
ar_push_arch_archive (&archs, initial_arch);
for (x = 0; x < rel_n_records (wants); ++x)
{
t_uchar * archive;
struct arch_archive * arch = 0;
t_uchar * spec;
t_uchar * category = 0;
t_uchar * fqcategory = 0;
archive = wants[x][0];
arch = find_archive (archs, archive);
if (!arch)
{
arch = arch_archive_connect_branch (archive, NULL);
if (!arch)
{
safe_printfmt (2, "Could not connect to archive %s ", archive);
exit (2);
}
ar_push_arch_archive (&archs, arch);
arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
}
if (!fqcategory_exists)
arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
spec = wants[x][1];
category = arch_parse_package_name (arch_ret_category, 0, spec);
fqcategory = arch_fully_qualify (arch->official_name, category);
if (arch->type != arch_archive_baz && !assoc_ref (fqcategory_exists, fqcategory))
{
arch_chatter (chatter_fd, "* creating category %s/%s\n", arch->official_name, category);
if (arch_make_category (&errstr, arch, category))
{
safe_printfmt (2, "archive-setup: error making category %s/%s in %s (%s)\n", arch->official_name, category, arch->location, errstr);
exit (1);
}
assoc_set (&fqcategory_exists, fqcategory, "yes");
}
if (str_cmp (spec, category))
{
if (arch_valid_package_name (spec, arch_no_archive, arch_req_package, 1))
{
t_uchar * branch = 0;
t_uchar * fqbranch = 0;
branch = arch_parse_package_name (arch_ret_package, 0, spec);
fqbranch = arch_fully_qualify (arch->official_name, branch);
if (!assoc_ref (fqcategories_checked, fqcategory))
{
rel_table branches = 0;
int b;
branches = arch_archive_branches (arch, category);
for (b = 0; b < rel_n_records (branches); ++b)
{
t_uchar * bran = 0;
bran = arch_fully_qualify (arch->official_name, branches[b][0]);
assoc_set (&fqbranch_exists, bran, "yes");
lim_free (0, bran);
}
rel_free_table (branches);
}
if (arch->type != arch_archive_baz && !assoc_ref (fqbranch_exists, fqbranch))
{
arch_chatter (chatter_fd, "* creating branch %s/%s\n", arch->official_name, branch);
if (arch_make_branch (&errstr, arch, branch))
{
safe_printfmt (2, "archive-setup: error making branch %s/%s (%s)\n", arch->official_name, branch, errstr);
exit (1);
}
assoc_set (&fqbranch_exists, fqbranch, "yes");
}
if (arch_valid_package_name (spec, arch_no_archive, arch_req_version, 0))
{
t_uchar * version = 0;
t_uchar * fqversion = 0;
version = arch_parse_package_name (arch_ret_package_version, 0, spec);
fqversion = arch_fully_qualify (arch->official_name, version);
if (!assoc_ref (fqbranches_checked, fqbranch))
{
rel_table versions = 0;
int v;
versions = arch_archive_versions (arch, branch);
for (v = 0; v < rel_n_records (versions); ++v)
{
t_uchar * vers = 0;
vers = arch_fully_qualify (arch->official_name, versions[v][0]);
assoc_set (&fqversion_exists, vers, "yes");
lim_free (0, vers);
}
rel_free_table (versions);
}
if (!assoc_ref (fqversion_exists, fqversion))
{
arch_chatter (chatter_fd, "* creating version %s/%s\n", arch->official_name, version);
if (arch_make_version (&errstr, arch, version))
{
safe_printfmt (2, "archive-setup: error making version %s/%s (%s)\n", arch->official_name, version, errstr);
exit (1);
}
assoc_set (&fqversion_exists, fqversion, "yes");
}
if (tag_op != arch_archive_setup_no_tags)
{
rel_table has_revisions = 0;
t_uchar * tag_from_archive;
t_uchar * tag_from_rev_spec;
struct arch_archive * from_arch = 0;
t_uchar * tag_from_version = 0;
rel_table from_has_revisions = 0;
arch_chatter (chatter_fd, "* creating tag in %s/%s\n", arch->official_name, version);
has_revisions = arch_archive_revisions (arch, version, 0);
tag_from_archive = wants[x][2];
tag_from_rev_spec = wants[x][3];
from_arch = find_archive (archs, tag_from_archive);
if (!from_arch)
{
/* FIXME-REMOVENAME use the namespace out facility */
from_arch = arch_archive_connect_branch (tag_from_archive, NULL);
if (!arch)
{
safe_printfmt (2, "Could not connect to archive %s ", archive);
exit (2);
}
ar_push_arch_archive (&archs, from_arch);
}
tag_from_version = arch_parse_package_name (arch_ret_package_version, 0, tag_from_rev_spec);
from_has_revisions = arch_archive_revisions (from_arch, tag_from_version, 0);
switch (tag_op)
{
default:
{
panic ("archive-setup.c internal error");
break;
}
case arch_archive_setup_make_base0_tag:
{
if (has_revisions)
arch_chatter (chatter_fd, " ...skipping, base-0 already exists");
else
{
t_uchar * tag_revision = 0;
t_uchar * tag_from_revision = 0;
tag_revision = str_alloc_cat (0, version, "--base-0");
if (arch_valid_package_name (tag_from_rev_spec, 0, arch_req_patch_level, 0))
tag_from_revision = arch_parse_package_name (arch_ret_non_archive, 0, tag_from_rev_spec);
else if (from_has_revisions)
tag_from_revision = str_alloc_cat_many (0, tag_from_version, "--", from_has_revisions[rel_n_records (from_has_revisions) - 1][0], str_end);
if (tag_from_revision)
{
tag_method_t * tag = arch_tag (talloc_context, chatter_fd, arch, tag_revision, from_arch, tag_from_revision, 0);
if (archive_cache)
arch_tag_cacherev (tag);
talloc_free (tag);
}
lim_free (0, tag_from_revision);
lim_free (0, tag_revision);
}
break;
}
}
rel_free_table (has_revisions);
lim_free (0, tag_from_version);
rel_free_table (from_has_revisions);
}
lim_free (0, version);
lim_free (0, fqversion);
}
lim_free (0, branch);
lim_free (0, fqbranch);
}
}
lim_free (0, category);
lim_free (0, fqcategory);
}
for (x = 0; x < ar_size_arch_archive (archs); ++x)
if (archs[x] != initial_arch)
arch_archive_close (archs[x]);
ar_free_arch_archive (&archs);
free_assoc_table (fqcategories_checked);
free_assoc_table (fqbranches_checked);
free_assoc_table (fqcategory_exists);
free_assoc_table (fqbranch_exists);
free_assoc_table (fqversion_exists);
}
/**
* \brief find an archive in the local cache.
*
* TODO, FIXME-REMOVENAME - replace registered_name with location here,
* and in all callers.
*/
static struct arch_archive *
find_archive (struct arch_archive ** archs, t_uchar * name)
{
int x;
for (x = 0; x < ar_size_arch_archive (archs); ++x)
if (!str_cmp (name, archs[x]->registered_name))
return archs[x];
return 0;
}
/* tag: Tom Lord Wed Jun 11 11:58:43 2003 (archive-setup.c)
*/
syntax highlighted by Code2HTML, v. 0.9.1