#include "rpmsystem-py.h"
+#include "header-py.h"
#include "spec-py.h"
/** \ingroup python
* \code
* import rpm
* rpm.addMacro("_topdir","/path/to/topdir")
- * ts=rpm.ts()
- * s=ts.parseSpec("foo.spec")
+ * s=rpm.spec("foo.spec")
* print s.prep()
* \endcode
*
*
*/
+/* Header objects are in another module, some hoop jumping required... */
+static PyObject *makeHeader(Header h)
+{
+ PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
+ if (rpmmod == NULL) return NULL;
+
+ PyObject *ptr = CAPSULE_BUILD(h, "rpm._C_Header");
+ PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
+ Py_XDECREF(ptr);
+ Py_XDECREF(rpmmod);
+ return hdr;
+}
+
+struct specPkgObject_s {
+ PyObject_HEAD
+ /*type specific fields */
+ rpmSpecPkg pkg;
+};
+
+static char specPkg_doc[] =
+"";
+
+static PyObject * specpkg_get_header(specPkgObject *s, void *closure)
+{
+ return makeHeader(rpmSpecPkgHeader(s->pkg));
+}
+
+static PyGetSetDef specpkg_getseters[] = {
+ { "header", (getter) specpkg_get_header, NULL, NULL },
+ { NULL } /* sentinel */
+};
+
+PyTypeObject specPkg_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "rpm.specpkg", /* tp_name */
+ sizeof(specPkgObject), /* tp_size */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
+ specPkg_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ specpkg_getseters, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+};
+
struct specObject_s {
PyObject_HEAD
/*type specific fields */
static void
spec_dealloc(specObject * s)
{
- if (s->spec) {
- s->spec=freeSpec(s->spec);
- }
- PyObject_Del(s);
+ if (s->spec) {
+ s->spec=rpmSpecFree(s->spec);
+ }
+ Py_TYPE(s)->tp_free((PyObject *)s);
}
-static int
-spec_print(specObject * s)
+static PyObject * getSection(rpmSpec spec, int section)
{
- return 0;
+ const char *sect = rpmSpecGetSection(spec, section);
+ if (sect) {
+ return Py_BuildValue("s", sect);
+ }
+ Py_RETURN_NONE;
}
-/* XXX TODO return something sensible if spec exists but component (eg %clean)
- * does not. Possibly "" or None */
-
static PyObject *
-spec_get_buildroot(specObject * s)
+spec_get_prep(specObject * s, void *closure)
{
- rpmSpec spec = specFromSpec(s);
- if (spec != NULL && spec->buildRoot) {
- return Py_BuildValue("s", spec->buildRoot);
- }
- else {
- return NULL;
- }
+ return getSection(s->spec, RPMBUILD_PREP);
}
static PyObject *
-spec_get_prep(specObject * s)
+spec_get_build(specObject * s, void *closure)
{
- rpmSpec spec = specFromSpec(s);
- PyObject *res = NULL;
- if (spec != NULL && spec->prep) {
- res = Py_BuildValue("s",getStringBuf(spec->prep));
- }
- return res;
+ return getSection(s->spec, RPMBUILD_BUILD);
}
-static PyObject *
-spec_get_build(specObject * s)
+static PyObject * spec_get_install(specObject * s, void *closure)
{
- rpmSpec spec = specFromSpec(s);
- PyObject *res = NULL;
- if (spec != NULL && spec->build) {
- res = Py_BuildValue("s",getStringBuf(spec->build));
- }
- return res;
+ return getSection(s->spec, RPMBUILD_INSTALL);
}
-static PyObject *
-spec_get_install(specObject * s)
+static PyObject * spec_get_clean(specObject * s, void *closure)
{
- rpmSpec spec = specFromSpec(s);
- PyObject *res = NULL;
- if (spec != NULL && spec->install) {
- res = Py_BuildValue("s",getStringBuf(spec->install));
- }
- return res;
+ return getSection(s->spec, RPMBUILD_CLEAN);
}
-static PyObject *
-spec_get_clean(specObject * s)
+static PyObject * spec_get_sources(specObject *s, void *closure)
{
- rpmSpec spec = specFromSpec(s);
- PyObject *res = NULL;
- if (spec != NULL && spec->clean) {
- res = Py_BuildValue("s",getStringBuf(spec->clean));
+ PyObject *sourceList;
+ rpmSpecSrc source;
+
+ sourceList = PyList_New(0);
+ if (!sourceList) {
+ return NULL;
}
- return res;
+
+ rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
+ while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
+ PyObject *srcUrl = Py_BuildValue("(sii)",
+ rpmSpecSrcFilename(source, 1),
+ rpmSpecSrcNum(source),
+ rpmSpecSrcFlags(source));
+ if (!srcUrl) {
+ Py_DECREF(sourceList);
+ return NULL;
+ }
+ PyList_Append(sourceList, srcUrl);
+ Py_DECREF(srcUrl);
+ }
+ rpmSpecSrcIterFree(iter);
+
+ return sourceList;
+
}
-static PyObject *
-spec_get_sources(specObject *s)
+static PyObject * spec_get_packages(specObject *s, void *closure)
{
- struct Source * source;
- PyObject *sourceList, *srcUrl;
- rpmSpec spec;
- char * fullSource;
+ rpmSpecPkg pkg;
+ PyObject *pkgList;
+ rpmSpecPkgIter iter;
- sourceList = PyList_New(0);
- spec = specFromSpec(s);
- if ( spec != NULL) {
- source = spec->sources;
-
- while (source != NULL) {
- fullSource = source->fullSource;
- srcUrl = Py_BuildValue("(sii)", fullSource, source->num, source->flags);
- PyList_Append(sourceList, srcUrl);
- source=source->next;
- }
-
- return PyList_AsTuple(sourceList);
- }
- else {
+ pkgList = PyList_New(0);
+ if (!pkgList) {
return NULL;
}
+ iter = rpmSpecPkgIterInit(s->spec);
+
+ while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
+ PyObject *po = specPkg_Wrap(&specPkg_Type, pkg);
+ if (!po) {
+ rpmSpecPkgIterFree(iter);
+ Py_DECREF(pkgList);
+ return NULL;
+ }
+ PyList_Append(pkgList, po);
+ Py_DECREF(po);
+ }
+ rpmSpecPkgIterFree(iter);
+ return pkgList;
+}
+
+static PyObject * spec_get_source_header(specObject *s, void *closure)
+{
+ return makeHeader(rpmSpecSourceHeader(s->spec));
}
static char spec_doc[] = "RPM Spec file object";
-static PyMethodDef spec_Spec_methods[] = {
- {"sources", (PyCFunction) spec_get_sources, METH_VARARGS, NULL },
- {"prep", (PyCFunction) spec_get_prep, METH_VARARGS, NULL },
- {"build", (PyCFunction) spec_get_build, METH_VARARGS, NULL },
- {"install", (PyCFunction) spec_get_install, METH_VARARGS, NULL },
- {"clean", (PyCFunction) spec_get_clean, METH_VARARGS, NULL },
- {"buildRoot", (PyCFunction) spec_get_buildroot, METH_VARARGS, NULL },
+static PyGetSetDef spec_getseters[] = {
+ {"sources", (getter) spec_get_sources, NULL, NULL },
+ {"prep", (getter) spec_get_prep, NULL, NULL },
+ {"build", (getter) spec_get_build, NULL, NULL },
+ {"install", (getter) spec_get_install, NULL, NULL },
+ {"clean", (getter) spec_get_clean, NULL, NULL },
+ {"packages", (getter) spec_get_packages, NULL, NULL },
+ {"sourceHeader", (getter) spec_get_source_header, NULL, NULL },
{NULL} /* Sentinel */
};
+static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+{
+ char * kwlist[] = {"specfile", "flags", NULL};
+ const char * specfile;
+ rpmSpec spec = NULL;
+ /* XXX This is a dumb default but anything else breaks compatibility... */
+ rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:spec_new", kwlist,
+ &specfile, &flags))
+ return NULL;
+
+ spec = rpmSpecParse(specfile, flags, NULL);
+ if (spec == NULL) {
+ PyErr_SetString(PyExc_ValueError, "can't parse specfile\n");
+ return NULL;
+ }
+
+ return spec_Wrap(subtype, spec);
+}
+
+static PyObject * spec_doBuild(specObject *self, PyObject *args, PyObject *kwds)
+{
+ char * kwlist[] = { "buildAmount", "pkgFlags", NULL };
+ struct rpmBuildArguments_s ba = { 0 };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:spec_doBuild",
+ kwlist, &ba.buildAmount, &ba.pkgFlags))
+ return NULL;
+
+ return PyBool_FromLong(rpmSpecBuild(self->spec, &ba) == RPMRC_OK);
+}
+
+static struct PyMethodDef spec_methods[] = {
+ { "_doBuild", (PyCFunction)spec_doBuild, METH_VARARGS|METH_KEYWORDS, NULL },
+ { NULL, NULL }
+};
+
PyTypeObject spec_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
"rpm.spec", /*tp_name*/
sizeof(specObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor) spec_dealloc, /*tp_dealloc*/
- (printfunc) spec_print, /*tp_print*/
+ 0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
spec_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- spec_Spec_methods, /* tp_methods */
+ spec_methods, /* tp_methods */
0, /* tp_members */
- 0, /* tp_getset */
+ spec_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- 0, /* tp_new */
+ spec_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
};
-rpmSpec specFromSpec(specObject *s)
+PyObject *
+spec_Wrap(PyTypeObject *subtype, rpmSpec spec)
{
- return s->spec;
+ specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
+ if (s == NULL) return NULL;
+
+ s->spec = spec;
+ return (PyObject *) s;
}
-PyObject *
-spec_Wrap(rpmSpec spec)
+PyObject * specPkg_Wrap(PyTypeObject *subtype, rpmSpecPkg pkg)
{
- specObject * s = PyObject_New(specObject, &spec_Type);
- if (s == NULL) return PyErr_NoMemory();
+ specPkgObject * s = (specPkgObject *)subtype->tp_alloc(subtype, 0);
+ if (s == NULL) return NULL;
- s->spec = spec;
+ s->pkg = pkg;
return (PyObject *) s;
}
+