From a180e863e89f1ca9a355704686e5b400f8abe6a9 Mon Sep 17 00:00:00 2001 From: blundellc Date: Sat, 13 Sep 2008 13:15:18 +0000 Subject: [PATCH] cran2deb: bundles considered functional but need more testing. Add a few comments describing some of the functions and what they do. Make dependencies on bundles work by translating dependencies on packages up into their potential bundle where no individual package is available. Add the repository name to debian/rules. This should allow bioc packages to be build and included via cross-repo dependencies. Bundle packages have Provides: fields --- these aren't actually used but do no harm. Bundle packages have a Description: field of just the BundleDescription --- otherwise it may become too long. Look in the package subdirectories of bundles for 'src' to determine if a package is architecture independent or not. git-svn-id: svn://svn.r-forge.r-project.org/svnroot/cran2deb@37 edb9625f-4e0d-4859-8d74-9fd3b1da38cb --- pkg/trunk/cran2deb | 77 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/pkg/trunk/cran2deb b/pkg/trunk/cran2deb index b995ca1..801cba6 100755 --- a/pkg/trunk/cran2deb +++ b/pkg/trunk/cran2deb @@ -66,6 +66,7 @@ version.upstream <- function(pkgver) { # version.upstream . version.new = id version.update <- function(rver, prev_pkgver) { + # return the next debian package version prev_rver <- version.upstream(prev_pkgver) if (prev_rver == rver) { # increment the Debian revision @@ -90,6 +91,7 @@ base_pkgs=c('base', 'datasets','grDevices','graphics','grid', 'methods' # 'profile', 'datasets' repourl.as.debian <- function(url) { + # map the url to a repository onto its name in debian package naming if (length(grep('cran',url))) { return('cran') } @@ -100,6 +102,7 @@ repourl.as.debian <- function(url) { } pkgname.as.debian <- function(name,repopref=NULL,version=NULL,binary=T) { + # generate the debian package name corresponding to the R package name if (name %in% base_pkgs) { name = 'R' } @@ -130,29 +133,38 @@ pkgname.as.debian <- function(name,repopref=NULL,version=NULL,binary=T) { } setup <- function() { + # set up the working directory tmp <- tempfile('cran2deb') dir.create(tmp) return (tmp) } cleanup <- function(dir) { + # remove the working directory unlink(dir,recursive=T) invisible() } r.bundle.of <- function(pkgname) { - bundles <- available[!is.na(available[, "Bundle"]), "Contains"] + # returns the bundle containing pkgname or NA + bundles <- names(available[!is.na(available[, 'Bundle']), 'Contains']) # use the first bundle - for (bundle in names(bundles)) { - content <- strsplit(bundles[[bundle]],'[[:space:]]+')[[1]] - if (pkgname %in% content) { + for (bundle in bundles) { + if (pkgname %in% r.bundle.contains(bundle)) { return(bundle) } } return(NA) } +r.bundle.contains <- function(bundlename) { + return(strsplit(available[bundlename,'Contains'],'[[:space:]]+')[[1]]) +} + prepare.pkg <- function(dir, pkgname) { + # download and extract an R package named pkgname + # OR the bundle containing pkgname + # based loosely on library/utils/R/packages2.R::install.packages # should do nothing Debian specific @@ -207,6 +219,8 @@ debian_ok_licenses=c('GPL','LGPL','AGPL','ARTISTIC' #,'UNLIMITED' ,'BSD','MIT','APACHE','X11','MPL') is_acceptable_license <- function(license) { + # determine if license is acceptable + # compress spaces into a single space license = gsub('[[:blank:]]+',' ',license) # make all characters upper case @@ -218,8 +232,8 @@ is_acceptable_license <- function(license) { return(T) } # uninteresting urls - license = gsub('\\(?HTTP://WWW.GNU.ORG/[A-Z/._-]*\\)?','',license) - license = gsub('\\(?HTTP://WWW.X.ORG/[A-Z/._-]*\\)?','',license) + license = gsub('HTTP://WWW.GNU.ORG/[A-Z/._-]*','',license) + license = gsub('HTTP://WWW.X.ORG/[A-Z/._-]*','',license) # remove all punctuation license = gsub('[[:punct:]]+','',license) # remove any extra space introduced @@ -252,14 +266,17 @@ is_acceptable_license <- function(license) { } chomp <- function(x) { + # remove leading and trailing spaces return(sub('^[[:space:]]+','',sub('[[:space:]]+$','',x))) } host.arch <- function() { + # return the host system architecture system('dpkg-architecture -qDEB_HOST_ARCH',intern=T) } r.dependencies.of <- function(name=NULL,description=NULL) { + # find the immediate dependencies of an R package if (!is.null(name) && (name == 'R' || name %in% base_pkgs)) { return(data.frame()) } @@ -307,6 +324,12 @@ r.dependencies.of <- function(name=NULL,description=NULL) { } version = sub(pat,'\\3',dep) dep = sub(pat,'\\1',dep) + if (!(dep %in% rownames(available))) { + depb <- r.bundle.of(dep) + if (!is.na(depb)) { + dep <- depb + } + } deps <- rbind(deps,data.frame(list(name=dep ,version=version))) } @@ -315,6 +338,7 @@ r.dependencies.of <- function(name=NULL,description=NULL) { } r.dependency.closure <- function(fringe) { + # find the transitive closure of the dependencies of some R packages closure <- list() if (is.data.frame(fringe)) { fringe <- levels(fringe$name) @@ -413,6 +437,7 @@ generate.changelog <- function(pkg) { generate.rules <- function(pkg) { cat(paste('#!/usr/bin/make -f' + ,paste('debRreposname :=',pkg$repo) ,'include /usr/share/R/debian/r-cran.mk' ,'',sep='\n') ,file=pkg$debfile('rules')) @@ -461,7 +486,7 @@ generate.control <- function(pkg) { control[1,'Priority'] = 'optional' control[1,'Maintainer'] = maintainer control[1,'Build-Depends'] = paste(pkg$depends$build,collapse=', ') - control[1,'Standards-Version'] = '3.7.3.0' + control[1,'Standards-Version'] = '3.8.0' control[2,'Package'] = pkg$debname control[2,'Architecture'] = 'all' @@ -469,31 +494,44 @@ generate.control <- function(pkg) { control[2,'Architecture'] = 'any' } control[2,'Depends'] = paste(pkg$depends$bin,collapse=', ') + + # bundles provide virtual packages of their contents + if (pkg$is_bundle) { + control[2,'Provides'] = paste( + lapply(r.bundle.contains(pkg$name) + ,function(name) return(pkgname.as.debian(name + ,repopref=pkg$repo + ,binary=T))) + ,collapse=', ') + } + + # generate the description descr = 'GNU R package "' if ('Title' %in% colnames(pkg$description)) { descr = paste(descr,pkg$description[1,'Title'],sep='') } else { descr = paste(descr,pkg$name,sep='') } + if (pkg$is_bundle) { + long_descr <- pkg$description[1,'BundleDescription'] + } else { + long_descr <- pkg$description[1,'Description'] + } # using \n\n.\n\n is not very nice, but is necessary to make sure # the longer description does not begin on the synopsis line --- R's # write.dcf does not appear to have a nicer way of doing this. - descr = paste(descr,'"\n\n', pkg$description[1,'Description'], sep='') + descr = paste(descr,'"\n\n', long_descr, sep='') if ('URL' %in% colnames(pkg$description)) { descr = paste(descr,'\n\nURL: ',pkg$description[1,'URL'],sep='') } control[2,'Description'] = descr + # Debian policy says 72 char width; indent minimally write.dcf(control,file=pkg$debfile('control.in'),indent=1,width=72) write.dcf(control,indent=1,width=72) } prepare.new.debian <- function(pkg) { - # XXX: TODO: bundles do not work. - if ('Bundle' %in% names(pkg$description[1,])) { - stop('E: TODO: bundles') - } - # generate Debian version and name pkg$repo = repourl.as.debian(pkg$repoURL) pkg$debversion = version.new(pkg$version) @@ -542,7 +580,18 @@ prepare.new.debian <- function(pkg) { # says: ``The sources and headers for the compiled code are in src, plus # optionally file Makevars or Makefile.'' It seems unlikely that # architecture independent code would end up here. - pkg$archdep = file.exists(file.path(pkg$path,'src')) + if (pkg$is_bundle) { + # if it's a bundle, check each of the packages + pkg$archdep = F + for (pkgname in r.bundle.contains(pkg$name)) { + pkg$archdep = file.exists(file.path(pkg$path,pkgname,'src')) + if (pkg$archdep) { + break + } + } + } else { + pkg$archdep = file.exists(file.path(pkg$path,'src')) + } pkg$arch <- 'all' if (pkg$archdep) { pkg$arch <- host.arch() -- 2.39.5