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
33 /*type specific fields */
38 spec_dealloc(specObject * s)
41 s->spec=freeSpec(s->spec);
43 s->ob_type->tp_free((PyObject *)s);
46 /* XXX TODO return something sensible if spec exists but component (eg %clean)
47 * does not. Possibly "" or None */
50 spec_get_buildroot(specObject * s)
52 rpmSpec spec = specFromSpec(s);
53 if (spec != NULL && spec->buildRoot) {
54 return Py_BuildValue("s", spec->buildRoot);
62 spec_get_prep(specObject * s)
64 rpmSpec spec = specFromSpec(s);
66 if (spec != NULL && spec->prep) {
67 res = Py_BuildValue("s",getStringBuf(spec->prep));
73 spec_get_build(specObject * s)
75 rpmSpec spec = specFromSpec(s);
77 if (spec != NULL && spec->build) {
78 res = Py_BuildValue("s",getStringBuf(spec->build));
84 spec_get_install(specObject * s)
86 rpmSpec spec = specFromSpec(s);
88 if (spec != NULL && spec->install) {
89 res = Py_BuildValue("s",getStringBuf(spec->install));
95 spec_get_clean(specObject * s)
97 rpmSpec spec = specFromSpec(s);
99 if (spec != NULL && spec->clean) {
100 res = Py_BuildValue("s",getStringBuf(spec->clean));
106 spec_get_sources(specObject *s)
108 struct Source * source;
109 PyObject *sourceList, *srcUrl;
113 sourceList = PyList_New(0);
114 spec = specFromSpec(s);
116 source = spec->sources;
118 while (source != NULL) {
119 fullSource = source->fullSource;
120 srcUrl = Py_BuildValue("(sii)", fullSource, source->num, source->flags);
121 PyList_Append(sourceList, srcUrl);
125 return PyList_AsTuple(sourceList);
133 static char spec_doc[] = "RPM Spec file object";
135 static PyMethodDef spec_Spec_methods[] = {
136 {"sources", (PyCFunction) spec_get_sources, METH_VARARGS, NULL },
137 {"prep", (PyCFunction) spec_get_prep, METH_VARARGS, NULL },
138 {"build", (PyCFunction) spec_get_build, METH_VARARGS, NULL },
139 {"install", (PyCFunction) spec_get_install, METH_VARARGS, NULL },
140 {"clean", (PyCFunction) spec_get_clean, METH_VARARGS, NULL },
141 {"buildRoot", (PyCFunction) spec_get_buildroot, METH_VARARGS, NULL },
142 {NULL} /* Sentinel */
145 static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
148 const char * specfile;
150 char * buildRoot = NULL;
152 char * passPhrase = "";
156 char * kwlist[] = {"specfile", NULL};
158 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:spec_new", kwlist,
163 * Just how hysterical can you get? We need to create a transaction
164 * set to get back the results from parseSpec()...
167 if (parseSpec(ts, specfile,"/", buildRoot,recursing, passPhrase,
168 cookie, anyarch, force) == 0) {
169 spec = rpmtsSpec(ts);
171 PyErr_SetString(pyrpmError, "can't parse specfile\n");
175 return spec ? spec_Wrap(subtype, spec) : NULL;
178 PyTypeObject spec_Type = {
179 PyObject_HEAD_INIT(&PyType_Type)
181 "rpm.spec", /*tp_name*/
182 sizeof(specObject), /*tp_basicsize*/
184 (destructor) spec_dealloc, /*tp_dealloc*/
191 0, /*tp_as_sequence*/
199 Py_TPFLAGS_DEFAULT, /*tp_flags*/
200 spec_doc, /* tp_doc */
203 0, /* tp_richcompare */
204 0, /* tp_weaklistoffset */
207 spec_Spec_methods, /* tp_methods */
212 0, /* tp_descr_get */
213 0, /* tp_descr_set */
214 0, /* tp_dictoffset */
217 spec_new, /* tp_new */
222 rpmSpec specFromSpec(specObject *s)
228 spec_Wrap(PyTypeObject *subtype, rpmSpec spec)
230 specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
231 if (s == NULL) return PyErr_NoMemory();
234 return (PyObject *) s;