class RPM::Spec
Public Class Methods
Create a spec file object from a spec file @param [String] filename Spec file path @return [Spec]
static VALUE
spec_s_open(VALUE klass, VALUE filename)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
Spec rspec;
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
rpmts ts = NULL;
#else
rpmSpec spec = NULL;
rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
#endif
if (TYPE(filename) != T_STRING) {
rb_raise(rb_eTypeError, "illegal argument type");
}
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
switch (parseSpec(&rspec, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
case 0:
if (rspec != NULL) {
break;
}
default:
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, spec_free, rspec);
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
ts = rpmtsCreate();
#if RPM_VERSION_CODE < RPM_VERSION(4,4,8)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#elif RPM_VERSION_CODE < RPM_VERSION(4,5,90)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#elif RPM_VERSION_CODE < RPM_VERSION(5,0,0)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#else
switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#endif
case 0:
if (ts != NULL) {
break;
}
default:
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, ts_free, ts);
#else
spec = rpmSpecParse(RSTRING_PTR(filename), flags, NULL);
if (spec == NULL) {
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, rpmSpecFree, spec);
#endif
}
Create a spec file object from a spec file @param [String] filename Spec file path @return [Spec]
static VALUE
spec_s_open(VALUE klass, VALUE filename)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
Spec rspec;
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
rpmts ts = NULL;
#else
rpmSpec spec = NULL;
rpmSpecFlags flags = (RPMSPEC_ANYARCH|RPMSPEC_FORCE);
#endif
if (TYPE(filename) != T_STRING) {
rb_raise(rb_eTypeError, "illegal argument type");
}
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
switch (parseSpec(&rspec, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
case 0:
if (rspec != NULL) {
break;
}
default:
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, spec_free, rspec);
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
ts = rpmtsCreate();
#if RPM_VERSION_CODE < RPM_VERSION(4,4,8)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#elif RPM_VERSION_CODE < RPM_VERSION(4,5,90)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#elif RPM_VERSION_CODE < RPM_VERSION(5,0,0)
switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#else
switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#endif
case 0:
if (ts != NULL) {
break;
}
default:
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, ts_free, ts);
#else
spec = rpmSpecParse(RSTRING_PTR(filename), flags, NULL);
if (spec == NULL) {
rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
}
return Data_Wrap_Struct(klass, NULL, rpmSpecFree, spec);
#endif
}
Public Instance Methods
Builds the spec file @param [Number] flags bits to enable stages of build @param [Boolean] test When true, don't execute scripts or package @return [Number] exit code
@example
spec = RPM::Spec.open("foo.spec") spec.build(RPM::BUILD__UNTIL_BUILD)
VALUE
rpm_spec_build(int argc, VALUE* argv, VALUE spec)
{
int flags, test;
rpmRC rc;
switch (argc) {
case 0:
rb_raise(rb_eArgError, "argument too few(1..2)");
case 1:
flags = NUM2INT(argv[0]);
test = 0;
break;
case 2:
flags = NUM2INT(argv[0]);
test = RTEST(argv[1]);
break;
default:
rb_raise(rb_eArgError, "argument too many(0..1)");
}
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
rc = buildSpec(RPM_SPEC(spec), flags,test);
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
rpmts ts = NULL;
ts = rpmtsCreate();
rc = buildSpec(ts, RPM_SPEC(spec), flags,test);
ts_free(ts);
#else
struct rpmBuildArguments_s buildArgs;
buildArgs.buildAmount = flags;
if (test)
buildArgs.buildAmount |= RPMBUILD_NOBUILD;
rc = rpmSpecBuild(RPM_SPEC(spec), &buildArgs);
#endif
return INT2NUM(rc);
}
VALUE
rpm_spec_get_build_restrictions(VALUE spec)
{
VALUE cache = rb_ivar_get(spec, id_rest);
if (NIL_P(cache)) {
#if RPM_VERSION_CODE >= RPM_VERSION(4,9,0) && RPM_VERSION_CODE < RPM_VERSION(5,0,0)
Header header = rpmSpecSourceHeader(RPM_SPEC(spec));
#else
Header header = RPM_SPEC(spec)->buildRestrictions;
#endif
cache = rpm_package_new_from_header(header);
rb_ivar_set(spec, id_rest, cache);
}
return cache;
}
@return [Array<String>] Return Build architectures defined in the spec file
VALUE
rpm_spec_get_buildarchs(VALUE spec)
{
VALUE ba = rb_ivar_get(spec, id_ba);
if (NIL_P(ba)) {
ba = rb_ary_new();
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
register int i;
for (i = 0; i < RPM_SPEC(spec)->BACount; i++) {
rb_ary_push(ba, rb_str_new2(RPM_SPEC(spec)->BANames[i]));
}
#else
Header header = rpmSpecSourceHeader(RPM_SPEC(spec));
rpmtd archtd = rpmtdNew();
if (!headerGet(header,
RPMTAG_BUILDARCHS, archtd, HEADERGET_MINMEM)) {
rpmtdFree(archtd);
return ba;
}
rpmtdInit(archtd);
while ( rpmtdNext(archtd) != -1 ) {
rb_ary_push(ba, rb_str_new2(rpmtdGetString(archtd)));
}
#endif
rb_ivar_set(spec, id_ba, ba);
}
return ba;
}
@return [Array<RPM::Conflict>] Return Build conflicts defined in the spec file
VALUE
rpm_spec_get_buildconflicts(VALUE spec)
{
VALUE bc = rb_ivar_get(spec, id_bc);
#if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
if (NIL_P(bc)) {
const char** names;
const char** vers;
int_32* flags;
int_32 count;
rpmTagType nt, vt, type;
register int i;
bc = rb_ary_new();
if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions,
RPMTAG_CONFLICTNAME, (hTYP_t)&nt,
(hPTR_t*)&names, (hCNT_t)&count)) {
goto leave;
}
get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTVERSION,
&vt, (void*)&vers);
get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTFLAGS,
&type, (void*)&flags);
for (i = 0; i < count; i++) {
rb_ary_push(bc, rpm_conflict_new(names[i], rpm_version_new(vers[i]),
flags[i], spec));
}
release_entry(nt, names);
release_entry(vt, vers);
rb_ivar_set(spec, id_bc, bc);
}
leave:
return bc;
#else
rpmtd nametd = rpmtdNew();
rpmtd versiontd = rpmtdNew();
rpmtd flagtd = rpmtdNew();
if (NIL_P(bc)) {
#if RPM_VERSION_CODE >= RPM_VERSION(4,9,0)
Header header = rpmSpecSourceHeader(RPM_SPEC(spec));
#else
Header header = RPM_SPEC(spec)->buildRestrictions;
#endif
bc = rb_ary_new();
if (!headerGet(header,
RPMTAG_CONFLICTNAME, nametd, HEADERGET_MINMEM)) {
goto leave;
}
get_entry(header, RPMTAG_CONFLICTVERSION,
versiontd);
get_entry(header, RPMTAG_CONFLICTFLAGS,
flagtd);
rpmtdInit(nametd);
while ( rpmtdNext(nametd) != -1) {
rb_ary_push(bc, rpm_conflict_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec));
}
rb_ivar_set(spec, id_bc, bc);
}
leave:
rpmtdFree(nametd);
rpmtdFree(versiontd);
rpmtdFree(flagtd);
return bc;
#endif
}
@return [Array<RPM::Require>] Return Build requires defined in the spec file
VALUE
rpm_spec_get_buildrequires(VALUE spec)
{
VALUE br = rb_ivar_get(spec, id_br);
#if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
if (NIL_P(br)) {
const char** names;
const char** vers;
int_32* flags;
int_32 count;
rpmTagType nt, vt, type;
register int i;
br = rb_ary_new();
if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions,
RPMTAG_REQUIRENAME, (hTYP_t)&nt,
(hPTR_t*)&names, (hCNT_t)&count)) {
goto leave;
}
get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREVERSION,
&vt, (void*)&vers);
get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREFLAGS,
&type, (void*)&flags);
for (i = 0; i < count; i++) {
rb_ary_push(br, rpm_require_new(names[i], rpm_version_new(vers[i]),
flags[i], spec));
}
release_entry(nt, names);
release_entry(vt, vers);
rb_ivar_set(spec, id_br, br);
}
leave:
return br;
#else
rpmtd nametd = rpmtdNew();
rpmtd versiontd = rpmtdNew();
rpmtd flagtd = rpmtdNew();
if (NIL_P(br)) {
#if RPM_VERSION_CODE >= RPM_VERSION(4,9,0)
Header header = rpmSpecSourceHeader(RPM_SPEC(spec));
#else
Header header = RPM_SPEC(spec)->buildRestrictions;
#endif
br = rb_ary_new();
if (!headerGet(header,
RPMTAG_REQUIRENAME, nametd, HEADERGET_MINMEM)) {
goto leave;
}
get_entry(header, RPMTAG_REQUIREVERSION,
versiontd);
get_entry(header, RPMTAG_REQUIREFLAGS,
flagtd);
rpmtdInit(nametd);
while ( rpmtdNext(nametd) != -1 ) {
rb_ary_push(br, rpm_require_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec));
}
rb_ivar_set(spec, id_br, br);
}
leave:
rpmtdFree(nametd);
rpmtdFree(versiontd);
rpmtdFree(flagtd);
return br;
#endif
}
@return [String] Return Build root defined in the spec file
VALUE
rpm_spec_get_buildroot(VALUE spec)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,5,90)
if (RPM_SPEC(spec)->buildRootURL) {
return rb_str_new2(RPM_SPEC(spec)->buildRootURL);
}
#elif RPM_VERSION_CODE < RPM_VERSION(4,5,90)
if (RPM_SPEC(spec)->rootURL) {
return rb_str_new2(RPM_SPEC(spec)->rootURL);
}
#elif RPM_VERSION_CODE < RPM_VERSION(4,9,0)
if (RPM_SPEC(spec)->buildRoot) {
return rb_str_new2(RPM_SPEC(spec)->buildRoot);
}
#elif RPM_VERSION_CODE < RPM_VERSION(5,0,0)
char *buildRootURL = rpmGenPath(NULL, "%{buildroot}", NULL);
VALUE result = rb_str_new2(buildRootURL);
free(buildRootURL);
return result;
#else
const char *buildRootURL = rpmGenPath(RPM_SPEC(spec)->rootURL, "%{?buildroot}", NULL);
VALUE result = rb_str_new2(buildRootURL);
buildRootURL = _free(buildRootURL);
return result;
#endif
return Qnil;
}
@return [String] Return Build subdirectory defined in the spec file
VALUE
rpm_spec_get_buildsubdir(VALUE spec)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
if (RPM_SPEC(spec)->buildSubdir) {
return rb_str_new2(RPM_SPEC(spec)->buildSubdir);
}
#else
char *buildSubDir = rpmGenPath(NULL, "%{buildsubdir}", NULL);
VALUE result = rb_str_new2(buildSubDir);
free(buildSubDir);
return result;
#endif
return Qnil;
}
Expands a macro in the spec file @param [String] name Name of the macro @return [String] @example
spec.expand_macros("configure")
=> "\n CFLAGS=......."
spec.expand_macros("_prefix")
=> "/usr"
VALUE
rpm_spec_expand_macros(VALUE spec, VALUE name)
{
char buf[BUFSIZ];
char *tmp, *res;
VALUE val;
if (TYPE(name) != T_STRING) {
rb_raise(rb_eTypeError, "illegal argument type");
}
sprintf(buf, "%%{%s}", RSTRING_PTR(name));
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
tmp = strdup(buf);
expandMacros(RPM_SPEC(spec), RPM_SPEC(spec)->macros, buf, BUFSIZ);
res = buf;
#else
tmp = rpmExpand(buf, NULL);
res = tmp;
#endif
if (strcmp(tmp, buf) == 0) {
val = Qnil;
} else {
val = rb_str_new2(res);
}
free(tmp);
return val;
}
@return [Array<RPM::Package>] Packages defined in the spec file
VALUE
rpm_spec_get_packages(VALUE spec)
{
VALUE pkg = rb_ivar_get(spec, id_pkg);
if (NIL_P(pkg)) {
pkg = rb_ary_new();
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
Package p = RPM_SPEC(spec)->packages;
while (p != NULL) {
if (p->fileList)
rb_ary_push(pkg, rpm_package_new_from_header(p->header));
p = p->next;
}
#else
rpmSpecPkgIter pi = rpmSpecPkgIterInit(RPM_SPEC(spec));
rpmSpecPkg p;
while ((p = rpmSpecPkgIterNext(pi)) != NULL) {
const char * fileList = rpmSpecGetSection(RPM_SPEC(spec), RPMBUILD_FILECHECK);
Header header = rpmSpecPkgHeader(p);
rb_ary_push(pkg, rpm_package_new_from_header(header));
}
rpmSpecPkgIterFree(pi);
#endif
rb_ivar_set(spec, id_pkg, pkg);
}
return pkg;
}
@return [Array<RPM::Source>] Sources defined in the spec file
VALUE
rpm_spec_get_sources(VALUE spec)
{
VALUE src = rb_ivar_get(spec, id_src);
if (NIL_P(src)) {
src = rb_ary_new();
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
struct Source* s = RPM_SPEC(spec)->sources;
while (s != NULL) {
VALUE obj = Qnil;
if (s->flags & RPMBUILD_ISSOURCE) {
obj = rpm_source_new(s->fullSource, s->num, s->flags & RPMBUILD_ISNO);
} else if (s->flags & RPMBUILD_ISPATCH) {
obj = rpm_patch_new(s->fullSource, s->num, s->flags & RPMBUILD_ISNO);
} else if (s->flags & RPMBUILD_ISICON) {
obj = rpm_icon_new(s->fullSource, s->num, s->flags & RPMBUILD_ISNO);
}
rb_ary_push(src, obj);
s = s->next;
}
#else
rpmSpecSrcIter s = rpmSpecSrcIterInit(RPM_SPEC(spec));
rpmSpecSrc source;
while ((source = rpmSpecSrcIterNext(s)) != NULL) {
VALUE obj = Qnil;
rpmSourceFlags flags = rpmSpecSrcFlags(source);
if (flags & RPMBUILD_ISSOURCE) {
obj = rpm_source_new(rpmSpecSrcFilename(source, 1),
rpmSpecSrcNum(source), flags & RPMBUILD_ISNO);
} else if (flags & RPMBUILD_ISPATCH) {
obj = rpm_patch_new(rpmSpecSrcFilename(source, 1),
rpmSpecSrcNum(source), flags & RPMBUILD_ISNO);
} else if (flags & RPMBUILD_ISICON) {
obj = rpm_icon_new(rpmSpecSrcFilename(source, 1),
rpmSpecSrcNum(source), flags & RPMBUILD_ISNO);
}
rb_ary_push(src, obj);
}
rpmSpecSrcIterFree(s);
#endif
rb_ivar_set(spec, id_src, src);
}
return src;
}