Use the new spec section getter in python bindings
[platform/upstream/rpm.git] / python / spec-py.c
1 #include "rpmsystem-py.h"
2
3 #include "header-py.h"
4 #include "spec-py.h"
5 #include "build/rpmbuild_internal.h"    /* XXX FIXME! */
6
7 /** \ingroup python
8  * \name Class: Rpmspec
9  * \class Rpmspec
10  * \brief A python rpm.spec object represents an RPM spec file set.
11  * 
12  *  The spec file is at the heart of RPM's packaging building process. Similar
13  *  in concept to a makefile, it contains information required by RPM to build
14  *  the package, as well as instructions telling RPM how to build it. The spec
15  *  file also dictates exactly what files are a part of the package, and where
16  *  they should be installed.
17  *  
18  *  The rpm.spec object represents a parsed specfile to aid extraction of data.
19  *  
20  *  For example
21  * \code
22  *  import rpm
23  *  rpm.addMacro("_topdir","/path/to/topdir")
24  *  s=rpm.spec("foo.spec")
25  *  print s.prep()
26  * \endcode
27  *
28  *  Macros set using add macro will be used allowing testing of conditional builds
29  *
30  */
31
32 /* Header objects are in another module, some hoop jumping required... */
33 static PyObject *makeHeader(Header h)
34 {
35     PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
36     if (rpmmod == NULL) return NULL;
37
38     PyObject *ptr = PyCObject_FromVoidPtr(h, NULL);
39     PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
40     Py_XDECREF(ptr);
41     Py_XDECREF(rpmmod);
42     return hdr;
43 }
44
45 struct specPkgObject_s {
46     PyObject_HEAD
47     /*type specific fields */
48     rpmSpecPkg pkg;
49 };
50
51 static char specPkg_doc[] =
52 "";
53
54 static PyObject * specpkg_get_header(specPkgObject *s, void *closure)
55 {
56     return makeHeader(rpmSpecPkgHeader(s->pkg));
57 }
58
59 static PyGetSetDef specpkg_getseters[] = {
60     { "header", (getter) specpkg_get_header, NULL, NULL },
61     { NULL }    /* sentinel */
62 };
63
64 PyTypeObject specPkg_Type = {
65         PyVarObject_HEAD_INIT(&PyType_Type, 0)
66         "rpm.specpkg",                  /* tp_name */
67         sizeof(specPkgObject),          /* tp_size */
68         0,                              /* tp_itemsize */
69         0,                              /* tp_dealloc */
70         0,                              /* tp_print */
71         0,                              /* tp_getattr */
72         0,                              /* tp_setattr */
73         0,                              /* tp_compare */
74         0,                              /* tp_repr */
75         0,                              /* tp_as_number */
76         0,                              /* tp_as_sequence */
77         0,                              /* tp_as_mapping */
78         0,                              /* tp_hash */
79         0,                              /* tp_call */
80         0,                              /* tp_str */
81         PyObject_GenericGetAttr,        /* tp_getattro */
82         PyObject_GenericSetAttr,        /* tp_setattro */
83         0,                              /* tp_as_buffer */
84         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
85         specPkg_doc,                    /* tp_doc */
86         0,                              /* tp_traverse */
87         0,                              /* tp_clear */
88         0,                              /* tp_richcompare */
89         0,                              /* tp_weaklistoffset */
90         0,                              /* tp_iter */
91         0,                              /* tp_iternext */
92         0,                              /* tp_methods */
93         0,                              /* tp_members */
94         specpkg_getseters,              /* tp_getset */
95         0,                              /* tp_base */
96         0,                              /* tp_dict */
97         0,                              /* tp_descr_get */
98         0,                              /* tp_descr_set */
99         0,                              /* tp_dictoffset */
100         0,                              /* tp_init */
101         0,                              /* tp_alloc */
102         0,                              /* tp_new */
103         0,                              /* tp_free */
104         0,                              /* tp_is_gc */
105 };
106
107 struct specObject_s {
108     PyObject_HEAD
109     /*type specific fields */
110     rpmSpec spec;
111 };
112
113 static void 
114 spec_dealloc(specObject * s) 
115 {
116     if (s->spec) {
117         s->spec=rpmSpecFree(s->spec);
118     }
119     Py_TYPE(s)->tp_free((PyObject *)s);
120 }
121
122 static PyObject * 
123 spec_get_buildroot(specObject * s, void *closure) 
124 {
125     rpmSpec spec = s->spec;
126     if (spec->buildRoot) {
127         return Py_BuildValue("s", spec->buildRoot);
128     }
129     Py_RETURN_NONE;
130 }
131
132 static PyObject * getSection(rpmSpec spec, int section)
133 {
134     const char *sect = rpmSpecGetSection(spec, section);
135     if (sect) {
136         return Py_BuildValue("s", sect);
137     }
138     Py_RETURN_NONE;
139 }
140
141 static PyObject * 
142 spec_get_prep(specObject * s, void *closure) 
143 {
144     return getSection(s->spec, RPMBUILD_PREP);
145 }
146
147 static PyObject * 
148 spec_get_build(specObject * s, void *closure) 
149 {
150     return getSection(s->spec, RPMBUILD_BUILD);
151 }
152
153 static PyObject * spec_get_install(specObject * s, void *closure) 
154 {
155     return getSection(s->spec, RPMBUILD_INSTALL);
156 }
157
158 static PyObject * spec_get_clean(specObject * s, void *closure) 
159 {
160     return getSection(s->spec, RPMBUILD_CLEAN);
161 }
162
163 static PyObject * spec_get_sources(specObject *s, void *closure)
164 {
165     PyObject *sourceList = PyList_New(0);
166     rpmSpecSrc source;
167
168     rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
169     while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
170         PyObject *srcUrl = Py_BuildValue("(sii)",
171                                 rpmSpecSrcFilename(source, 1),
172                                 rpmSpecSrcNum(source),
173                                 rpmSpecSrcFlags(source)); 
174         PyList_Append(sourceList, srcUrl);
175         Py_DECREF(srcUrl);
176     } 
177     rpmSpecSrcIterFree(iter);
178
179     return sourceList;
180
181 }
182
183 static PyObject * spec_get_packages(specObject *s, void *closure)
184 {
185     rpmSpecPkg pkg;
186     PyObject *pkgList = PyList_New(0);
187     rpmSpecPkgIter iter = rpmSpecPkgIterInit(s->spec);
188
189     while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
190         PyObject *po = specPkg_Wrap(&specPkg_Type, pkg);
191         PyList_Append(pkgList, po);
192         Py_DECREF(po);
193     }
194     rpmSpecPkgIterFree(iter);
195     return pkgList;
196 }
197
198 static char spec_doc[] = "RPM Spec file object";
199
200 static PyGetSetDef spec_getseters[] = {
201     {"sources",   (getter) spec_get_sources, NULL, NULL },
202     {"prep",   (getter) spec_get_prep, NULL, NULL },
203     {"build",   (getter) spec_get_build, NULL, NULL },
204     {"install",   (getter) spec_get_install, NULL, NULL },
205     {"clean",   (getter) spec_get_clean, NULL, NULL },
206     {"buildRoot",   (getter) spec_get_buildroot, NULL, NULL },
207     {"packages", (getter) spec_get_packages, NULL, NULL },
208     {NULL}  /* Sentinel */
209 };
210
211 static PyObject *spec_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
212 {
213     char * kwlist[] = {"specfile", "flags", NULL};
214     const char * specfile;
215     rpmSpec spec = NULL;
216     /* XXX This is a dumb default but anything else breaks compatibility... */
217     rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
218
219     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i:spec_new", kwlist,
220                                      &specfile, &flags))
221         return NULL;
222
223     spec = rpmSpecParse(specfile, flags, NULL);
224     if (spec == NULL) {
225         PyErr_SetString(PyExc_ValueError, "can't parse specfile\n");
226         return NULL;
227     }
228
229     return spec_Wrap(subtype, spec);
230 }
231
232 static PyObject * spec_doBuild(specObject *self, PyObject *args, PyObject *kwds)
233 {
234     char * kwlist[] = { "buildAmount", "pkgFlags", NULL };
235     struct rpmBuildArguments_s ba = { 0 };
236
237     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|i:spec_doBuild",
238                         kwlist, &ba.buildAmount, &ba.pkgFlags))
239         return NULL;
240
241     return PyBool_FromLong(rpmSpecBuild(self->spec, &ba) == RPMRC_OK);
242 }
243
244 static struct PyMethodDef spec_methods[] = {
245     { "_doBuild", (PyCFunction)spec_doBuild, METH_VARARGS|METH_KEYWORDS, NULL },
246     { NULL, NULL }
247 };
248
249 PyTypeObject spec_Type = {
250     PyVarObject_HEAD_INIT(&PyType_Type, 0)
251     "rpm.spec",               /*tp_name*/
252     sizeof(specObject),        /*tp_basicsize*/
253     0,                         /*tp_itemsize*/
254     (destructor) spec_dealloc, /*tp_dealloc*/
255     0,                         /*tp_print*/
256     0,                         /*tp_getattr*/
257     0,                         /*tp_setattr*/
258     0,                         /*tp_compare*/
259     0,                         /*tp_repr*/
260     0,                         /*tp_as_number*/
261     0,                         /*tp_as_sequence*/
262     0,                         /*tp_as_mapping*/
263     0,                         /*tp_hash */
264     0,                         /*tp_call*/
265     0,                         /*tp_str*/
266     0,                         /*tp_getattro*/
267     0,                         /*tp_setattro*/
268     0,                         /*tp_as_buffer*/
269     Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
270     spec_doc,                  /* tp_doc */
271     0,                         /* tp_traverse */
272     0,                         /* tp_clear */
273     0,                         /* tp_richcompare */
274     0,                         /* tp_weaklistoffset */
275     0,                         /* tp_iter */
276     0,                         /* tp_iternext */
277     spec_methods,              /* tp_methods */
278     0,                         /* tp_members */
279     spec_getseters,            /* tp_getset */
280     0,                         /* tp_base */
281     0,                         /* tp_dict */
282     0,                         /* tp_descr_get */
283     0,                         /* tp_descr_set */
284     0,                         /* tp_dictoffset */
285     0,                         /* tp_init */
286     0,                         /* tp_alloc */
287     spec_new,                  /* tp_new */
288     0,                         /* tp_free */
289     0,                         /* tp_is_gc */
290 };
291
292 PyObject *
293 spec_Wrap(PyTypeObject *subtype, rpmSpec spec) 
294 {
295     specObject * s = (specObject *)subtype->tp_alloc(subtype, 0);
296     if (s == NULL) return NULL;
297
298     s->spec = spec; 
299     return (PyObject *) s;
300 }
301
302 PyObject * specPkg_Wrap(PyTypeObject *subtype, Package pkg) 
303 {
304     specPkgObject * s = (specPkgObject *)subtype->tp_alloc(subtype, 0);
305     if (s == NULL) return NULL;
306
307     s->pkg = pkg;
308     return (PyObject *) s;
309 }
310