Initial rpm.spec implementation
authorpauln <devnull@localhost>
Wed, 10 Mar 2004 22:44:29 +0000 (22:44 +0000)
committerpauln <devnull@localhost>
Wed, 10 Mar 2004 22:44:29 +0000 (22:44 +0000)
CVS patchset: 7160
CVS date: 2004/03/10 22:44:29

python/Makefile.am
python/rpmmodule.c
python/rpmts-py.c
python/spec-py.c [new file with mode: 0644]
python/spec-py.h [new file with mode: 0644]

index be15747..73f2464 100644 (file)
@@ -17,19 +17,21 @@ INCLUDES = -I. \
        -I$(top_srcdir)/rpmio \
        @WITH_BEECRYPT_INCLUDE@ \
        -I$(top_srcdir)/popt \
+       -I$(top_srcdir)/build \
        -I$(pyincdir) \
        @WITH_LIBELF_INCLUDE@ \
        @INCPATH@
 
 noinst_HEADERS = header-py.h \
        rpmal-py.h rpmds-py.h rpmdb-py.h rpmfd-py.h rpmfts-py.h \
-       rpmfi-py.h rpmmi-py.h rpmrc-py.h rpmte-py.h rpmts-py.h
+       rpmfi-py.h rpmmi-py.h rpmrc-py.h rpmte-py.h rpmts-py.h spec-py.h
 
 mylibs= \
        $(top_builddir)/lib/.libs/librpm.so \
        $(top_builddir)/rpmdb/.libs/librpmdb.so \
        $(top_builddir)/rpmio/.libs/librpmio.so \
        $(top_builddir)/popt/.libs/libpopt.so \
+       $(top_builddir)/build/.libs/librpmbuild.so \
        @WITH_LIBELF_LIB@
 
 LDADD =
@@ -55,7 +57,7 @@ poptmodule_so_LDFLAGS = $(mylibs) $(LIBS) -shared -Wl,-soname,poptmodule.so
 noinst_LTLIBRARIES = librpmmodule.la
 librpmmodule_la_SOURCES = rpmmodule.c header-py.c \
        rpmal-py.c rpmds-py.c rpmdb-py.c rpmfd-py.c rpmfts-py.c \
-       rpmfi-py.c rpmmi-py.c rpmrc-py.c rpmte-py.c rpmts-py.c
+       rpmfi-py.c rpmmi-py.c rpmrc-py.c rpmte-py.c rpmts-py.c spec-py.c
 librpmmodule_OBJECTS = $(subst .c,.o,$(librpmmodule_la_SOURCES))
 
 rpmmodule.so$(EXEEXT): librpmmodule.la
index 3bc2064..f47da86 100644 (file)
@@ -22,6 +22,7 @@
 #include "rpmrc-py.h"
 #include "rpmte-py.h"
 #include "rpmts-py.h"
+#include "spec-py.h"
 
 #include "debug.h"
 
@@ -189,6 +190,7 @@ void initrpm(void)
 
     if (PyType_Ready(&rpmte_Type) < 0) return;
     if (PyType_Ready(&rpmts_Type) < 0) return;
+    if (PyType_Ready(&spec_Type) < 0) return;
 #endif
 
     m = Py_InitModule3("rpm", rpmModuleMethods, rpm__doc__);
@@ -239,6 +241,9 @@ void initrpm(void)
 
     Py_INCREF(&rpmts_Type);
     PyModule_AddObject(m, "ts", (PyObject *) &rpmts_Type);
+
+    Py_INCREF(&spec_Type);
+    PyModule_AddObject(m, "spec", (PyObject *) &spec_Type);
 #else
     hdr_Type.ob_type = &PyType_Type;
     rpmal_Type.ob_type = &PyType_Type;
@@ -249,6 +254,7 @@ void initrpm(void)
     rpmmi_Type.ob_type = &PyType_Type;
     rpmte_Type.ob_type = &PyType_Type;
     rpmts_Type.ob_type = &PyType_Type;
+    spec_Type.ob_type =  &PyType_Type;
 #endif
 
     dict = PyDict_New();
index 8bc29ac..5748c66 100644 (file)
@@ -7,12 +7,14 @@
 #include <rpmcli.h>
 #include <rpmpgp.h>
 #include <rpmdb.h>
+#include <rpmbuild.h>
 
 #include "header-py.h"
 #include "rpmds-py.h"  /* XXX for rpmdsNew */
 #include "rpmfi-py.h"  /* XXX for rpmfiNew */
 #include "rpmmi-py.h"
 #include "rpmte-py.h"
+#include "spec-py.h"
 
 #define        _RPMTS_INTERNAL /* XXX for ts->rdb, ts->availablePackage */
 #include "rpmts-py.h"
@@ -1261,6 +1263,35 @@ fprintf(stderr, "*** rpmts_Next(%p) ts %p\n", s, s->ts);
 /**
  */
 /*@null@*/
+static specObject *
+spec_Parse(rpmtsObject * s, PyObject * args)
+{
+    const char * specfile;
+    Spec spec;
+    char * buildRoot = NULL;
+    int recursing = 0;
+    char * passPhrase = "";
+    char *cookie = NULL;
+    int anyarch = 1;
+    int force = 1;
+
+    if (!PyArg_ParseTuple(args, "s:parseSpec", &specfile)) {
+                    return NULL;
+    }
+                        
+    if (parseSpec(s->ts, specfile,"/", buildRoot,recursing, passPhrase,
+             cookie, anyarch, force)!=0) {
+             PyErr_SetString(pyrpmError, "can't parse specfile\n");
+                     return NULL;
+   }
+
+    spec = rpmtsSpec(s->ts);
+    return spec_Wrap(spec);
+}
+
+/**
+ */
+/*@null@*/
 static rpmmiObject *
 rpmts_Match(rpmtsObject * s, PyObject * args)
        /*@globals rpmGlobalMacroContext @*/
@@ -1375,6 +1406,8 @@ static struct PyMethodDef rpmts_methods[] = {
        NULL },
  {"getKeys",   (PyCFunction) rpmts_GetKeys,    METH_VARARGS,
        NULL },
+ {"parseSpec", (PyCFunction) spec_Parse,       METH_VARARGS,
+       "ts.parseSpec(\"/path/to/foo.spec\")\n" },
  {"dbMatch",   (PyCFunction) rpmts_Match,      METH_VARARGS,
 "ts.dbMatch([TagN, [key, [len]]]) -> mi\n\
 - Create a match iterator for the default transaction rpmdb.\n" },
diff --git a/python/spec-py.c b/python/spec-py.c
new file mode 100644 (file)
index 0000000..9005c80
--- /dev/null
@@ -0,0 +1,208 @@
+/** \ingroup py_c
+ * \file python/spec-py.c
+ */
+
+#include "system.h"
+
+#include "spec-py.h"
+
+/** \ingroup python
+ * \name Class: Rpmspec
+ * \class Rpmspec
+ * \brief A python rpm.spec object represents an RPM spec file set.
+ * 
+ *  The spec file is at the heart of RPM's packaging building process. Similar
+ *  in concept to a makefile, it contains information required by RPM to build
+ *  the package, as well as instructions telling RPM how to build it. The spec
+ *  file also dictates exactly what files are a part of the package, and where
+ *  they should be installed.
+ *  
+ *  The rpm.spec object represents a parsed specfile to aid extraction of data.
+ *  
+ *  For example
+ * \code
+ *  import rpm
+ *  rpm.addMacro("_topdir","/path/to/topdir")
+ *  ts=rpm.ts()
+ *  s=ts.parseSpec("foo.spec")
+ *  print s.prep()
+ * \endcode
+ *
+ *  Macros set using add macro will be used allowing testing of conditional builds
+ *
+ */
+
+
+static void 
+spec_dealloc(specObject * s) 
+{
+        if (s->spec) {
+            freeSpec(s->spec);
+        }
+        PyObject_Del(s);
+}
+
+static int
+spec_print(specObject * s)
+{
+    return 0;
+}
+
+static PyObject * 
+spec_get_buildroot(specObject * s) 
+{
+    Spec spec = specFromSpec(s);
+    if (spec->buildRootURL) {
+        return Py_BuildValue("s", spec->buildRootURL);
+    }
+    else {
+        return NULL;
+    }
+}
+
+static PyObject * 
+spec_get_prep(specObject * s) 
+{
+    Spec spec = specFromSpec(s);
+    if (spec->prep) {
+        StringBuf sb = newStringBuf();
+        sb=spec->prep;
+        return Py_BuildValue("s",getStringBuf(sb));
+    }
+    else {
+        return NULL;
+    }
+}
+
+static PyObject * 
+spec_get_build(specObject * s) 
+{
+    Spec spec = specFromSpec(s);
+    if (spec->build) {
+        StringBuf sb = newStringBuf();
+        sb=spec->build;
+        return Py_BuildValue("s",getStringBuf(sb));
+    }
+    else {
+        return NULL;
+    }
+}
+
+static PyObject * 
+spec_get_install(specObject * s) 
+{
+    Spec spec = specFromSpec(s);
+    if (spec->install) {
+        StringBuf sb = newStringBuf();
+        sb=spec->install;
+        return Py_BuildValue("s",getStringBuf(sb));
+    }
+    else {
+        return NULL;
+    }
+}
+
+static PyObject * 
+spec_get_clean(specObject * s) 
+{
+    Spec spec = specFromSpec(s);
+    if (spec->clean) {
+        StringBuf sb = newStringBuf();
+        sb=spec->clean;
+        return Py_BuildValue("s",getStringBuf(sb));
+    }
+    else {
+        return NULL;
+    }
+}
+
+static PyObject *
+spec_get_sources(specObject *s)
+{
+    struct Source * source;
+    PyObject *sourceList, *srcUrl;
+
+    sourceList = PyList_New(0);
+    Spec spec = specFromSpec(s);
+    source = spec->sources;
+
+     while (source != NULL) {
+        srcUrl = Py_BuildValue("(sii)", source->fullSource, source->num, source->flags);
+        PyList_Append(sourceList, srcUrl);
+        source=source->next;
+    } 
+
+    return PyList_AsTuple(sourceList);
+
+}
+
+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 },
+    {NULL}  /* Sentinel */
+};
+
+PyTypeObject spec_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                         /*ob_size*/
+    "rpm.spec",               /*tp_name*/
+    sizeof(specObject),        /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor) spec_dealloc, /*tp_dealloc*/
+    (printfunc) spec_print,    /*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*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    spec_doc,                  /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    spec_Spec_methods,         /* tp_methods */
+    0,                         /* tp_members */
+    0,                         /* 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 */
+};
+
+Spec specFromSpec(specObject *s) 
+{
+    return s->spec;
+}
+
+specObject *
+spec_Wrap(Spec spec) 
+{
+    specObject * s = PyObject_New(specObject, &spec_Type);
+    if (s == NULL)
+        return NULL;
+    s->spec = spec; 
+    return s;
+}
diff --git a/python/spec-py.h b/python/spec-py.h
new file mode 100644 (file)
index 0000000..f6fa814
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef RPMPYTHON_SPEC
+#define RPMPYTHON_SPEC
+
+#include <rpmbuild.h>
+
+/** \ingroup py_c
+ * \file python/spec-py.h
+ */
+
+typedef struct specObject_s {
+    PyObject_HEAD
+    /*type specific fields */
+    Spec spec;
+} specObject;
+
+extern PyTypeObject spec_Type;
+
+Spec specFromSpec(specObject * spec);
+
+specObject * spec_Wrap(Spec spec);
+
+#endif /* RPMPYTHON_SPEC */