1 #include "rpmsystem-py.h"
9 * \brief A python rpm.spec object represents an RPM spec file set.
11 * The spec file is at the heart of RPM's packaging building process. Similar
12 * in concept to a makefile, it contains information required by RPM to build
13 * the package, as well as instructions telling RPM how to build it. The spec
14 * file also dictates exactly what files are a part of the package, and where
15 * they should be installed.
17 * The rpm.spec object represents a parsed specfile to aid extraction of data.
22 * rpm.addMacro("_topdir","/path/to/topdir")
23 * s=rpm.spec("foo.spec")
27 * Macros set using add macro will be used allowing testing of conditional builds
31 /* Header objects are in another module, some hoop jumping required... */
32 static PyObject *makeHeader(Header h)
34 PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
35 if (rpmmod == NULL) return NULL;
37 PyObject *ptr = CAPSULE_BUILD(h, "rpm._C_Header");
38 PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
44 struct specPkgObject_s {
46 /*type specific fields */
50 static char specPkg_doc[] =
53 static PyObject * specpkg_get_header(specPkgObject *s, void *closure)
55 return makeHeader(rpmSpecPkgHeader(s->pkg));
58 static PyGetSetDef specpkg_getseters[] = {
59 { "header", (getter) specpkg_get_header, NULL, NULL },
60 { NULL } /* sentinel */
63 PyTypeObject specPkg_Type = {
64 PyVarObject_HEAD_INIT(&PyType_Type, 0)
65 "rpm.specpkg", /* tp_name */
66 sizeof(specPkgObject), /* tp_size */
75 0, /* tp_as_sequence */
76 0, /* tp_as_mapping */
80 PyObject_GenericGetAttr, /* tp_getattro */
81 PyObject_GenericSetAttr, /* tp_setattro */
83 Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
84 specPkg_doc, /* tp_doc */
87 0, /* tp_richcompare */
88 0, /* tp_weaklistoffset */
93 specpkg_getseters, /* tp_getset */
98 0, /* tp_dictoffset */
106 struct specObject_s {
108 /*type specific fields */
113 spec_dealloc(specObject * s)
116 s->spec=rpmSpecFree(s->spec);
118 Py_TYPE(s)->tp_free((PyObject *)s);
121 static PyObject * getSection(rpmSpec spec, int section)
123 const char *sect = rpmSpecGetSection(spec, section);
125 return Py_BuildValue("s", sect);
131 spec_get_prep(specObject * s, void *closure)
133 return getSection(s->spec, RPMBUILD_PREP);
137 spec_get_build(specObject * s, void *closure)
139 return getSection(s->spec, RPMBUILD_BUILD);
142 static PyObject * spec_get_install(specObject * s, void *closure)
144 return getSection(s->spec, RPMBUILD_INSTALL);
147 static PyObject * spec_get_clean(specObject * s, void *closure)
149 return getSection(s->spec, RPMBUILD_CLEAN);
152 static PyObject * spec_get_sources(specObject *s, void *closure)
154 PyObject *sourceList;
157 sourceList = PyList_New(0);
162 rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
163 while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
164 PyObject *srcUrl = Py_BuildValue("(sii)",
165 rpmSpecSrcFilename(source, 1),
166 rpmSpecSrcNum(source),
167 rpmSpecSrcFlags(source));
169 Py_DECREF(sourceList);
172 PyList_Append(sourceList, srcUrl);
175 rpmSpecSrcIterFree(iter);
181 static PyObject * spec_get_packages(specObject *s, void *closure)
187 pkgList = PyList_New(0);
192 iter = rpmSpecPkgIterInit(s->spec);
194 while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
195 PyObject *po = specPkg_Wrap(&specPkg_Type, pkg);
197 rpmSpecPkgIterFree(iter);
201 PyList_Append(pkgList, po);
204 rpmSpecPkgIterFree(iter);
208 static PyObject * spec_get_source_header(specObject *s, void *closure)
210 return makeHeader(rpmSpecSourceHeader(s->spec));
213 static char spec_doc[] = "RPM Spec file object";
215 static PyGetSetDef spec_getseters[] = {
216 {"sources", (getter) spec_get_sources, NULL, NULL },
217 {"prep", (getter) spec_get_prep, NULL, NULL },
218 {"build", (getter) spec_get_build, NULL, NULL },
219 {"install", (getter) spec_get_install, NULL, NULL },
220 {"clean", (getter) spec_get_clean, NULL, NULL },
221 {"packages", (getter) spec_get_packages, NULL, NULL },
222 {"sourceHeader", (getter) spec_get_source_header, NULL, NULL },
223 {NULL} /* Sentinel */
226 static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
228 char * kwlist[] = {"specfile", "flags", NULL};
229 const char * specfile;
231 /* XXX This is a dumb default but anything else breaks compatibility... */
232 rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
234 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:spec_new", kwlist,
238 spec = rpmSpecParse(specfile, flags, NULL);
240 PyErr_SetString(PyExc_ValueError, "can't parse specfile\n");
244 return spec_Wrap(subtype, spec);
247 static PyObject * spec_doBuild(specObject *self, PyObject *args, PyObject *kwds)
249 char * kwlist[] = { "buildAmount", "pkgFlags", NULL };
250 struct rpmBuildArguments_s ba = { 0 };
252 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:spec_doBuild",
253 kwlist, &ba.buildAmount, &ba.pkgFlags))
256 return PyBool_FromLong(rpmSpecBuild(self->spec, &ba) == RPMRC_OK);
259 static struct PyMethodDef spec_methods[] = {
260 { "_doBuild", (PyCFunction)spec_doBuild, METH_VARARGS|METH_KEYWORDS, NULL },
264 PyTypeObject spec_Type = {
265 PyVarObject_HEAD_INIT(&PyType_Type, 0)
266 "rpm.spec", /*tp_name*/
267 sizeof(specObject), /*tp_basicsize*/
269 (destructor) spec_dealloc, /*tp_dealloc*/
276 0, /*tp_as_sequence*/
284 Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
285 spec_doc, /* tp_doc */
288 0, /* tp_richcompare */
289 0, /* tp_weaklistoffset */
292 spec_methods, /* tp_methods */
294 spec_getseters, /* tp_getset */
297 0, /* tp_descr_get */
298 0, /* tp_descr_set */
299 0, /* tp_dictoffset */
302 spec_new, /* tp_new */
308 spec_Wrap(PyTypeObject *subtype, rpmSpec spec)
310 specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
311 if (s == NULL) return NULL;
314 return (PyObject *) s;
317 PyObject * specPkg_Wrap(PyTypeObject *subtype, rpmSpecPkg pkg)
319 specPkgObject * s = (specPkgObject *)subtype->tp_alloc(subtype, 0);
320 if (s == NULL) return NULL;
323 return (PyObject *) s;