csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
#include "rpmsystem-py.h"
2ff057
2ff057
#include "header-py.h"
2ff057
#include "spec-py.h"
2ff057
2ff057
/** \ingroup python
2ff057
 * \name Class: Rpmspec
2ff057
 * \class Rpmspec
2ff057
 * \brief A python rpm.spec object represents an RPM spec file set.
2ff057
 * 
2ff057
 *  The spec file is at the heart of RPM's packaging building process. Similar
2ff057
 *  in concept to a makefile, it contains information required by RPM to build
2ff057
 *  the package, as well as instructions telling RPM how to build it. The spec
2ff057
 *  file also dictates exactly what files are a part of the package, and where
2ff057
 *  they should be installed.
2ff057
 *  
2ff057
 *  The rpm.spec object represents a parsed specfile to aid extraction of data.
2ff057
 *  
2ff057
 *  For example
2ff057
 * \code
2ff057
 *  import rpm
2ff057
 *  rpm.rpmPushMacro("_topdir","/path/to/topdir")
2ff057
 *  s=rpm.spec("foo.spec")
2ff057
 *  print(s.prep)
2ff057
 * \endcode
2ff057
 *
2ff057
 *  Macros set using add macro will be used allowing testing of conditional builds
2ff057
 *
2ff057
 */
2ff057
2ff057
/* Header objects are in another module, some hoop jumping required... */
2ff057
static PyObject *makeHeader(Header h)
2ff057
{
2ff057
    PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
2ff057
    if (rpmmod == NULL) return NULL;
2ff057
2ff057
    PyObject *ptr = CAPSULE_BUILD(h, "rpm._C_Header");
2ff057
    PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
2ff057
    Py_XDECREF(ptr);
2ff057
    Py_XDECREF(rpmmod);
2ff057
    return hdr;
2ff057
}
2ff057
2ff057
struct specPkgObject_s {
2ff057
    PyObject_HEAD
2ff057
    /*type specific fields */
2ff057
    rpmSpecPkg pkg;
2ff057
    specObject *source_spec;
2ff057
};
2ff057
2ff057
static void specPkg_dealloc(specPkgObject * s)
2ff057
{
2ff057
    Py_DECREF(s->source_spec);
2ff057
}
2ff057
2ff057
static PyObject *pkgGetSection(rpmSpecPkg pkg, int section)
2ff057
{
2ff057
    char *sect = rpmSpecPkgGetSection(pkg, section);
2ff057
    if (sect != NULL) {
2ff057
        PyObject *ps = PyBytes_FromString(sect);
2ff057
        free(sect);
2ff057
        if (ps != NULL)
2ff057
            return ps;
2ff057
    }
2ff057
    Py_RETURN_NONE;
2ff057
}
2ff057
2ff057
static char specPkg_doc[] =
2ff057
"Package data parsed from spec file.";
2ff057
2ff057
static PyObject * specpkg_get_header(specPkgObject *s, void *closure)
2ff057
{
2ff057
    return makeHeader(rpmSpecPkgHeader(s->pkg));
2ff057
}
2ff057
2ff057
static PyObject * specpkg_get_fileFile(specPkgObject *s, void *closure)
2ff057
{
2ff057
    return  pkgGetSection(s->pkg, RPMBUILD_FILE_FILE);
2ff057
}
2ff057
2ff057
static PyObject * specpkg_get_fileList(specPkgObject *s, void *closure)
2ff057
{
2ff057
    return  pkgGetSection(s->pkg, RPMBUILD_FILE_LIST);
2ff057
}
2ff057
2ff057
static PyObject * specpkg_get_policyList(specPkgObject *s, void *closure)
2ff057
{
2ff057
    return  pkgGetSection(s->pkg, RPMBUILD_POLICY);
2ff057
}
2ff057
2ff057
static PyGetSetDef specpkg_getseters[] = {
2ff057
    { "header",     (getter) specpkg_get_header,     NULL, NULL },
2ff057
    { "fileFile",   (getter) specpkg_get_fileFile,   NULL, NULL },
2ff057
    { "fileList",   (getter) specpkg_get_fileList,   NULL, NULL },
2ff057
    { "policyList", (getter) specpkg_get_policyList, NULL, NULL },
2ff057
    { NULL }   /* sentinel */
2ff057
};
2ff057
2ff057
PyTypeObject specPkg_Type = {
2ff057
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
2ff057
	"rpm.specpkg",			/* tp_name */
2ff057
	sizeof(specPkgObject),		/* tp_size */
2ff057
	0,				/* tp_itemsize */
2ff057
	(destructor) specPkg_dealloc, 	/* tp_dealloc */
2ff057
	0,				/* tp_print */
2ff057
	0, 				/* tp_getattr */
2ff057
	0,				/* tp_setattr */
2ff057
	0,				/* tp_compare */
2ff057
	0,				/* tp_repr */
2ff057
	0,				/* tp_as_number */
2ff057
	0,				/* tp_as_sequence */
2ff057
	0,				/* tp_as_mapping */
2ff057
	0,				/* tp_hash */
2ff057
	0,				/* tp_call */
2ff057
	0,				/* tp_str */
2ff057
	PyObject_GenericGetAttr,	/* tp_getattro */
2ff057
	PyObject_GenericSetAttr,	/* tp_setattro */
2ff057
	0,				/* tp_as_buffer */
2ff057
	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,	/* tp_flags */
2ff057
	specPkg_doc,			/* tp_doc */
2ff057
	0,				/* tp_traverse */
2ff057
	0,				/* tp_clear */
2ff057
	0,				/* tp_richcompare */
2ff057
	0,				/* tp_weaklistoffset */
2ff057
	0,				/* tp_iter */
2ff057
	0,				/* tp_iternext */
2ff057
	0,				/* tp_methods */
2ff057
	0,				/* tp_members */
2ff057
	specpkg_getseters,		/* tp_getset */
2ff057
	0,				/* tp_base */
2ff057
	0,				/* tp_dict */
2ff057
	0,				/* tp_descr_get */
2ff057
	0,				/* tp_descr_set */
2ff057
	0,				/* tp_dictoffset */
2ff057
	0,				/* tp_init */
2ff057
	0,				/* tp_alloc */
2ff057
	0,				/* tp_new */
2ff057
	0,				/* tp_free */
2ff057
	0,				/* tp_is_gc */
2ff057
};
2ff057
2ff057
struct specObject_s {
2ff057
    PyObject_HEAD
2ff057
    /*type specific fields */
2ff057
    rpmSpec spec;
2ff057
};
2ff057
2ff057
static void 
2ff057
spec_dealloc(specObject * s) 
2ff057
{
2ff057
    if (s->spec) {
2ff057
	s->spec=rpmSpecFree(s->spec);
2ff057
    }
2ff057
    Py_TYPE(s)->tp_free((PyObject *)s);
2ff057
}
2ff057
2ff057
static PyObject * getSection(rpmSpec spec, int section)
2ff057
{
2ff057
    const char *sect = rpmSpecGetSection(spec, section);
2ff057
    if (sect) {
2ff057
	return Py_BuildValue("s", sect);
2ff057
    }
2ff057
    Py_RETURN_NONE;
2ff057
}
2ff057
2ff057
static PyObject *
2ff057
spec_get_parsed(specObject * s, void *closure)
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_NONE);
2ff057
}
2ff057
2ff057
static PyObject * 
2ff057
spec_get_prep(specObject * s, void *closure) 
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_PREP);
2ff057
}
2ff057
2ff057
static PyObject * 
2ff057
spec_get_build(specObject * s, void *closure) 
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_BUILD);
2ff057
}
2ff057
2ff057
static PyObject * spec_get_install(specObject * s, void *closure) 
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_INSTALL);
2ff057
}
2ff057
2ff057
static PyObject * spec_get_check(specObject * s, void *closure)
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_CHECK);
2ff057
}
2ff057
2ff057
static PyObject * spec_get_clean(specObject * s, void *closure) 
2ff057
{
2ff057
    return getSection(s->spec, RPMBUILD_CLEAN);
2ff057
}
2ff057
2ff057
static PyObject * spec_get_sources(specObject *s, void *closure)
2ff057
{
2ff057
    PyObject *sourceList;
2ff057
    rpmSpecSrc source;
2ff057
2ff057
    sourceList = PyList_New(0);
2ff057
    if (!sourceList) {
2ff057
        return NULL;
2ff057
    }
2ff057
2ff057
    rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
2ff057
    while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
2ff057
	PyObject *srcUrl = Py_BuildValue("(sii)",
2ff057
				rpmSpecSrcFilename(source, 1),
2ff057
				rpmSpecSrcNum(source),
2ff057
				rpmSpecSrcFlags(source)); 
2ff057
        if (!srcUrl) {
2ff057
            Py_DECREF(sourceList);
2ff057
            return NULL;
2ff057
        }
2ff057
	PyList_Append(sourceList, srcUrl);
2ff057
	Py_DECREF(srcUrl);
2ff057
    } 
2ff057
    rpmSpecSrcIterFree(iter);
2ff057
2ff057
    return sourceList;
2ff057
2ff057
}
2ff057
2ff057
static PyObject * spec_get_packages(specObject *s, void *closure)
2ff057
{
2ff057
    rpmSpecPkg pkg;
2ff057
    PyObject *pkgList;
2ff057
    rpmSpecPkgIter iter;
2ff057
2ff057
    pkgList = PyList_New(0);
2ff057
    if (!pkgList) {
2ff057
        return NULL;
2ff057
    }
2ff057
2ff057
    iter = rpmSpecPkgIterInit(s->spec);
2ff057
2ff057
    while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
2ff057
	PyObject *po = specPkg_Wrap(&specPkg_Type, pkg, s);
2ff057
        if (!po) {
2ff057
            rpmSpecPkgIterFree(iter);
2ff057
            Py_DECREF(pkgList);
2ff057
            return NULL;
2ff057
        }
2ff057
	PyList_Append(pkgList, po);
2ff057
	Py_DECREF(po);
2ff057
    }
2ff057
    rpmSpecPkgIterFree(iter);
2ff057
    return pkgList;
2ff057
}
2ff057
2ff057
static PyObject * spec_get_source_header(specObject *s, void *closure)
2ff057
{
2ff057
    return makeHeader(rpmSpecSourceHeader(s->spec));
2ff057
}
2ff057
2ff057
static char spec_doc[] = "RPM Spec file object";
2ff057
2ff057
static PyGetSetDef spec_getseters[] = {
2ff057
    {"sources",   (getter) spec_get_sources, NULL, NULL },
2ff057
    {"parsed",    (getter) spec_get_parsed, NULL, NULL},
2ff057
    {"prep",   (getter) spec_get_prep, NULL, NULL },
2ff057
    {"build",   (getter) spec_get_build, NULL, NULL },
2ff057
    {"install",   (getter) spec_get_install, NULL, NULL },
2ff057
    {"check",	(getter) spec_get_check, NULL, NULL },
2ff057
    {"clean",   (getter) spec_get_clean, NULL, NULL },
2ff057
    {"packages", (getter) spec_get_packages, NULL, NULL },
2ff057
    {"sourceHeader", (getter) spec_get_source_header, NULL, NULL },
2ff057
    {NULL}  /* Sentinel */
2ff057
};
2ff057
2ff057
static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
2ff057
{
2ff057
    char * kwlist[] = {"specfile", "flags", NULL};
2ff057
    const char * specfile;
2ff057
    rpmSpec spec = NULL;
2ff057
    /* XXX This is a dumb default but anything else breaks compatibility... */
2ff057
    rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
2ff057
2ff057
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:spec_new", kwlist,
2ff057
				     &specfile, &flags))
2ff057
	return NULL;
2ff057
2ff057
    spec = rpmSpecParse(specfile, flags, NULL);
2ff057
    if (spec == NULL) {
2ff057
	PyErr_SetString(PyExc_ValueError, "can't parse specfile\n");
2ff057
	return NULL;
2ff057
    }
2ff057
2ff057
    return spec_Wrap(subtype, spec);
2ff057
}
2ff057
2ff057
static PyObject * spec_doBuild(specObject *self, PyObject *args, PyObject *kwds)
2ff057
{
2ff057
    char * kwlist[] = { "buildAmount", "pkgFlags", NULL };
2ff057
    struct rpmBuildArguments_s ba = { 0 };
2ff057
2ff057
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:spec_doBuild",
2ff057
			kwlist, &ba.buildAmount, &ba.pkgFlags))
2ff057
	return NULL;
2ff057
2ff057
    return PyBool_FromLong(rpmSpecBuild(self->spec, &ba) == RPMRC_OK);
2ff057
}
2ff057
2ff057
static struct PyMethodDef spec_methods[] = {
2ff057
    { "_doBuild", (PyCFunction)spec_doBuild, METH_VARARGS|METH_KEYWORDS, NULL },
2ff057
    { NULL, NULL }
2ff057
};
2ff057
2ff057
PyTypeObject spec_Type = {
2ff057
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
2ff057
    "rpm.spec",               /*tp_name*/
2ff057
    sizeof(specObject),        /*tp_basicsize*/
2ff057
    0,                         /*tp_itemsize*/
2ff057
    (destructor) spec_dealloc, /*tp_dealloc*/
2ff057
    0,                         /*tp_print*/
2ff057
    0,                         /*tp_getattr*/
2ff057
    0,                         /*tp_setattr*/
2ff057
    0,                         /*tp_compare*/
2ff057
    0,                         /*tp_repr*/
2ff057
    0,                         /*tp_as_number*/
2ff057
    0,                         /*tp_as_sequence*/
2ff057
    0,                         /*tp_as_mapping*/
2ff057
    0,                         /*tp_hash */
2ff057
    0,                         /*tp_call*/
2ff057
    0,                         /*tp_str*/
2ff057
    0,                         /*tp_getattro*/
2ff057
    0,                         /*tp_setattro*/
2ff057
    0,                         /*tp_as_buffer*/
2ff057
    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
2ff057
    spec_doc,                  /* tp_doc */
2ff057
    0,                         /* tp_traverse */
2ff057
    0,                         /* tp_clear */
2ff057
    0,                         /* tp_richcompare */
2ff057
    0,                         /* tp_weaklistoffset */
2ff057
    0,                         /* tp_iter */
2ff057
    0,                         /* tp_iternext */
2ff057
    spec_methods,	       /* tp_methods */
2ff057
    0,                         /* tp_members */
2ff057
    spec_getseters,            /* tp_getset */
2ff057
    0,                         /* tp_base */
2ff057
    0,                         /* tp_dict */
2ff057
    0,                         /* tp_descr_get */
2ff057
    0,                         /* tp_descr_set */
2ff057
    0,                         /* tp_dictoffset */
2ff057
    0,                         /* tp_init */
2ff057
    0,                         /* tp_alloc */
2ff057
    spec_new,                  /* tp_new */
2ff057
    0,                         /* tp_free */
2ff057
    0,                         /* tp_is_gc */
2ff057
};
2ff057
2ff057
PyObject *
2ff057
spec_Wrap(PyTypeObject *subtype, rpmSpec spec) 
2ff057
{
2ff057
    specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
2ff057
    if (s == NULL) return NULL;
2ff057
2ff057
    s->spec = spec; 
2ff057
    return (PyObject *) s;
2ff057
}
2ff057
2ff057
PyObject * specPkg_Wrap(PyTypeObject *subtype, rpmSpecPkg pkg, specObject *source)
2ff057
{
2ff057
    specPkgObject * s = (specPkgObject *)subtype->tp_alloc(subtype, 0);
2ff057
    if (s == NULL) return NULL;
2ff057
2ff057
    s->pkg = pkg;
2ff057
    s->source_spec = source;
2ff057
    Py_INCREF(s->source_spec);
2ff057
    return (PyObject *) s;
2ff057
}
2ff057