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.rpmPushMacro("_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(PYTHON_MODULENAME);
35 if (rpmmod == NULL) return NULL;
37 PyObject *ptr = CAPSULE_BUILD(h, PYTHON_MODULENAME"._C_Header");
38 PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
44 struct specPkgObject_s {
46 /*type specific fields */
48 specObject *source_spec;
51 static void specPkg_dealloc(specPkgObject * s)
53 Py_DECREF(s->source_spec);
56 static PyObject *pkgGetSection(rpmSpecPkg pkg, int section)
58 char *sect = rpmSpecPkgGetSection(pkg, section);
60 PyObject *ps = utf8FromString(sect);
68 static char specPkg_doc[] =
69 "Package data parsed from spec file.";
71 static PyObject * specpkg_get_header(specPkgObject *s, void *closure)
73 return makeHeader(rpmSpecPkgHeader(s->pkg));
76 static PyObject * specpkg_get_fileFile(specPkgObject *s, void *closure)
78 return pkgGetSection(s->pkg, RPMBUILD_FILE_FILE);
81 static PyObject * specpkg_get_fileList(specPkgObject *s, void *closure)
83 return pkgGetSection(s->pkg, RPMBUILD_FILE_LIST);
86 static PyObject * specpkg_get_policyList(specPkgObject *s, void *closure)
88 return pkgGetSection(s->pkg, RPMBUILD_POLICY);
91 static PyGetSetDef specpkg_getseters[] = {
92 { "header", (getter) specpkg_get_header, NULL, NULL },
93 { "fileFile", (getter) specpkg_get_fileFile, NULL, NULL },
94 { "fileList", (getter) specpkg_get_fileList, NULL, NULL },
95 { "policyList", (getter) specpkg_get_policyList, NULL, NULL },
96 { NULL } /* sentinel */
99 PyTypeObject specPkg_Type = {
100 PyVarObject_HEAD_INIT(&PyType_Type, 0)
101 PYTHON_MODULENAME".specpkg", /* tp_name */
102 sizeof(specPkgObject), /* tp_size */
104 (destructor) specPkg_dealloc, /* tp_dealloc */
110 0, /* tp_as_number */
111 0, /* tp_as_sequence */
112 0, /* tp_as_mapping */
116 PyObject_GenericGetAttr, /* tp_getattro */
117 PyObject_GenericSetAttr, /* tp_setattro */
118 0, /* tp_as_buffer */
119 Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
120 specPkg_doc, /* tp_doc */
123 0, /* tp_richcompare */
124 0, /* tp_weaklistoffset */
129 specpkg_getseters, /* tp_getset */
132 0, /* tp_descr_get */
133 0, /* tp_descr_set */
134 0, /* tp_dictoffset */
142 struct specObject_s {
144 /*type specific fields */
149 spec_dealloc(specObject * s)
152 s->spec=rpmSpecFree(s->spec);
154 Py_TYPE(s)->tp_free((PyObject *)s);
157 static PyObject * getSection(rpmSpec spec, int section)
159 const char *sect = rpmSpecGetSection(spec, section);
161 return utf8FromString(sect);
167 spec_get_parsed(specObject * s, void *closure)
169 return getSection(s->spec, RPMBUILD_NONE);
173 spec_get_prep(specObject * s, void *closure)
175 return getSection(s->spec, RPMBUILD_PREP);
179 spec_get_build(specObject * s, void *closure)
181 return getSection(s->spec, RPMBUILD_BUILD);
184 static PyObject * spec_get_install(specObject * s, void *closure)
186 return getSection(s->spec, RPMBUILD_INSTALL);
189 static PyObject * spec_get_check(specObject * s, void *closure)
191 return getSection(s->spec, RPMBUILD_CHECK);
194 static PyObject * spec_get_clean(specObject * s, void *closure)
196 return getSection(s->spec, RPMBUILD_CLEAN);
199 static PyObject * spec_get_sources(specObject *s, void *closure)
201 PyObject *sourceList;
204 sourceList = PyList_New(0);
209 rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
210 while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
211 PyObject *srcUrl = Py_BuildValue("(Nii)",
212 utf8FromString(rpmSpecSrcFilename(source, 1)),
213 rpmSpecSrcNum(source),
214 rpmSpecSrcFlags(source));
216 Py_DECREF(sourceList);
219 PyList_Append(sourceList, srcUrl);
222 rpmSpecSrcIterFree(iter);
228 static PyObject * spec_get_packages(specObject *s, void *closure)
234 pkgList = PyList_New(0);
239 iter = rpmSpecPkgIterInit(s->spec);
241 while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
242 PyObject *po = specPkg_Wrap(&specPkg_Type, pkg, s);
244 rpmSpecPkgIterFree(iter);
248 PyList_Append(pkgList, po);
251 rpmSpecPkgIterFree(iter);
255 static PyObject * spec_get_source_header(specObject *s, void *closure)
257 return makeHeader(rpmSpecSourceHeader(s->spec));
260 static char spec_doc[] = "RPM Spec file object";
262 static PyGetSetDef spec_getseters[] = {
263 {"sources", (getter) spec_get_sources, NULL, NULL },
264 {"parsed", (getter) spec_get_parsed, NULL, NULL},
265 {"prep", (getter) spec_get_prep, NULL, NULL },
266 {"build", (getter) spec_get_build, NULL, NULL },
267 {"install", (getter) spec_get_install, NULL, NULL },
268 {"check", (getter) spec_get_check, NULL, NULL },
269 {"clean", (getter) spec_get_clean, NULL, NULL },
270 {"packages", (getter) spec_get_packages, NULL, NULL },
271 {"sourceHeader", (getter) spec_get_source_header, NULL, NULL },
272 {NULL} /* Sentinel */
275 static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
277 char * kwlist[] = {"specfile", "flags", NULL};
278 const char * specfile;
280 /* XXX This is a dumb default but anything else breaks compatibility... */
281 rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
283 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:spec_new", kwlist,
287 spec = rpmSpecParse(specfile, flags, NULL);
289 PyErr_SetString(PyExc_ValueError, "can't parse specfile\n");
293 return spec_Wrap(subtype, spec);
296 static PyObject * spec_doBuild(specObject *self, PyObject *args, PyObject *kwds)
298 char * kwlist[] = { "buildAmount", "pkgFlags", NULL };
299 struct rpmBuildArguments_s ba = { 0 };
301 if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:spec_doBuild",
302 kwlist, &ba.buildAmount, &ba.pkgFlags))
305 return PyBool_FromLong(rpmSpecBuild(self->spec, &ba) == RPMRC_OK);
308 static struct PyMethodDef spec_methods[] = {
309 { "_doBuild", (PyCFunction)spec_doBuild, METH_VARARGS|METH_KEYWORDS, NULL },
313 PyTypeObject spec_Type = {
314 PyVarObject_HEAD_INIT(&PyType_Type, 0)
315 PYTHON_MODULENAME".spec", /*tp_name*/
316 sizeof(specObject), /*tp_basicsize*/
318 (destructor) spec_dealloc, /*tp_dealloc*/
325 0, /*tp_as_sequence*/
333 Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
334 spec_doc, /* tp_doc */
337 0, /* tp_richcompare */
338 0, /* tp_weaklistoffset */
341 spec_methods, /* tp_methods */
343 spec_getseters, /* tp_getset */
346 0, /* tp_descr_get */
347 0, /* tp_descr_set */
348 0, /* tp_dictoffset */
351 spec_new, /* tp_new */
357 spec_Wrap(PyTypeObject *subtype, rpmSpec spec)
359 specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
360 if (s == NULL) return NULL;
363 return (PyObject *) s;
366 PyObject * specPkg_Wrap(PyTypeObject *subtype, rpmSpecPkg pkg, specObject *source)
368 specPkgObject * s = (specPkgObject *)subtype->tp_alloc(subtype, 0);
369 if (s == NULL) return NULL;
372 s->source_spec = source;
373 Py_INCREF(s->source_spec);
374 return (PyObject *) s;