]> git.donarmstrong.com Git - cran2deb.git/commitdiff
pkg/trunk -> trunk
authorblundellc <blundellc@edb9625f-4e0d-4859-8d74-9fd3b1da38cb>
Sat, 13 Sep 2008 13:38:05 +0000 (13:38 +0000)
committerblundellc <blundellc@edb9625f-4e0d-4859-8d74-9fd3b1da38cb>
Sat, 13 Sep 2008 13:38:05 +0000 (13:38 +0000)
git-svn-id: svn://svn.r-forge.r-project.org/svnroot/cran2deb@145 edb9625f-4e0d-4859-8d74-9fd3b1da38cb

102 files changed:
pkg/trunk/DESCRIPTION [deleted file]
pkg/trunk/R/build.R [deleted file]
pkg/trunk/R/db.R [deleted file]
pkg/trunk/R/debcontrol.R [deleted file]
pkg/trunk/R/debiannaming.R [deleted file]
pkg/trunk/R/debianpkg.R [deleted file]
pkg/trunk/R/getrpkg.R [deleted file]
pkg/trunk/R/license.R [deleted file]
pkg/trunk/R/log.R [deleted file]
pkg/trunk/R/rdep.R [deleted file]
pkg/trunk/R/util.R [deleted file]
pkg/trunk/R/version.R [deleted file]
pkg/trunk/R/zzz.R.in [deleted file]
pkg/trunk/README [deleted symlink]
pkg/trunk/configure [deleted file]
pkg/trunk/data/populate_depend_aliases [deleted file]
pkg/trunk/data/populate_forcedep [deleted file]
pkg/trunk/data/populate_licenses [deleted file]
pkg/trunk/data/populate_sysreq [deleted file]
pkg/trunk/data/quit [deleted file]
pkg/trunk/exec/autobuild [deleted file]
pkg/trunk/exec/build [deleted file]
pkg/trunk/exec/build_ctv [deleted file]
pkg/trunk/exec/build_some [deleted file]
pkg/trunk/exec/copy_find [deleted file]
pkg/trunk/exec/cran2deb [deleted file]
pkg/trunk/exec/cran_pkgs [deleted file]
pkg/trunk/exec/depend [deleted file]
pkg/trunk/exec/diagnose [deleted file]
pkg/trunk/exec/diagnose_ctv [deleted file]
pkg/trunk/exec/get_base_pkgs [deleted file]
pkg/trunk/exec/help [deleted file]
pkg/trunk/exec/latest_log [deleted file]
pkg/trunk/exec/license [deleted file]
pkg/trunk/exec/repopulate [deleted file]
pkg/trunk/exec/root [deleted file]
pkg/trunk/exec/update [deleted file]
pkg/trunk/exec/update_cache [deleted file]
pkg/trunk/inst/doc/DB_NOTES [deleted file]
pkg/trunk/inst/doc/DEPENDS [deleted file]
pkg/trunk/inst/doc/INSTALL_NOTES [deleted file]
pkg/trunk/inst/doc/PKG [deleted file]
pkg/trunk/inst/doc/README [deleted file]
pkg/trunk/inst/etc/dput.cf.in [deleted file]
pkg/trunk/inst/etc/hook/A80rjava [deleted file]
pkg/trunk/inst/etc/hook/B90lintian [deleted file]
pkg/trunk/inst/etc/hook/B91dpkg-i [deleted file]
pkg/trunk/inst/etc/hook/B92test-pkg [deleted file]
pkg/trunk/inst/etc/hook/D70aptupdate [deleted file]
pkg/trunk/inst/etc/mini-dinstall.conf.in [deleted file]
pkg/trunk/inst/etc/pbuilderrc.in [deleted file]
trunk/DESCRIPTION [new file with mode: 0644]
trunk/R/build.R [new file with mode: 0644]
trunk/R/db.R [new file with mode: 0644]
trunk/R/debcontrol.R [new file with mode: 0644]
trunk/R/debiannaming.R [new file with mode: 0644]
trunk/R/debianpkg.R [new file with mode: 0644]
trunk/R/getrpkg.R [new file with mode: 0644]
trunk/R/license.R [new file with mode: 0644]
trunk/R/log.R [new file with mode: 0644]
trunk/R/rdep.R [new file with mode: 0644]
trunk/R/util.R [new file with mode: 0644]
trunk/R/version.R [new file with mode: 0644]
trunk/R/zzz.R.in [new file with mode: 0644]
trunk/README [new symlink]
trunk/configure [new file with mode: 0755]
trunk/data/populate_depend_aliases [new file with mode: 0644]
trunk/data/populate_forcedep [new file with mode: 0644]
trunk/data/populate_licenses [new file with mode: 0644]
trunk/data/populate_sysreq [new file with mode: 0644]
trunk/data/quit [new file with mode: 0644]
trunk/exec/autobuild [new file with mode: 0755]
trunk/exec/build [new file with mode: 0755]
trunk/exec/build_ctv [new file with mode: 0755]
trunk/exec/build_some [new file with mode: 0755]
trunk/exec/copy_find [new file with mode: 0755]
trunk/exec/cran2deb [new file with mode: 0755]
trunk/exec/cran_pkgs [new file with mode: 0755]
trunk/exec/depend [new file with mode: 0755]
trunk/exec/diagnose [new file with mode: 0755]
trunk/exec/diagnose_ctv [new file with mode: 0755]
trunk/exec/get_base_pkgs [new file with mode: 0755]
trunk/exec/help [new file with mode: 0755]
trunk/exec/latest_log [new file with mode: 0644]
trunk/exec/license [new file with mode: 0755]
trunk/exec/repopulate [new file with mode: 0755]
trunk/exec/root [new file with mode: 0755]
trunk/exec/update [new file with mode: 0755]
trunk/exec/update_cache [new file with mode: 0755]
trunk/inst/doc/DB_NOTES [new file with mode: 0644]
trunk/inst/doc/DEPENDS [new file with mode: 0644]
trunk/inst/doc/INSTALL_NOTES [new file with mode: 0644]
trunk/inst/doc/PKG [new file with mode: 0644]
trunk/inst/doc/README [new file with mode: 0644]
trunk/inst/etc/dput.cf.in [new file with mode: 0644]
trunk/inst/etc/hook/A80rjava [new file with mode: 0755]
trunk/inst/etc/hook/B90lintian [new file with mode: 0755]
trunk/inst/etc/hook/B91dpkg-i [new file with mode: 0755]
trunk/inst/etc/hook/B92test-pkg [new file with mode: 0755]
trunk/inst/etc/hook/D70aptupdate [new file with mode: 0755]
trunk/inst/etc/mini-dinstall.conf.in [new file with mode: 0644]
trunk/inst/etc/pbuilderrc.in [new file with mode: 0644]

diff --git a/pkg/trunk/DESCRIPTION b/pkg/trunk/DESCRIPTION
deleted file mode 100644 (file)
index d591695..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-Package: cran2deb
-Version: 0.0
-Date: 2008-07-14
-Title: Convert CRAN packages into Debian packages
-Author: Charles Blundell <blundellc@gmail.com>, with assistance from Dirk Eddelbuettel <>
-Maintainer: Charles Blundell <blundellc@gmail.com>
-Depends: ctv, utils, RSQLite, DBI, digest
-SystemRequirements: littler, rc, pbuilder, debian toolchain, web server, mini-dinstall, curl
-Description: Convert CRAN packages into Debian packages, mostly unassisted, easily
- subverting the R package system.
-License: GPL-3
diff --git a/pkg/trunk/R/build.R b/pkg/trunk/R/build.R
deleted file mode 100644 (file)
index 4ca1923..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-
-build <- function(name,extra_deps,force=F) {
-    # can't, and hence don't need to, build base packages
-    if (name %in% base_pkgs) {
-        return(T)
-    }
-    log_clear()
-    dir <- setup()
-
-    # obtain the Debian version-to-be
-    version <- try(new_build_version(name))
-    if (inherits(version,'try-error')) {
-        error('failed to build',name)
-        return(NULL)
-    }
-
-    result <- try((function() {
-        if (!force && !needs_build(name,version)) {
-            notice('skipping build of',name)
-            return(NULL)
-        }
-
-        pkg <- prepare_new_debian(prepare_pkg(dir,name),extra_deps)
-        if (pkg$debversion != version) {
-            fail('expected Debian version',version,'not equal to actual version',pkg$debversion)
-        }
-        # delete the current archive (XXX: assumes mini-dinstall)
-        for (subdir in c('mini-dinstall','unstable')) {
-            path = file.path(dinstall_archive,subdir)
-            if (file.exists(path)) {
-                unlink(path,recursive=T)
-            }
-        }
-
-        # delete notes of upload
-        file.remove(Sys.glob(file.path(pbuilder_results,'*.upload')))
-
-        # make mini-dinstall generate the skeleton of the archive
-        ret = log_system('umask 002;mini-dinstall --batch -c',dinstall_config)
-        if (ret != 0) {
-            fail('failed to create archive')
-        }
-
-        # pull in all the R dependencies
-        notice('R dependencies:',paste(pkg$depends$r,collapse=', '))
-        for (dep in pkg$depends$r) {
-            if (pkgname_as_debian(dep) %in% debian_pkgs) {
-                notice('using Debian package of',dep)
-                next
-            }
-            # otherwise, convert to source package name
-            srcdep = pkgname_as_debian(dep,binary=F)
-
-            notice('uploading',srcdep)
-            ret = log_system('umask 002;dput','-c',shQuote(dput_config),'local'
-                        ,changesfile(srcdep))
-            if (ret != 0) {
-                fail('upload of dependency failed! maybe you did not build it first?')
-            }
-        }
-        build_debian(pkg)
-
-        # upload the package
-        ret = log_system('umask 002;dput','-c',shQuote(dput_config),'local'
-                    ,changesfile(pkg$srcname,pkg$debversion))
-        if (ret != 0) {
-            fail('upload failed!')
-        }
-
-        # delete the current archive (XXX: assumes mini-dinstall)
-        # this is handy for group operation
-        for (subdir in c('mini-dinstall','unstable')) {
-            path = file.path(dinstall_archive,subdir)
-            if (file.exists(path)) {
-                unlink(path,recursive=T)
-            }
-        }
-
-        return(pkg$debversion)
-    })())
-    cleanup(dir)
-    if (is.null(result)) {
-        # nothing was done so escape asap.
-        return(result)
-    }
-
-    # otherwise record progress
-    failed = inherits(result,'try-error')
-    if (failed) {
-        error('failure of',name,'means these packages will fail:'
-                     ,paste(r_dependency_closure(name,forward_arcs=F),collapse=', '))
-    }
-    db_record_build(name, version, log_retrieve(), !failed)
-    return(!failed)
-}
-
-needs_build <- function(name,version) {
-    # see if the last build was successful
-    build <- db_latest_build(name)
-    if (!is.null(build) && build$success) {
-        # then something must have changed for us to attempt this
-        # build
-        if (build$r_version == version_upstream(version) &&
-            build$deb_epoch == version_epoch(version) &&
-            build$db_version == db_get_version()) {
-            return(F)
-        }
-    } else {
-        # always rebuild on failure or no record
-        return(T)
-    }
-    # see if it has already been built
-    srcname <- pkgname_as_debian(name,binary=F)
-    debname <- pkgname_as_debian(name,binary=T)
-    if (file.exists(changesfile(srcname, version))) {
-        notice('already built',srcname,'version',version)
-        return(F)
-    }
-
-    # XXX: what about building newer versions of Debian packages?
-    if (debname %in% debian_pkgs) {
-        notice(srcname,' exists in Debian (perhaps a different version)')
-        return(F)
-    }
-
-    rm(debname,srcname)
-    return(T)
-}
-
-build_debian <- function(pkg) {
-    wd <- getwd()
-    setwd(pkg$path)
-    notice('building Debian package'
-                 ,pkg$debname
-                 ,paste('(',pkg$debversion,')',sep='')
-                 ,'...')
-
-    cmd = paste('pdebuild --configfile',shQuote(pbuilder_config))
-    if (version_revision(pkg$debversion) > 2) {
-        cmd = paste(cmd,'--debbuildopts','-sd')
-        notice('build should exclude original source')
-    }
-    ret = log_system(cmd)
-    setwd(wd)
-    if (ret != 0) {
-        fail('Failed to build package.')
-    }
-}
-
diff --git a/pkg/trunk/R/db.R b/pkg/trunk/R/db.R
deleted file mode 100644 (file)
index f6a4c07..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-
-db_start <- function() {
-    drv <- dbDriver('SQLite')
-    con <- dbConnect(drv, dbname=file.path(cache_root,'cran2deb.db'))
-    if (!dbExistsTable(con,'sysreq_override')) {
-        dbGetQuery(con,paste('CREATE TABLE sysreq_override ('
-                  ,' depend_alias TEXT NOT NULL'
-                  ,',r_pattern TEXT PRIMARY KEY NOT NULL'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'debian_dependency')) {
-        dbGetQuery(con,paste('CREATE TABLE debian_dependency ('
-                  ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
-                  ,',alias TEXT NOT NULL'
-                  ,',build INTEGER NOT NULL'
-                  ,',debian_pkg TEXT NOT NULL'
-                  ,',UNIQUE (alias,build,debian_pkg)'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'forced_depends')) {
-        dbGetQuery(con,paste('CREATE TABLE forced_depends ('
-                  ,' r_name TEXT NOT NULL'
-                  ,',depend_alias TEXT NOT NULL'
-                  ,',PRIMARY KEY (r_name,depend_alias)'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'license_override')) {
-        dbGetQuery(con,paste('CREATE TABLE license_override ('
-                  ,' name TEXT PRIMARY KEY NOT NULL'
-                  ,',accept INT NOT NULL'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'license_hashes')) {
-        dbGetQuery(con,paste('CREATE TABLE license_hashes ('
-                  ,' name TEXT NOT NULL'
-                  ,',sha1 TEXT PRIMARY KEY NOT NULL'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'database_versions')) {
-        dbGetQuery(con,paste('CREATE TABLE database_versions ('
-                  ,' version INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
-                  ,',version_date INTEGER NOT NULL'
-                  ,',base_epoch INTEGER NOT NULL'
-                  ,')'))
-        db_add_version(con,1,0)
-    }
-    if (!dbExistsTable(con,'packages')) {
-        dbGetQuery(con,paste('CREATE TABLE packages ('
-                  ,' package TEXT PRIMARY KEY NOT NULL'
-                  ,',latest_r_version TEXT'
-                  ,')'))
-    }
-    if (!dbExistsTable(con,'builds')) {
-        dbGetQuery(con,paste('CREATE TABLE builds ('
-                  ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
-                  ,',package TEXT NOT NULL'
-                  ,',r_version TEXT NOT NULL'
-                  ,',deb_epoch INTEGER NOT NULL'
-                  ,',deb_revision INTEGER NOT NULL'
-                  ,',db_version INTEGER NOT NULL'
-                  ,',date_stamp TEXT NOT NULL'
-                  ,',git_revision TEXT NOT NULL'
-                  ,',success INTEGER NOT NULL'
-                  ,',log TEXT'
-                  ,',UNIQUE(package,r_version,deb_epoch,deb_revision,db_version)'
-                  ,')'))
-    }
-    return(con)
-}
-
-db_stop <- function(con,bump=F) {
-    if (bump) {
-        db_bump(con)
-    }
-    dbDisconnect(con)
-}
-
-db_quote <- function(text) {
-    return(paste('\'', gsub('([\'"])','\\1\\1',text),'\'',sep=''))
-}
-
-db_now <- function() {
-    return(as.integer(gsub('-','',Sys.Date())))
-}
-
-db_cur_version <- function(con) {
-    return(as.integer(dbGetQuery(con, 'SELECT max(version) FROM database_versions')[[1]]))
-}
-
-db_base_epoch <- function(con) {
-    return(as.integer(dbGetQuery(con,
-        paste('SELECT max(base_epoch) FROM database_versions'
-             ,'WHERE version IN (SELECT max(version) FROM database_versions)'))[[1]]))
-}
-
-db_get_base_epoch <- function() {
-    con <- db_start()
-    v <- db_base_epoch(con)
-    db_stop(con)
-    return(v)
-}
-
-db_get_version <- function() {
-    con <- db_start()
-    v <- db_cur_version(con)
-    db_stop(con)
-    return(v)
-}
-
-db_add_version <- function(con, version, epoch) {
-    dbGetQuery(con,paste('INSERT INTO database_versions (version,version_date,base_epoch)'
-              ,'VALUES (',as.integer(version),',',db_now(),',',as.integer(epoch),')'))
-}
-
-db_bump <- function(con) {
-    db_add_version(con,db_cur_version(con)+1, db_base_epoch(con))
-}
-
-db_bump_epoch <- function(con) {
-    db_add_version(con,db_cur_version(con)+1, db_base_epoch(con)+1)
-}
-
-db_sysreq_override <- function(sysreq_text) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                    'SELECT DISTINCT depend_alias FROM sysreq_override WHERE'
-                            ,db_quote(tolower(sysreq_text)),'LIKE r_pattern'))
-    db_stop(con)
-    if (length(results) == 0) {
-        return(NULL)
-    }
-    return(results$depend_alias)
-}
-
-db_add_sysreq_override <- function(pattern,depend_alias) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                     'INSERT OR REPLACE INTO sysreq_override'
-                    ,'(depend_alias, r_pattern) VALUES ('
-                    ,' ',db_quote(tolower(depend_alias))
-                    ,',',db_quote(tolower(pattern))
-                    ,')'))
-    db_stop(con,TRUE)
-}
-
-db_sysreq_overrides <- function() {
-    con <- db_start()
-    overrides <- dbGetQuery(con,paste('SELECT * FROM sysreq_override'))
-    db_stop(con)
-    return(overrides)
-}
-
-db_get_depends <- function(depend_alias,build=F) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                    'SELECT DISTINCT debian_pkg FROM debian_dependency WHERE'
-                    ,db_quote(tolower(depend_alias)),'= alias'
-                    ,'AND',as.integer(build),'= build'))
-    db_stop(con)
-    return(results$debian_pkg)
-}
-
-db_add_depends <- function(depend_alias,debian_pkg,build=F) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                     'INSERT OR REPLACE INTO debian_dependency'
-                    ,'(alias, build, debian_pkg) VALUES ('
-                    ,' ',db_quote(tolower(depend_alias))
-                    ,',',as.integer(build)
-                    ,',',db_quote(tolower(debian_pkg))
-                    ,')'))
-    db_stop(con,TRUE)
-}
-
-db_depends <- function() {
-    con <- db_start()
-    depends <- dbGetQuery(con,paste('SELECT * FROM debian_dependency'))
-    db_stop(con)
-    return(depends)
-}
-
-db_get_forced_depends <- function(r_name) {
-    con <- db_start()
-    forced_depends <- dbGetQuery(con,
-                paste('SELECT depend_alias FROM forced_depends WHERE'
-                     ,db_quote(r_name),'= r_name'))
-    db_stop(con)
-    return(forced_depends$depend_alias)
-}
-
-db_add_forced_depends <- function(r_name, depend_alias) {
-    if (!length(db_get_depends(depend_alias,build=F)) &&
-        !length(db_get_depends(depend_alias,build=T))) {
-        fail('Debian dependency alias',depend_alias,'is not know,'
-                  ,'yet trying to force a dependency on it?')
-    }
-    con <- db_start()
-    dbGetQuery(con,
-            paste('INSERT OR REPLACE INTO forced_depends (r_name, depend_alias)'
-                 ,'VALUES (',db_quote(r_name),',',db_quote(depend_alias),')'))
-    db_stop(con,TRUE)
-}
-
-db_forced_depends <- function() {
-    con <- db_start()
-    depends <- dbGetQuery(con,paste('SELECT * FROM forced_depends'))
-    db_stop(con)
-    return(depends)
-}
-
-db_license_override_name <- function(name) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                    'SELECT DISTINCT accept FROM license_override WHERE'
-                            ,db_quote(tolower(name)),'= name'))
-    db_stop(con)
-    if (length(results) == 0) {
-        return(NULL)
-    }
-    return(as.logical(results$accept))
-}
-
-db_add_license_override <- function(name,accept) {
-    notice('adding',name,'accept?',accept)
-    if (accept != TRUE && accept != FALSE) {
-        fail('accept must be TRUE or FALSE')
-    }
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                     'INSERT OR REPLACE INTO license_override'
-                    ,'(name, accept) VALUES ('
-                    ,' ',db_quote(tolower(name))
-                    ,',',as.integer(accept)
-                    ,')'))
-    db_stop(con,TRUE)
-}
-
-db_license_override_hash <- function(license_sha1) {
-    con <- db_start()
-    results <- dbGetQuery(con,paste(
-                     'SELECT DISTINCT accept FROM license_override'
-                    ,'INNER JOIN license_hashes'
-                    ,'ON license_hashes.name = license_override.name WHERE'
-                    ,db_quote(tolower(license_sha1)),'= license_hashes.sha1'))
-    db_stop(con)
-    if (length(results) == 0) {
-        return(NULL)
-    }
-    return(as.logical(results$accept))
-}
-
-db_license_overrides <- function() {
-    con <- db_start()
-    overrides <- dbGetQuery(con,paste('SELECT * FROM license_override'))
-    hashes    <- dbGetQuery(con,paste('SELECT * FROM license_hashes'))
-    db_stop(con)
-    return(list(overrides=overrides,hashes=hashes))
-}
-
-db_add_license_hash <- function(name,license_sha1) {
-    if (is.null(db_license_override_name(name))) {
-        fail('license',name,'is not know, yet trying to add a hash for it?')
-    }
-    notice('adding hash',license_sha1,'for',name)
-    con <- db_start()
-    dbGetQuery(con,paste(
-         'INSERT OR REPLACE INTO license_hashes'
-        ,'(name, sha1) VALUES ('
-        ,' ',db_quote(tolower(name))
-        ,',',db_quote(tolower(license_sha1))
-        ,')'))
-    db_stop(con,TRUE)
-}
-
-
-db_update_package_versions <- function() {
-    con <- db_start()
-    for (package in available[,'Package']) {
-        dbGetQuery(con, paste('INSERT OR REPLACE INTO packages (package,latest_r_version)'
-                             ,'VALUES (',db_quote(package)
-                             ,',',db_quote(available[package,'Version']),')'))
-    }
-    db_stop(con)
-}
-
-db_record_build <- function(package, deb_version, log, success=F) {
-    con <- db_start()
-    dbGetQuery(con,paste('INSERT OR REPLACE INTO builds'
-                        ,'(package,r_version,deb_epoch,deb_revision,db_version,success,date_stamp,git_revision,log)'
-                        ,'VALUES'
-                        ,'(',db_quote(package)
-                        ,',',db_quote(version_upstream(deb_version))
-                        ,',',db_quote(version_epoch(deb_version))
-                        ,',',db_quote(version_revision(deb_version))
-                        ,',',db_cur_version(con)
-                        ,',',as.integer(success)
-                        ,',',db_quote(format(Sys.time(),'%a, %d %b %Y %H:%M:%S %z'))
-                        ,',',db_quote(git_revision)
-                        ,',',db_quote(paste(log, collapse='\n'))
-                        ,')'))
-    db_stop(con)
-}
-
-db_builds <- function(pkgname) {
-    # returns all successful builds
-    con <- db_start()
-    build <- dbGetQuery(con, paste('SELECT * FROM builds'
-                       ,'WHERE success = 1'
-                       ,'AND package =',db_quote(pkgname)))
-    db_stop(con)
-    if (length(build) == 0) {
-        return(NULL)
-    }
-    build$success <- as.logical(build$success)
-    return(build)
-}
-
-db_latest_build <- function(pkgname) {
-    con <- db_start()
-    build <- dbGetQuery(con, paste('SELECT * FROM builds'
-                       ,'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
-                       ,              'GROUP BY package) AS last'
-                       ,'WHERE id = max_id'
-                       ,'AND builds.package =',db_quote(pkgname)))
-    db_stop(con)
-    if (length(build) == 0) {
-        return(NULL)
-    }
-    build$success <- as.logical(build$success)
-    return(build)
-}
-
-db_latest_build_version <- function(pkgname) {
-    build <- db_latest_build(pkgname)
-    if (is.null(build)) {
-        return(NULL)
-    }
-    return(version_new(build$r_version, build$deb_revision, build$deb_epoch))
-}
-
-db_latest_build_status <- function(pkgname) {
-    build <- db_latest_build(pkgname)
-    if (is.null(build)) {
-        return(NULL)
-    }
-    return(list(build$success,build$log))
-}
-
-db_outdated_packages <- function() {
-    con <- db_start()
-    packages <- dbGetQuery(con,paste('SELECT packages.package FROM packages'
-               ,'LEFT OUTER JOIN ('
-               # extract the latest attempt at building each package
-               ,      'SELECT * FROM builds'
-               ,      'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
-               ,                    'GROUP BY package) AS last'
-               ,      'WHERE id = max_id) AS build'
-               ,'ON build.package = packages.package'
-               # outdated iff:
-               # - there is no latest build
-               ,'WHERE build.package IS NULL'
-               # - the database has changed since last build
-               ,'OR build.db_version < (SELECT max(version) FROM database_versions)'
-               # - the debian epoch has been bumped up
-               ,'OR build.deb_epoch < (SELECT max(base_epoch) FROM database_versions'
-               ,                        'WHERE version IN ('
-               ,                            'SELECT max(version) FROM database_versions))'
-               # - the latest build is not of the latest R version
-               ,'OR build.r_version != packages.latest_r_version'
-               ))$package
-    db_stop(con)
-    return(packages)
-}
-
diff --git a/pkg/trunk/R/debcontrol.R b/pkg/trunk/R/debcontrol.R
deleted file mode 100644 (file)
index 84d9933..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-get_dependencies <- function(pkg,extra_deps) {
-    # determine dependencies
-    dependencies <- r_dependencies_of(description=pkg$description)
-    depends <- list()
-    # these are used for generating the Depends fields
-    as_deb <- function(r,build) {
-        return(pkgname_as_debian(paste(dependencies[r,]$name)
-                                ,version=dependencies[r,]$version
-                                ,repopref=pkg$repo
-                                ,build=build))
-    }
-    depends$bin <- lapply(rownames(dependencies), as_deb, build=F)
-    depends$build <- lapply(rownames(dependencies), as_deb, build=T)
-    # add the command line dependencies
-    depends$bin = c(extra_deps$deb,depends$bin)
-    depends$build = c(extra_deps$deb,depends$build)
-    # add the system requirements
-    if ('SystemRequirements' %in% colnames(pkg$description)) {
-        sysreq <- sysreqs_as_debian(pkg$description[1,'SystemRequirements'])
-        depends$bin = c(sysreq$bin,depends$bin)
-        depends$build = c(sysreq$build,depends$build)
-    }
-
-    forced <- forced_deps_as_debian(pkg$name)
-    if (length(forced)) {
-        notice('forced build dependencies:',paste(forced$build, collapse=', '))
-        notice('forced binary dependencies:',paste(forced$bin, collapse=', '))
-        depends$bin = c(forced$bin,depends$bin)
-        depends$build = c(forced$build,depends$build)
-    }
-
-    # make sure we depend upon R in some way...
-    if (!length(grep('^r-base',depends$build))) {
-        depends$build = c(depends$build,pkgname_as_debian('R',version='>= 2.7.0',build=T))
-        depends$bin   = c(depends$bin,  pkgname_as_debian('R',version='>= 2.7.0',build=F))
-    }
-    # also include stuff to allow tcltk to build (suggested by Dirk)
-    depends$build = c(depends$build,'xvfb','xauth','xfonts-base')
-
-    # make all bin dependencies build dependencies.
-    depends$build = c(depends$build, depends$bin)
-
-    # remove duplicates
-    depends <- lapply(depends,unique)
-
-    # append the Debian dependencies
-    depends$build=c(depends$build,'debhelper (>> 4.1.0)','cdbs')
-    if (pkg$archdep) {
-        depends$bin=c(depends$bin,'${shlibs:Depends}')
-    }
-
-    # the names of dependent source packages (to find the .changes file to
-    # upload via dput). these can be found recursively.
-    depends$r = r_dependency_closure(dependencies)
-    # append command line dependencies
-    depends$r = c(extra_deps$r, depends$r)
-    return(depends)
-}
-
-sysreqs_as_debian <- function(sysreq_text) {
-    # form of this field is unspecified (ugh) but most people seem to stick
-    # with this
-    aliases <- c()
-    sysreq_text <- gsub('[[:space:]]and[[:space:]]',' , ',tolower(sysreq_text))
-    for (sysreq in strsplit(sysreq_text,'[[:space:]]*,[[:space:]]*')[[1]]) {
-        startreq = sysreq
-        # constant case
-        sysreq = tolower(sysreq)
-        # drop version information/comments for now
-        sysreq = gsub('[[][^])]*[]]','',sysreq)
-        sysreq = gsub('\\([^)]*\\)','',sysreq)
-        sysreq = gsub('[[][^])]*[]]','',sysreq)
-        sysreq = gsub('version','',sysreq)
-        sysreq = gsub('from','',sysreq)
-        sysreq = gsub('[<>=]*[[:space:]]*[[:digit:]]+[[:digit:].+:~-]*','',sysreq)
-        # byebye URLs
-        sysreq = gsub('(ht|f)tps?://[[:alnum:]!?*"\'(),%$_@.&+/=-]*','',sysreq)
-        # squish out space
-        sysreq = chomp(gsub('[[:space:]]+',' ',sysreq))
-        alias <- db_sysreq_override(sysreq)
-        if (is.null(alias)) {
-            error('do not know what to do with SystemRequirement:',sysreq)
-            error('original SystemRequirement:',startreq)
-            fail('unmet system requirement')
-        }
-        notice('mapped SystemRequirement',startreq,'onto',alias,'via',sysreq)
-        aliases = c(aliases,alias)
-    }
-    return(map_aliases_to_debian(aliases))
-}
-
-forced_deps_as_debian <- function(r_name) {
-    aliases <- db_get_forced_depends(r_name)
-    return(map_aliases_to_debian(aliases))
-}
-
-map_aliases_to_debian <- function(aliases) {
-    if (!length(aliases)) {
-        return(aliases)
-    }
-    debs <- list()
-    debs$bin = unlist(sapply(aliases, db_get_depends))
-    debs$build = unlist(sapply(aliases, db_get_depends, build=T))
-    debs$bin = debs$bin[debs$bin != 'build-essential']
-    debs$build = debs$build[debs$build != 'build-essential']
-    return(debs)
-}
-
-generate_control <- function(pkg) {
-    # construct control file
-    control = data.frame()
-    control[1,'Source'] = pkg$srcname
-    control[1,'Section'] = 'math'
-    control[1,'Priority'] = 'optional'
-    control[1,'Maintainer'] = maintainer
-    control[1,'Build-Depends'] = paste(pkg$depends$build,collapse=', ')
-    control[1,'Standards-Version'] = '3.8.0'
-
-    control[2,'Package'] = pkg$debname
-    control[2,'Architecture'] = 'all'
-    if (pkg$archdep) {
-        control[2,'Architecture'] = 'any'
-    }
-    control[2,'Depends'] = paste(pkg$depends$bin,collapse=', ')
-
-#   # bundles provide virtual packages of their contents
-#   # unnecessary for now; cran2deb converts R bundles itself
-#    if (pkg$is_bundle) {
-#        control[2,'Provides'] = paste(
-#                    lapply(r_bundle_contains(pkg$name)
-#                          ,function(name) return(pkgname_as_debian(paste(name)
-#                                                                  ,repopref=pkg$repo)))
-#                          ,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']
-    }
-
-    if (length(long_descr) < 1) {
-        # bypass lintian extended-description-is-empty for which we care not.
-        long_descr <- paste('The author/maintainer of this package'
-                           ,'did not care to enter a longer 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', 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)
-}
-
diff --git a/pkg/trunk/R/debiannaming.R b/pkg/trunk/R/debiannaming.R
deleted file mode 100644 (file)
index 83c0ab5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-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')
-    }
-    if (length(grep('bioc',url))) {
-        return('bioc')
-    }
-    fail('unknown repository',url)
-}
-
-pkgname_as_debian <- function(name,repopref=NULL,version=NULL,binary=T,build=F) {
-    # generate the debian package name corresponding to the R package name
-    if (name %in% base_pkgs) {
-        name = 'R'
-    }
-    if (name == 'R') {
-        # R is special.
-        if (binary) {
-            if (build) {
-                debname='r-base-dev'
-            } else {
-                debname='r-base-core'
-            }
-        } else {
-            debname='R'
-        }
-    } else {
-        # XXX: data.frame rownames are unique, so always override repopref for
-        #      now.
-        if (!(name %in% rownames(available))) {
-            bundle <- r_bundle_of(name)
-            if (!is.null(bundle)) {
-                name <- bundle
-            }
-        }
-        debname = tolower(name)
-        if (binary) {
-            if (name %in% rownames(available)) {
-                repopref <- tolower(repourl_as_debian(available[name,'Repository']))
-            } else if (is.null(repopref)) {
-                repopref <- 'unknown'
-            }
-            debname = paste('r',repopref,debname,sep='-')
-        }
-    }
-    if (!is.null(version) && length(version) > 1) {
-        debname = paste(debname,' (',version,')',sep='')
-    }
-    return(debname)
-}
-
diff --git a/pkg/trunk/R/debianpkg.R b/pkg/trunk/R/debianpkg.R
deleted file mode 100644 (file)
index 416a911..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-append_build_from_pkg <- function(pkg, builds) {
-    pkg_build <- data.frame(id = -1     # never used
-                           ,package = pkg$name
-                           ,r_version = version_upstream(pkg$debversion)
-                           ,deb_epoch = version_epoch(pkg$debversion)
-                           ,deb_revision = version_revision(pkg$debversion)
-                           ,db_version = db_get_version()
-                           ,date_stamp = pkg$date_stamp
-                           ,git_revision = git_revision
-                           ,success = 1 # never used
-                           ,log = ''    # never used
-                           )
-    return(cbind(data.frame(srcname=pkg$srcname), rbind(builds, pkg_build)))
-}
-
-generate_changelog <- function(pkg) {
-    # TODO: ``Writing R extensions'' mentions that a package may also have
-    # {NEWS,ChangeLog} files.
-    builds <- append_build_from_pkg(pkg, db_builds(pkg$name))
-    sapply(rev(rownames(builds)), function(b, changelog) generate_changelog_entry(builds[b,], changelog), pkg$debfile('changelog.in'))
-}
-
-generate_changelog_entry <- function(build, changelog) {
-    # TODO: should say 'New upstream release' when necessary
-    debversion <- version_new(build$r_version, build$deb_revision, build$deb_epoch)
-    cat(paste(paste(build$srcname,' (',debversion,') unstable; urgency=low',sep='')
-             ,'' ,paste('  * cran2deb ',build$git_revision
-                       ,' with DB version ',as.integer(build$db_version),'.',sep='')
-             ,'',paste(' --',maintainer,'',build$date_stamp)
-             ,'','','',sep='\n'),file=changelog, append=TRUE)
-}
-
-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'))
-    Sys.chmod(pkg$debfile('rules'),'0700')
-}
-
-generate_copyright <- function(pkg) {
-    # generate_copyright file; we trust DESCRIPTION
-
-    # if maintainer is missing then try to use author
-    if (!('Maintainer' %in% colnames(pkg$description))) {
-        if ('Author' %in% colnames(pkg$description)) {
-            maintainer = pkg$description[1,'Author']
-        } else {
-            fail('Maintainer and Author not defined in R DESCRIPTION')
-        }
-    } else {
-        maintainer = pkg$description[1,'Maintainer']
-    }
-    # likewise if author is missing then try to use maintainer
-    if (!('Author' %in% colnames(pkg$description))) {
-        author = maintainer
-    } else {
-        author = pkg$description[1,'Author']
-    }
-
-    writeLines(strwrap(
-        paste('This Debian package of the GNU R package',pkg$name
-             ,'was generated automatically using cran2deb by'
-             ,paste(maintainer,'.',sep='')
-             ,''
-             ,'The original GNU R package is Copyright (C) '
-             # TODO: copyright start date, true copyright date
-             ,format(Sys.time(),'%Y')
-             ,author
-             ,'and possibly others.'
-             ,''
-             ,'The original GNU R package is maintained by'
-             ,maintainer,'and was obtained from:'
-             ,''
-             ,pkg$repoURL
-             ,''
-             ,''
-             ,'The GNU R package DESCRIPTION offers a'
-             ,'Copyright licenses under the terms of the license:'
-             ,pkg$license,'.  On a Debian GNU/Linux system, common'
-             ,'licenses are included in the directory'
-             ,'/usr/share/common-licenses/.'
-             ,''
-             ,'The DESCRIPTION file for the original GNU R package '
-             ,'can be found in '
-             ,file.path('/usr/lib/R/site-library'
-                   ,pkg$debname
-                   ,'DESCRIPTION'
-                   )
-             ,sep='\n'), width=72), con=pkg$debfile('copyright.in'))
-}
-
-prepare_new_debian <- function(pkg,extra_deps) {
-    # generate Debian version and name
-    pkg$debversion = new_build_version(pkg$name)
-
-    # make the debian/ directory
-    debdir <- file.path(pkg$path,'debian')
-    pkg$debfile <- function(x) { file.path(debdir,x) }
-    unlink(debdir,recursive=T)
-    dir.create(debdir)
-
-    # see if this is an architecture-dependent package.
-    # heuristic: if /src/ exists in pkg$path, then this is an
-    #            architecture-dependent package.
-    # CRAN2DEB.pm is a bit fancier about this but ``Writing R extensions''
-    # 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.
-    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()
-    }
-
-    pkg$license <- accept_license(pkg)
-    pkg$depends <- get_dependencies(pkg,extra_deps)
-    generate_changelog(pkg)
-    generate_rules(pkg)
-    generate_copyright(pkg)
-    generate_control(pkg)
-
-    # convert text to utf8 (who knows what the original character set is --
-    # let's hope iconv DTRT).
-    for (file in c('control','changelog','copyright')) {
-        log_system('iconv -o ',shQuote(pkg$debfile(file))
-                    ,' -t utf8 -c '
-                    ,shQuote(pkg$debfile(paste(file,'in',sep='.'))))
-        file.remove(pkg$debfile(paste(file,'in',sep='.')))
-    }
-    return(pkg)
-}
diff --git a/pkg/trunk/R/getrpkg.R b/pkg/trunk/R/getrpkg.R
deleted file mode 100644 (file)
index 5273a1f..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-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()
-}
-
-download_pkg <- function(dir, pkgname) {
-    # download pkgname into dir, and construct some metadata
-
-    # record some basic information
-    pkg <- pairlist()
-    pkg$date_stamp = format(Sys.time(),'%a, %d %b %Y %H:%M:%S %z')
-    pkg$name = pkgname
-    pkg$repoURL = available[pkgname,'Repository']
-    pkg$repo = repourl_as_debian(pkg$repoURL)
-    if (!length(grep('^[A-Za-z0-9][A-Za-z0-9+.-]+$',pkg$name))) {
-        fail('Cannot convert package name into a Debian name',pkg$name)
-    }
-    pkg$srcname = pkgname_as_debian(pkg$name,binary=F)
-    pkg$debname = pkgname_as_debian(pkg$name,repo=pkg$repo)
-    pkg$version <- available[pkgname,'Version']
-
-    # see if we have already built this release and uploaded it.
-    debfn <- file.path(pbuilder_results, paste(pkg$srcname, '_', pkg$version, '.orig.tar.gz', sep=''))
-    pkg$need_repack = FALSE
-    if (file.exists(debfn)) {
-        # if so, use the existing archive. this is good for three reasons:
-        # 1. it saves downloading the archive again
-        # 2. the repacking performed below changes the MD5 sum of the archive
-        #    which upsets some Debian archive software.
-        # 3. why repack more than once?
-        pkg$archive <- file.path(dir, basename(debfn))
-        file.copy(debfn,pkg$archive)
-        pkg$path = file.path(dir, paste(pkg$srcname ,pkg$version ,sep='-'))
-    } else {
-        # see if we have a local mirror in /srv/R
-        use_local = FALSE
-        if (pkg$repo == 'cran') {
-            localfn = file.path('/srv/R/Repositories/CRAN/src/contrib',paste(pkg$name,'_',pkg$version,'.tar.gz',sep=''))
-            use_local = file.exists(localfn)
-        } else if (pkg$repo == 'bioc') {
-            localfn = file.path('/srv/R/Repositories/Bioconductor/release/bioc/src/contrib',paste(pkg$name,'_',pkg$version,'.tar.gz',sep=''))
-            use_local = file.exists(localfn)
-        }
-
-        fn <- paste(pkgname, '_', pkg$version, '.tar.gz', sep='')
-        archive <- file.path(dir, fn)
-
-        if (use_local) {
-            file.copy(localfn, archive)
-        } else {
-            # use this instead of download.packages as it is more resilient to
-            # dodgy network connections (hello BT 'OpenWorld', bad ISP)
-            url <- paste(available[pkgname,'Repository'], fn, sep='/')
-            # don't log the output -- we don't care!
-            ret <- system(paste('curl','-o',shQuote(archive),'-m 720 --retry 5',shQuote(url)))
-            if (ret != 0) {
-                fail('failed to download',url)
-            }
-            # end of download.packages replacement
-        }
-
-        if (length(grep('\\.\\.',archive)) || normalizePath(archive) != archive) {
-            fail('funny looking path',archive)
-        }
-        pkg$path = sub("_\\.(zip|tar\\.gz)", ""
-                      ,gsub(.standard_regexps()$valid_package_version, ""
-                      ,archive))
-        pkg$archive = archive
-        # this is not a Debian conformant archive
-        pkg$need_repack = TRUE
-    }
-    return(pkg)
-}
-
-repack_pkg <- function(pkg) {
-    # re-pack into a Debian-named archive with a Debian-named directory.
-    debpath = file.path(dirname(pkg$archive)
-                   ,paste(pkg$srcname
-                         ,pkg$version
-                         ,sep='-'))
-    file.rename(pkg$path, debpath)
-    pkg$path = debpath
-    debarchive = file.path(dirname(pkg$archive)
-                          ,paste(pkg$srcname,'_'
-                                ,pkg$version,'.orig.tar.gz'
-                                ,sep=''))
-    wd <- getwd()
-    setwd(dirname(pkg$path))
-    # remove them pesky +x files
-    # BUT EXCLUDE configure and cleanup
-    log_system('find',shQuote(basename(pkg$path))
-                ,'-type f -a '
-                ,   '! \\( -name configure -o -name cleanup \\)'
-                ,'-exec chmod -x {} \\;')
-    # tar it all back up
-    log_system('tar -czf',shQuote(debarchive),shQuote(basename(pkg$path)))
-    setwd(wd)
-    file.remove(pkg$archive)
-    pkg$archive = debarchive
-    pkg$need_repack = FALSE
-    return(pkg)
-}
-
-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
-
-    # first a little trick; change pkgname if pkgname is contained in a bundle
-    if (!(pkgname %in% rownames(available))) {
-        bundle <- r_bundle_of(pkgname)
-        if (is.null(bundle)) {
-            fail('package',pkgname,'is unavailable')
-        }
-        pkgname <- bundle
-    }
-
-    # grab the archive and some metadata
-    pkg <- download_pkg(dir, pkgname)
-
-    # now extract the archive
-    if (!length(grep('\\.tar\\.gz',pkg$archive))) {
-        fail('archive is not tarball')
-    }
-    wd <- getwd()
-    setwd(dir)
-    ret = log_system('tar','xzf',shQuote(pkg$archive))
-    setwd(wd)
-    if (ret != 0) {
-        fail('Extraction of archive',pkg$archive,'failed.')
-    }
-
-    # if necessary, repack the archive into Debian-conformant format
-    if (pkg$need_repack) {
-        pkg <- repack_pkg(pkg)
-    }
-    if (!file.info(pkg$path)[,'isdir']) {
-        fail(pkg$path,'is not a directory and should be.')
-    }
-
-    # extract the DESCRIPTION file, which contains much metadata
-    pkg$description = read.dcf(file.path(pkg$path,'DESCRIPTION'))
-
-    # ensure consistency of version numbers
-    if ('Version' %in% names(pkg$description[1,])) {
-        if (pkg$description[1,'Version'] != available[pkg$name,'Version']) {
-            # should never happen since available is the basis upon which the
-            # package is retrieved.
-            error('available version:',available[pkg$name,'Version'])
-            error('package version:',pkg$description[1,'Version'])
-            fail('inconsistency between R package version and cached R version')
-        }
-    }
-
-    pkg$is_bundle = 'Bundle' %in% names(pkg$description[1,])
-    # note subtly of short circuit operators (no absorption)
-    if ((!pkg$is_bundle && pkg$description[1,'Package'] != pkg$name) ||
-        ( pkg$is_bundle && pkg$description[1,'Bundle'] != pkg$name)) {
-        fail('package name mismatch')
-    }
-    return(pkg)
-}
-
diff --git a/pkg/trunk/R/license.R b/pkg/trunk/R/license.R
deleted file mode 100644 (file)
index 846cf56..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-is_acceptable_license <- function(license) {
-    # determine if license text is acceptable
-
-    if (length(grep('^file ',license))) {
-        # skip file licenses
-        return(FALSE)
-    }
-    license <- license_text_reduce(license)
-    action = db_license_override_name(license)
-    if (!is.null(action)) {
-        return(action)
-    }
-    license <- license_text_further_reduce(license)
-    action = db_license_override_name(license)
-    if (!is.null(action)) {
-        warn('Accepting/rejecting wild license as',license,'. FIX THE PACKAGE!')
-        return(action)
-    }
-    license <- license_text_extreme_reduce(license)
-    action = db_license_override_name(license)
-    if (!is.null(action)) {
-        warn('Accepting/rejecting wild license as',license,'. FIX THE PACKAGE!')
-        return(action)
-    }
-    error('Wild license',license,'did not match classic rules; rejecting')
-    return(F)
-}
-
-license_text_reduce <- function(license) {
-    # these reduction steps are sound for all conformant R license
-    # specifications.
-
-    # compress spaces into a single space
-    license = gsub('[[:space:]]+',' ',license)
-    # make all characters lower case
-    license = tolower(license)
-    # don't care about versions of licenses
-    license = chomp(sub('\\( ?[<=>!]+ ?[0-9.-]+ ?\\)',''
-                    ,sub('-[0-9.-]+','',license)))
-    # remove any extra space introduced
-    license = chomp(gsub('[[:space:]]+',' ',license))
-    return(license)
-}
-
-license_text_further_reduce <- function(license) {
-    # these reduction steps are heuristic and may lead to
-    # in correct acceptances, if care is not taken.
-
-    # uninteresting urls
-    license = gsub('http://www.gnu.org/[[:alnum:]/._-]*','',license)
-    license = gsub('http://www.x.org/[[:alnum:]/._-]*','',license)
-    license = gsub('http://www.opensource.org/[[:alnum:]/._-]*','',license)
-    # remove all punctuation
-    license = gsub('[[:punct:]]+','',license)
-    # remove any extra space introduced
-    license = chomp(gsub('[[:space:]]+',' ',license))
-    # redundant
-    license = gsub('the','',license)
-    license = gsub('see','',license)
-    license = gsub('standard','',license)
-    license = gsub('licen[sc]e','',license)
-    license = gsub('(gnu )?(gpl|general public)','gpl',license)
-    license = gsub('(mozilla )?(mpl|mozilla public)','mpl',license)
-    # remove any extra space introduced
-    license = chomp(gsub('[[:space:]]+',' ',license))
-    return(license)
-}
-
-license_text_extreme_reduce <- function(license) {
-    # remove everything that may or may not be a version specification
-    license = gsub('(ver?sion|v)? *[0-9.-]+ *(or *(higher|later|newer|greater|above))?',''
-                   ,license)
-    # remove any extra space introduced
-    license = chomp(gsub('[[:space:]]+',' ',license))
-    return(license)
-}
-
-license_text_hash_reduce <- function(text) {
-    # reduction of license text, suitable for hashing.
-    return(chomp(tolower(gsub('[[:space:]]+',' ',text))))
-}
-
-get_license <- function(pkg,license) {
-    license <- chomp(gsub('[[:space:]]+',' ',license))
-    if (length(grep('^file ',license))) {
-        if (length(grep('^file LICEN[CS]E$',license))) {
-            file = gsub('file ','',license)
-            path = file.path(pkg$path, file)
-            if (file.exists(path)) {
-                license <- license_text_reduce(readChar(path,file.info(path)$size))
-            } else {
-                path = file.path(pkg$path, 'inst', file)
-                if (file.exists(path)) {
-                    license <- license_text_reduce(readChar(path,file.info(path)$size))
-                } else {
-                    error('said to look at a license file but license file is missing')
-                }
-            }
-        } else {
-            error('invalid license file specification',license)
-            return(NA)
-        }
-    }
-    return(license)
-}
-
-get_license_hash <- function(pkg,license) {
-    return(digest(get_license(pkg,license),algo='sha1',serialize=FALSE))
-}
-
-is_acceptable_hash_license <- function(pkg,license) {
-    license_sha1 <- get_license_hash(pkg,license)
-    if (is.null(license_sha1)) {
-        return(FALSE)
-    }
-    action = db_license_override_hash(license_sha1)
-    if (is.null(action)) {
-        action = FALSE
-    }
-    if (action) {
-        warn('Wild license',license,'accepted via hash',license_sha1)
-    }
-    return(action)
-}
-
-
-accept_license <- function(pkg) {
-    # check the license
-    if (!('License' %in% names(pkg$description[1,]))) {
-        fail('package has no License: field in description!')
-    }
-    accept=NULL
-    for (license in strsplit(chomp(pkg$description[1,'License'])
-                            ,'[[:space:]]*\\|[[:space:]]*')[[1]]) {
-        if (is_acceptable_license(license)) {
-            accept=license
-            break
-        }
-        if (is_acceptable_hash_license(pkg,license)) {
-            accept=license
-            break
-        }
-    }
-    if (is.null(accept)) {
-        fail('No acceptable license:',pkg$description[1,'License'])
-    } else {
-        notice('Auto-accepted license',accept)
-    }
-    if (accept == 'Unlimited') {
-        # definition of Unlimited from ``Writing R extensions''
-        accept=paste('Unlimited (no restrictions on distribution or'
-                    ,'use other than those imposed by relevant laws)')
-    }
-    return(accept)
-}
diff --git a/pkg/trunk/R/log.R b/pkg/trunk/R/log.R
deleted file mode 100644 (file)
index 2a9be4e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-log_messages <- list()
-
-log_clear <- function() {
-    assign('log_messages',list(),envir=.GlobalEnv)
-}
-
-log_add <- function(text,print=T) {
-    if (print) {
-        message(text)
-    }
-    assign('log_messages',c(log_messages, text),envir=.GlobalEnv)
-}
-
-log_retrieve <- function() {
-    return(log_messages)
-}
-
-notice <- function(...) {
-    log_add(paste('N:',...))
-}
-
-warn <- function(...) {
-    log_add(paste('W:',...))
-}
-
-error <- function(...) {
-    log_add(paste('E:',...))
-}
-
-fail <- function(...) {
-    txt <- paste('E:',...)
-    log_add(txt)
-    stop(txt)
-}
-
-log_system <- function(...) {
-    r <- try((function() {
-        # pipe() does not appear useful here, since
-        # we want the return value!
-        # XXX: doesn't work with ; or | !
-        tmp <- tempfile('log_system')
-        on.exit(unlink(tmp))
-        cmd <- paste(...)
-        # unfortunately this destroys ret
-        #cmd <- paste(cmd,'2>&1','| tee',tmp)
-        cmd <- paste(cmd,'>',tmp,'2>&1')
-        ret <- system(cmd)
-        f <- file(tmp)
-        output <- readLines(f)
-        close(f)
-        unlink(tmp)
-        return(list(ret,output))
-    })())
-    if (inherits(r,'try-error')) {
-        fail('system failed on:',paste(...))
-    }
-    for (line in r[[2]]) {
-        if (!length(grep('^[WENI]:',line))) {
-            line = paste('I:',line)
-        }
-        log_add(line) #,print=F)
-    }
-    return(r[[1]])
-}
-
diff --git a/pkg/trunk/R/rdep.R b/pkg/trunk/R/rdep.R
deleted file mode 100644 (file)
index 141453b..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-
-r_bundle_of <- function(pkgname) {
-    # returns the bundle containing pkgname or NA
-    bundles <- names(available[!is.na(available[, 'Bundle']), 'Contains'])
-    # use the first bundle
-    for (bundle in bundles) {
-        if (pkgname %in% r_bundle_contains(bundle)) {
-            return(bundle)
-        }
-    }
-    return(NULL)
-}
-
-r_bundle_contains <- function(bundlename) {
-    return(strsplit(available[bundlename,'Contains'],'[[:space:]]+')[[1]])
-}
-
-r_requiring <- function(names) {
-    for (name in names) {
-        if (!(name %in% base_pkgs) && !(name %in% rownames(available))) {
-            bundle <- r_bundle_of(name)
-            if (!is.null(bundle)) {
-                name = bundle
-                names <- c(names,bundle)
-            }
-        }
-        if (name %in% rownames(available) && !is.na(available[name,'Contains'])) {
-            names <- c(names,r_bundle_contains(name))
-        }
-    }
-    # approximately prune first into a smaller availability
-    candidates <- rownames(available)[sapply(rownames(available)
-                                            ,function(name)
-                                                length(grep(paste(names,collapse='|')
-                                                           ,available[name,r_depend_fields])) > 0)]
-    if (length(candidates) == 0) {
-        return(c())
-    }
-    # find a logical index into available of every package/bundle
-    # whose dependency field contains at least one element of names.
-    # (this is not particularly easy to read---sorry---but is much faster than
-    # the alternatives i could think of)
-    prereq=c()
-    dep_matches <- function(dep) chomp(gsub('\\([^\\)]+\\)','',dep)) %in% names
-    any_dep_matches <- function(name,field=NA)
-                any(sapply(strsplit(chomp(available[name,field])
-                                   ,'[[:space:]]*,[[:space:]]*')
-                          ,dep_matches))
-
-    for (field in r_depend_fields) {
-        matches = sapply(candidates, any_dep_matches, field=field)
-        if (length(matches) > 0) {
-            prereq = c(prereq,candidates[matches])
-        }
-    }
-    return(unique(prereq))
-}
-
-r_dependencies_of <- function(name=NULL,description=NULL) {
-    # find the immediate dependencies (children in the dependency graph) of an
-    # R package
-    if (!is.null(name) && (name == 'R' || name %in% base_pkgs)) {
-        return(data.frame())
-    }
-    if (is.null(description) && is.null(name)) {
-        fail('must specify either a description or a name.')
-    }
-    if (is.null(description)) {
-        if (!(name %in% rownames(available))) {
-            bundle <- r_bundle_of(name)
-            if (!is.null(bundle)) {
-                name <- bundle
-            } else {
-                # unavailable packages don't depend upon anything
-                return(data.frame())
-            }
-        }
-        description <- data.frame()
-        # keep only the interesting fields
-        for (field in r_depend_fields) {
-            if (!(field %in% names(available[name,]))) {
-                next
-            }
-            description[1,field] = available[name,field]
-        }
-    }
-    # extract the dependencies from the description
-    deps <- data.frame()
-    for (field in r_depend_fields) {
-        if (!(field %in% names(description[1,]))) {
-            next
-        }
-        new_deps <- lapply(strsplit(chomp(description[1,field])
-                                   ,'[[:space:]]*,[[:space:]]*')[[1]]
-                          ,r_parse_dep_field)
-        deps <- iterate(lapply(new_deps[!is.na(new_deps)],rbind),deps,rbind)
-    }
-    return (deps)
-}
-
-r_parse_dep_field <- function(dep) {
-    if (is.na(dep)) {
-        return(NA)
-    }
-    # remove other comments
-    dep = gsub('(\\(\\)|\\([[:space:]]*[^<=>!].*\\))','',dep)
-    # squish spaces
-    dep = chomp(gsub('[[:space:]]+',' ',dep))
-    # parse version
-    pat = '^([^ ()]+) ?(\\( ?([<=>!]+ ?[0-9.-]+) ?\\))?$'
-    if (!length(grep(pat,dep))) {
-        fail('R dependency',dep,'does not appear to be well-formed')
-    }
-    version = sub(pat,'\\3',dep)
-    dep = sub(pat,'\\1',dep)
-    if (!(dep %in% rownames(available))) {
-        depb <- r_bundle_of(dep)
-        if (!is.null(depb)) {
-            dep <- depb
-        }
-    }
-    return(list(name=dep,version=version))
-}
-
-r_dependency_closure <- function(fringe, forward_arcs=T) {
-    # find the transitive closure of the dependencies/prerequisites of some R
-    # packages
-    closure <- list()
-    if (is.data.frame(fringe)) {
-        fringe <- as.list(fringe$name)
-    }
-    fun = function(x) r_dependencies_of(name=x)$name
-    if (!forward_arcs) {
-        fun = r_requiring
-    }
-    while(length(fringe) > 0) {
-        # pop off the top
-        top <- fringe[[1]]
-        if (length(fringe) > 1) {
-            fringe <- fringe[2:length(fringe)]
-        } else {
-            fringe <- list()
-        }
-        src <- pkgname_as_debian(top,binary=F)
-        if (src == 'R') {
-            next
-        }
-        newdeps <- fun(top)
-        closure=c(closure,top)
-        fringe=c(fringe,newdeps)
-    }
-    # build order
-    return(rev(unique(closure,fromLast=T)))
-}
-
diff --git a/pkg/trunk/R/util.R b/pkg/trunk/R/util.R
deleted file mode 100644 (file)
index e10951e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-iterate <- function(xs,z,fun) {
-    y <- z
-    for (x in xs)
-        y <- fun(y,x)
-    return(y)
-}
-
-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)
-}
-
-err <- function(...) {
-    error(...)
-    exit()
-}
-
-exit <- function() {
-    q(save='no')
-}
diff --git a/pkg/trunk/R/version.R b/pkg/trunk/R/version.R
deleted file mode 100644 (file)
index 184ec23..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-version_new <- function(rver,debian_revision=1, debian_epoch=db_get_base_epoch()) {
-    # generate a string representation of the Debian version of an
-    # R version of a package
-    pkgver = rver
-
-    # ``Writing R extensions'' says that the version consists of at least two
-    # non-negative integers, separated by . or -
-    if (!length(grep('^([0-9]+[.-])+[0-9]+$',rver))) {
-        fail('Not a valid R package version',rver)
-    }
-
-    # Debian policy says that an upstream version should start with a digit and
-    # may only contain ASCII alphanumerics and '.+-:~'
-    if (!length(grep('^[0-9][A-Za-z0-9.+:~-]*$',rver))) {
-        fail('R package version',rver
-                  ,'does not obviously translate into a valid Debian version.')
-    }
-
-    # if rver contains a : then the Debian version must also have a colon
-    if (debian_epoch == 0 && length(grep(':',pkgver)))
-        debian_epoch = 1
-
-    # if the epoch is non-zero then include it
-    if (debian_epoch != 0)
-        pkgver = paste(debian_epoch,':',pkgver,sep='')
-
-    # always add the '-1' Debian release; nothing is lost and rarely will R
-    # packages be Debian packages without modification.
-    return(paste(pkgver,'-',debian_revision,sep=''))
-}
-
-version_epoch <- function(pkgver) {
-    # return the Debian epoch of a Debian package version
-    if (!length(grep(':',pkgver)))
-        return(0)
-    return(as.integer(sub('^([0-9]+):.*','\\1',pkgver)))
-}
-# version_epoch . version_new(x,y) = id
-# version_epoch(version_new(x,y)) = base_epoch
-
-version_revision <- function(pkgver) {
-    # return the Debian revision of a Debian package version
-    return(as.integer(sub('.*-([0-9]+)$','\\1',pkgver)))
-}
-# version_revision . version_new(x) = id
-# version_revision(version_new(x)) = 1
-
-version_upstream <- function(pkgver) {
-    # return the upstream version of a Debian package version
-    return(sub('-[0-9]+$','',sub('^[0-9]+:','',pkgver)))
-}
-# version_upstream . version_new = id
-
-version_update <- function(rver, prev_pkgver, prev_success) {
-    # return the next debian package version
-    prev_rver <- version_upstream(prev_pkgver)
-    if (prev_rver == rver) {
-        # increment the Debian revision if the previous build was successful
-        inc = 0
-        if (prev_success) {
-            inc = 1
-        }
-        return(version_new(rver
-                          ,debian_revision = version_revision(prev_pkgver)+inc
-                          ,debian_epoch    = version_epoch(prev_pkgver)
-                          ))
-    }
-    # new release
-    # TODO: implement Debian ordering over version and then autoincrement
-    #       Debian epoch when upstream version does not increment.
-    return(version_new(rver
-                      ,debian_epoch = version_epoch(prev_pkgver)
-                      ))
-}
-
-new_build_version <- function(pkgname) {
-    if (!(pkgname %in% rownames(available))) {
-        bundle <- r_bundle_of(pkgname)
-        if (is.null(bundle)) {
-            fail('tried to discover new version of',pkgname,'but it does not appear to be available')
-        }
-        name <- bundle
-    }
-    db_ver <- db_latest_build_version(pkgname)
-    db_succ <- db_latest_build_status(pkgname)[[1]]
-    latest_r_ver <- available[pkgname,'Version']
-    if (!is.null(db_ver)) {
-        return(version_update(latest_r_ver, db_ver, db_succ))
-    }
-    return(version_new(latest_r_ver))
-}
-
diff --git a/pkg/trunk/R/zzz.R.in b/pkg/trunk/R/zzz.R.in
deleted file mode 100644 (file)
index e486f50..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.First.lib <- function(libname, pkgname) {
-    global <- function(name,value) assign(name,value,envir=.GlobalEnv)
-    global("maintainer", 'cran2deb autobuild <cran2deb@example.org>')
-    global("root", system.file(package='cran2deb'))
-    global("cache_root", '/var/cache/cran2deb')
-    global("pbuilder_results", '/var/cache/cran2deb/results')
-    global("pbuilder_config", '/etc/cran2deb/pbuilderrc')
-    global("dput_config", '/etc/cran2deb/dput.cf')
-    global("dinstall_config", '/etc/cran2deb/mini-dinstall.conf')
-    global("dinstall_archive", '/etc/cran2deb/archive')
-    global("r_depend_fields", c('Depends','Imports')) # Suggests, Enhances
-    # git_revision {
-    # git_revision }
-    global("changesfile", function(srcname,version='*') {
-        return(file.path(pbuilder_results
-                        ,paste(srcname,'_',version,'_'
-                              ,host_arch(),'.changes',sep='')))
-    })
-
-    cache <- file.path(cache_root,'cache.rda')
-    if (file.exists(cache)) {
-        load(cache,envir=.GlobalEnv)
-    }
-}
diff --git a/pkg/trunk/README b/pkg/trunk/README
deleted file mode 120000 (symlink)
index a6047ac..0000000
+++ /dev/null
@@ -1 +0,0 @@
-inst/doc/README
\ No newline at end of file
diff --git a/pkg/trunk/configure b/pkg/trunk/configure
deleted file mode 100755 (executable)
index 106c58a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-# stamp the source with the originating git revision.
-git_rev=$(git show --pretty'=oneline' 'HEAD' | head -n1 | cut -f1 -d' ')
-#git_r='assign("git_revision","'$git_rev'",envir=.GlobalEnv)'
-git_r='    global("git_revision","'$git_rev'")'
-
-awk -v "git_r=$git_r" '
-/# git_revision }/ {suppress=0}
-suppress == 0 {print}
-/# git_revision {/ {print git_r; suppress=1}
-' <R/zzz.R.in >R/zzz.R
diff --git a/pkg/trunk/data/populate_depend_aliases b/pkg/trunk/data/populate_depend_aliases
deleted file mode 100644 (file)
index d7dc09a..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-alias_build boost libboost-dev 
-alias_build boost libboost-graph-dev 
-alias_build ggobi ggobi 
-alias_run ggobi ggobi 
-alias_build glade libglade2-dev 
-alias_run glade libglade2-0 
-alias_build glib libglib2.0-dev 
-alias_run glib libglib2.0-0 
-alias_build glu libglu1-mesa-dev 
-alias_run glu libglu1-mesa 
-alias_build gmp libgmp3-dev 
-alias_run gmp libgmp3c2 
-alias_build gsl libgsl0-dev 
-alias_run gsl libgsl0ldbl 
-alias_build ignore build-essential 
-alias_build java openjdk-6-jdk 
-alias_build java libgcj9-dev 
-alias_run java openjdk-6-jre 
-alias_build libatk libatk1.0-dev 
-alias_run libatk libatk1.0-0 
-alias_build libcairo libcairo2-dev 
-alias_run libcairo libcairo2 
-alias_run libcurl libcurl3 
-alias_build libcurl libcurl4-openssl-dev 
-alias_build libdieharder libdieharder-dev 
-alias_run libdieharder libdieharder2 
-alias_build libfontconfig libfontconfig1-dev 
-alias_run libfontconfig libfontconfig1 
-alias_build libfreetype libfreetype6-dev 
-alias_run libfreetype libfreetype6 
-alias_build libgdal libgdal1-dev 
-alias_run libgdal libgdal1-1.5.0 
-alias_build libgd libgd2-noxpm-dev 
-alias_run libgd libgd2-noxpm 
-alias_build libgraphviz libgraphviz-dev 
-alias_run libgraphviz libgraphviz4 
-alias_build libgtk libgtk2.0-dev 
-alias_run libgtk libgtk2.0-0 
-alias_build libjpeg libjpeg62-dev 
-alias_run libjpeg libjpeg62 
-alias_build libmagick libmagick9-dev 
-alias_run libmagick libmagick9 
-alias_build libpango libpango1.0-dev 
-alias_run libpango libpango1.0-0 
-alias_build libpng libpng12-dev 
-alias_run libpng libpng12-0 
-alias_build libxml libxml2-dev 
-alias_run libxml libxml2 
-alias_build msttcorefonts msttcorefonts 
-alias_run msttcorefonts msttcorefonts 
-alias_run netcdf libnetcdf4 
-alias_build netcdf libnetcdf-dev 
-alias_build opengl libgl1-mesa-dev 
-alias_run opengl libgl1-mesa-glx 
-alias_build pari-gp pari-gp 
-alias_run pari-gp pari-gp 
-alias_build proj proj 
-alias_run proj proj 
-alias_build quantlib libquantlib0-dev 
-alias_run quantlib libquantlib-0.9.6 
-alias_run sqlite libsqlite3-0 
-alias_build sqlite libsqlite3-dev 
-alias_build zlib zlib1g-dev 
-alias_run zlib zlib1g 
-alias_build cshell tcsh|csh|c-shell 
-alias_run cshell tcsh|csh|c-shell 
-alias_build autotools autotools-dev 
-alias_build tcl tcl8.4-dev 
-alias_build tk tk8.4-dev 
-alias_build odbc unixodbc-dev 
-alias_build mysql libmysqlclient15-dev 
-alias_build mpi libopenmpi-dev 
-alias_build pvm pvm-dev 
-alias_build hdf5 libhdf5-serial-dev 
-alias_build sprng libsprng2-dev 
diff --git a/pkg/trunk/data/populate_forcedep b/pkg/trunk/data/populate_forcedep
deleted file mode 100644 (file)
index 799d286..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-force java rJava 
-force autotools rJava 
-force sqlite RSQLite 
-force sqlite SQLiteDF 
-force boost RBGL 
-force netcdf ncdf 
-force cshell dse 
-force libgtk cairoDevice 
-force tcl tkrplot 
-force tk tkrplot 
-force mysql RMySQL 
-force mpi Rmpi 
-force pvm rpvm 
-force hdf5 hdf5 
-force libgtk rggobi 
-force libxml rggobi 
-force sprng rsprng 
-force gmp rsprng 
diff --git a/pkg/trunk/data/populate_licenses b/pkg/trunk/data/populate_licenses
deleted file mode 100644 (file)
index ad791bd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-accept AGPL
-accept APACHE
-accept ARTISTIC
-accept BSD
-accept CeCILL
-accept CPL
-accept GPL
-accept GPLQA
-accept GPL+QHULL
-accept LGPL
-accept MIT
-accept MPL
-accept TCLTK2
-accept UNLIMITED
-accept X11
-reject distrib-noncomm
-reject GPL+ACM
-reject MCLUST
-reject UNCLEAR
-hash APACHE /usr/share/common-licenses/Apache-2.0
-hash ARTISTIC /usr/share/common-licenses/Artistic
-hash BSD /usr/share/common-licenses/BSD
-hash GPL /usr/share/common-licenses/GPL-2
-hash GPL /usr/share/common-licenses/GPL-3
-hash LGPL /usr/share/common-licenses/LGPL-2
-hash LGPL /usr/share/common-licenses/LGPL-2.1
-hash LGPL /usr/share/common-licenses/LGPL-3
-pkg BSD minpack.lm
-pkg CeCILL LLAhclust
-pkg CPL lmom
-pkg distrib-noncomm Bhat
-pkg distrib-noncomm conf.design
-pkg distrib-noncomm gpclib
-pkg distrib-noncomm mlbench
-pkg distrib-noncomm poplab
-pkg distrib-noncomm PredictiveRegression
-pkg distrib-noncomm PTAk
-pkg distrib-noncomm siggenes
-pkg GPL+ACM akima
-pkg GPL+ACM tripack
-pkg GPL degreenet
-pkg GPL ergm
-pkg GPL gmodels
-pkg GPL ICE
-pkg GPL latentnet
-pkg GPL network
-pkg GPL networksis
-pkg GPL pastecs
-pkg GPL pbatR
-pkg GPL PKtools
-pkg GPL+QHULL geometry
-pkg GPL reldist
-pkg GPL RXshrink
-pkg GPL snpMatrix
-pkg GPL splancs
-pkg GPL statnet
-pkg GPL uroot
-pkg LGPL R.huge
-pkg MCLUST mclust
-pkg TCLTK2 tcltk2
-pkg UNCLEAR adapt
-pkg UNCLEAR cat
-pkg UNCLEAR cosmo
-pkg UNCLEAR mix
-pkg UNCLEAR mlmm
-pkg UNCLEAR norm
-pkg UNCLEAR pan
-pkg UNCLEAR titecrm
-pkg UNCLEAR tlnise
-pkg UNLIMITED boolean
-pkg GPLQA regtest
-pkg GPL gllm
-pkg GPL rake
-pkg GPL Rigroup
-pkg GPL ICEinfer
-pkg GPL partsm
-pkg GPL timsac
-pkg GPL HTMLapplets
-pkg GPL moc
-pkg GPL ibdreg
-pkg AGPL accuracy
-pkg AGPL Zelig
-pkg GPL TWIX
-pkg GPL aplpack
-accept distrib-noncomm
-accept GPL+ACM
-accept MCLUST
-accept UNCLEAR
-accept acepack
-accept ff
-pkg acepack acepack
-pkg ff ff
-pkg AGPL AIS
-pkg AGPL BARD
-accept NISTnls
-pkg NISTnls NISTnls
-pkg GPL NMMAPSlite
-pkg GPL PET
-pkg distrib-noncomm RLadyBug
diff --git a/pkg/trunk/data/populate_sysreq b/pkg/trunk/data/populate_sysreq
deleted file mode 100644 (file)
index b8f4b3e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-sysreq ignore gcc 
-sysreq ignore gnu make 
-sysreq ignore % if present 
-sysreq ignore none 
-sysreq libcurl curl 
-sysreq ggobi ggobi 
-sysreq libatk atk 
-sysreq libcairo cairo 
-sysreq libdieharder dieharder% 
-sysreq libfontconfig fontconfig 
-sysreq libfreetype freetype 
-sysreq libfreetype %freetype 
-sysreq libgd libgd 
-sysreq libgdal %gdal% 
-sysreq opengl opengl 
-sysreq glade %glade 
-sysreq glib glib 
-sysreq glu glu library 
-sysreq gmp gmp 
-sysreq libgraphviz graphviz 
-sysreq gsl gnu gsl% 
-sysreq gsl gnu scientific library 
-sysreq libgtk gtk% 
-sysreq libjpeg libjpeg% 
-sysreq libmagick imagemagick 
-sysreq libpango pango 
-sysreq libpng libpng 
-sysreq quantlib quantlib% 
-sysreq libxml libxml% 
-sysreq msttcorefonts msttcorefonts 
-sysreq pari-gp pari/gp 
-sysreq proj proj% 
-sysreq zlib zlib 
-sysreq java java 
-sysreq odbc %odbc% 
-sysreq ignore drivers. see readme. 
-sysreq ignore r must be compiled with --enable-r-shlib if the server is to be built 
diff --git a/pkg/trunk/data/quit b/pkg/trunk/data/quit
deleted file mode 100644 (file)
index ff60466..0000000
+++ /dev/null
@@ -1 +0,0 @@
-quit
diff --git a/pkg/trunk/exec/autobuild b/pkg/trunk/exec/autobuild
deleted file mode 100755 (executable)
index 0b24cba..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb autobuild
-## DOC:     automatically builds all out of date packages.
-## DOC:
-suppressMessages(library(cran2deb))
-
-if (exists('argv')) { # check for littler
-    db_update_package_versions()
-    outdated <- db_outdated_packages()
-    build_order <- r_dependency_closure(outdated)
-    notice('build order',paste(build_order,collapse=', '))
-    for (pkg in build_order) {
-        build(pkg,c())
-    }
-}
diff --git a/pkg/trunk/exec/build b/pkg/trunk/exec/build
deleted file mode 100755 (executable)
index b875e60..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb build [-D extra_dep1,extra_dep2,...] package1 package2 ...
-## DOC:     builds a particular package.
-## DOC:
-suppressMessages(library(cran2deb))
-
-if (exists('argv')) { # check for littler
-    argc <- length(argv)
-    extra_deps = list()
-    extra_deps$deb = c()
-    extra_deps$r = c()
-    opts = c('-D','-R')
-    # first argument is the root --- this is dealt with elsewhere.
-    for (i in 2:argc) {
-        if (!(argv[i] %in% opts)) {
-            if (argc >= i) {
-                argv <- argv[i:argc]
-            } else {
-                argv <- list()
-            }
-            argc = argc - i + 1
-            break
-        }
-        if (i == argc) {
-            err('missing argument')
-        }
-        if (argv[i] == '-D') {
-            extra_deps$deb = c(extra_deps$deb,strsplit(chomp(argv[i+1]),',')[[1]])
-        }
-        if (argv[i] == '-R') {
-            extra_deps$r = c(extra_deps$r,strsplit(chomp(argv[i+1]),',')[[1]])
-            extra_deps$deb = c(extra_deps$deb,lapply(extra_deps$r,pkgname_as_debian))
-        }
-    }
-    if (argc == 0) {
-        err('usage: cran2deb [-D extra_dep1,extra_dep2,...] package package ...')
-    }
-    build_order <- r_dependency_closure(c(extra_deps$r,argv))
-    notice('build order',paste(build_order,collapse=', '))
-    for (pkg in build_order) {
-        build(pkg,extra_deps,force=pkg %in% argv)
-    }
-}
diff --git a/pkg/trunk/exec/build_ctv b/pkg/trunk/exec/build_ctv
deleted file mode 100755 (executable)
index 1e39e04..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-## DOC: cran2deb build_ctv
-## DOC:     build all CRAN TaskViews. warning and error logs in ./ctv/
-## DOC:
-
-for ctv in $(cran2deb cran_pkgs query); do
-    echo task view $ctv...
-    if [ ! -e "ctv/$ctv" ]; then
-        cran2deb build_some "$ctv"
-        mkdir -p "ctv/$ctv"
-        mv warn fail "ctv/$ctv"
-    fi
-done
-
diff --git a/pkg/trunk/exec/build_some b/pkg/trunk/exec/build_some
deleted file mode 100755 (executable)
index f02af9d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/rc
-## DOC: cran2deb build_some [taskview1 taskview2 ...]
-## DOC:     build some packages, logging warnings into ./warn/$package
-## DOC:     and failures into ./fail/$package. with no arguments a random
-## DOC:     sample of packages is built.  the file ./all_pkgs overrides this
-## DOC:     behaviour and is expected to be a list of packages to build.
-## DOC:
-
-mkdir -p warn fail
-shift
-if [ ! -e all_pkgs ]; then
-    cran2deb cran_pkgs $* >all_pkgs
-fi
-
-for pkg in $(cat all_pkgs); do
-    if (~ $pkg *..* */*) {
-        echo bad name $pkg >>fail/ERROR
-    } else if ([ -e warn/$pkg ]) {
-        echo skipping $pkg...
-    } else if ([ -e fail/$pkg ]) {
-        echo skipping failed $pkg...
-    } else {
-        echo -n .. package $pkg
-        fail=0
-        cran2deb build $pkg >fail/$pkg >[2=1] || fail=1
-        if (~ $fail 0) {
-            echo success
-            grep '^[WE]:' fail/$pkg >warn/$pkg
-#            if (~ `{stat -c '%s' warn/$pkg} 0) {
-#                rm -f warn/$pkg
-#            }
-            rm -f fail/$pkg
-        } else {
-            echo FAILED
-        }
-    }
-done
diff --git a/pkg/trunk/exec/copy_find b/pkg/trunk/exec/copy_find
deleted file mode 100755 (executable)
index eebcec1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/rc
-## DOC: cran2deb copy_find path
-## DOC:     a tool for finding (heuristically) some copyright notices.
-## DOC:
-kwords='copyright|warranty|redistribution|modification|patent|trademark|licen[cs]e|permission'
-nl=`` () {printf '\n'}
-ifs=$nl {
-    files=`{find $1 ! -path '*debian*' -type f}
-    lines=()
-    for (file in $files) {
-        notices=`{grep -H '(C)' $file}
-        notices=($notices `{grep -HEi $kwords $file})
-        lines=($lines `{{for (notice in $notices) echo $notice} | sort -u})
-    }
-    # let's hope no file has a : in it
-    ifs=() { seen_files=`{{for (line in $lines) echo $line} | cut -d: -f1} }
-    missing_copyright=()
-    for (file in $files) {
-        if (echo -n $seen_files | grep -q '^'^$file^'$') {
-        } else {
-            missing_copyright=($missing_copyright $file)
-        }
-    }
-    echo 'Suspect copyright notices:'
-    for (line in $lines) echo '    '$line
-    echo 'Files without *suspect* copyright notices:'
-    for (missing in $missing_copyright) {
-        echo '    '$missing
-        echo '       type: '`{file $missing}
-        echo '      chars: '`{wc -c $missing | awk '{print $1}'}
-        echo '      lines: '`{wc -l $missing | awk '{print $1}'}
-    }
-}
diff --git a/pkg/trunk/exec/cran2deb b/pkg/trunk/exec/cran2deb
deleted file mode 100755 (executable)
index 7efedc7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-umask 002
-root=$(r -e 'suppressMessages(library(cran2deb));cat(system.file(package="cran2deb"),file=stdout())')
-cmd=$1
-shift
-if [ ! -x "$root/exec/$cmd" ]; then
-    echo unknown command $cmd
-    exit 1
-fi
-"$root/exec/$cmd" "$root" $*
diff --git a/pkg/trunk/exec/cran_pkgs b/pkg/trunk/exec/cran_pkgs
deleted file mode 100755 (executable)
index b8a2dcb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb cran_pkgs
-## DOC:     print a list of 800 packages picked at random
-## DOC: cran2deb cran_pkgs query
-## DOC:     print the names of all CRAN TaskViews
-## DOC: cran2deb cran_pkgs taskview1 taskview2 ...
-## DOC:     print the names of all packages in a particular CRAN TaskView
-## DOC:
-
-library(cran2deb)
-
-if (length(argv) == 1) {
-    writeLines(sample(dimnames(available)[[1]],800))
-} else {
-    argv = argv[2:length(argv)]
-    if (argv[1] == 'query') {
-        for (ctv in ctv.available) {
-            writeLines(ctv$name)
-        }
-        q(save='no')
-    }
-    # list of task lists
-    for (ctv in ctv.available) {
-        if (ctv$name %in% argv) {
-            writeLines(ctv$packagelist$name)
-        }
-    }
-}
diff --git a/pkg/trunk/exec/depend b/pkg/trunk/exec/depend
deleted file mode 100755 (executable)
index 2552d8f..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb depend
-## DOC:     add dependency aliases, system requirements and forced dependencies
-## DOC:
-
-suppressPackageStartupMessages(library(cran2deb))
-suppressPackageStartupMessages(library(digest))
-
-exec_cmd <- function(argc, argv) {
-    usage <- function()
-        message(paste('usage: alias <alias> <debian_pkg>'
-                     ,'       alias_run <alias> <debian_pkg>'
-                     ,'       alias_build <alias> <debian_pkg>'
-                     ,'       sysreq <alias> <sysreq sql pattern>'
-                     ,'       force <alias> <r_pkg>'
-                     ,'       ls [aliases|force|sysreq]'
-                     ,'       quit'
-                     ,sep='\n'))
-
-    if (argc < 1) {
-        return()
-    }
-    cmd = argv[1]
-
-    if (cmd == 'alias') {
-        if (argc < 3) {
-            usage()
-            return()
-        }
-        alias = argv[2]
-        pkg = argv[3]
-        db_add_depends(alias, pkg, build=T)
-        pkg = gsub('-dev$','',pkg)
-        db_add_depends(alias, pkg, build=F)
-    } else if (cmd == 'alias_run' || cmd == 'alias_build') {
-        if (argc < 3) {
-            usage()
-            return()
-        }
-        db_add_depends(argv[2], argv[3], cmd == 'alias_build')
-    } else if (cmd == 'sysreq') {
-        if (argc < 3) {
-            usage()
-            return()
-        }
-        sysreq = paste(argv[3:argc],collapse=' ')
-        db_add_sysreq_override(sysreq,argv[2])
-    } else if (cmd == 'force') {
-        if (argc < 3) {
-            usage()
-            return()
-        }
-        db_add_forced_depends(argv[3],argv[2])
-    } else if (cmd == 'ls') {
-        if (argc < 2 || argv[2] == 'aliases') {
-            aliases <- db_depends()
-            for (i in rownames(aliases)) {
-                type = 'alias_run'
-                if (as.logical(aliases[i,'build'])) {
-                    type = 'alias_build'
-                }
-                cat(paste(type,aliases[i,'alias'],aliases[i,'debian_pkg'],'\n'))
-            }
-        } else if (argv[2] == 'sysreq') {
-            sysreqs <- db_sysreq_overrides()
-            for (i in rownames(sysreqs)) {
-                cat(paste('sysreq',sysreqs[i,'depend_alias'],sysreqs[i,'r_pattern'],'\n'))
-            }
-        } else if (argv[2] == 'force') {
-            forced <- db_forced_depends()
-            for (i in rownames(forced)) {
-                cat(paste('force',forced[i,'depend_alias'],forced[i,'r_name'],'\n'))
-            }
-        } else {
-            usage()
-            return()
-        }
-    } else if (cmd == 'quit') {
-        exit()
-    } else if (cmd == '#') {
-    } else {
-        usage()
-        return()
-    }
-}
-
-argc <- length(argv)
-if (argc > 1) {
-    exec_cmd(argc-1,argv[c(2:argc)])
-} else {
-    while(T) {
-        argv <- strsplit(readline('depend> '),'[[:space:]]+')[[1]]
-        exec_cmd(length(argv),argv)
-    }
-}
diff --git a/pkg/trunk/exec/diagnose b/pkg/trunk/exec/diagnose
deleted file mode 100755 (executable)
index 3740b50..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/rc
-
-success=`{ls /var/cache/cran2deb/results/*.deb | wc -l}
-echo $success successful packages
-total=$success
-
-fn count_dup { sort | uniq -c | sort -n}# | awk '$1 > 1{print}' }
-fn collapse { a=`{echo $^* | sed -e 's/ | /|/g'}; echo $^a }
-echo 'warnings:'
-{for (x in (warn/* /dev/null)) cut -d: -f3- <$x | sort -u} | awk '{print $1}' | count_dup
-echo
-
-faildep=('^Error: package ''.*'' could not be loaded'
-     '|' '^ERROR: lazy loading failed for package ''.*'''
-     '|' '^[[:space:]]*package .* is not available'
-     '|' 'there is no package called ''.*''')
-faildeb='do not know what to do with SystemRequirement:'
-faillic=('No acceptable license: ')
-failspc=': No space left on device'
-failhdr='error: .*\.hp?p?: No such file or directory'
-faildep=`{collapse $faildep}
-faildep=$^faildep
-faillic=`{collapse $faillic}
-faillic=$^faillic
-other=''
-
-nfaildep=`{grep -El $faildep fail/* /dev/null | wc -l}
-echo $nfaildep failed R dependencies.
-grep -Eh $faildep fail/* | count_dup
-other=$faildep
-#total=$total+$nfaildep
-echo
-
-nfaillic=`{grep -El $faillic `{grep -EL $other fail/*} /dev/null | wc -l}
-echo $nfaillic failed licenses.
-grep -Eh $faillic `{grep -EL $other fail/*} | count_dup
-other=$other^'|'^$faillic
-total=$total+$nfaillic
-echo
-
-nfailspc=`{grep -El $failspc `{grep -EL $other fail/*} /dev/null | wc -l}
-echo $nfailspc out of space
-other=$other^'|'^$failspc
-total=$total+$nfailspc
-echo
-
-nfailhdr=`{grep -El $failhdr `{grep -EL $other fail/*} /dev/null | wc -l}
-echo $nfailhdr missing C header
-grep -Eh $failhdr `{grep -EL $other fail/* /dev/null} | count_dup
-other=$other^'|'^$failhdr
-total=$total+$nfailhdr
-echo
-
-nfaildeb=`{grep -El $faildeb `{grep -EL $other fail/*} /dev/null | wc -l}
-echo $nfaildeb system requirement failures.
-grep -Eh $faildeb `{grep -EL $other fail/* /dev/null} | count_dup
-other=$other^'|'^$faildeb
-total=$total+$nfaildeb
-echo
-
-nfailother=`{hoc -e `{grep -EL $other fail/* /dev/null | wc -l}^-1}
-echo $nfailother other failures.
-
-total=`{hoc -e $total}
-succrate=`{hoc -e $success/'('$total')*100'}
-echo $succrate% success rate '('$total' total)'
-#total=`{hoc -e $total-$nfaillic-$nfailspc-$nfailhdr}
-total=`{hoc -e $total-$nfaillic-$nfailspc}
-succrate=`{hoc -e $success/'('$total')*100'}
-echo $succrate% success rate with exclusions '('$total' total)'
-grep -EL $other fail/* /dev/null | xargs tail -n 20
-
diff --git a/pkg/trunk/exec/diagnose_ctv b/pkg/trunk/exec/diagnose_ctv
deleted file mode 100755 (executable)
index 5e7ef03..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-(for x in ctv/*; do echo;echo;echo "$x: "; cd "$x" && cran2deb diagnose && cd ../..; done) >ctv.results
diff --git a/pkg/trunk/exec/get_base_pkgs b/pkg/trunk/exec/get_base_pkgs
deleted file mode 100755 (executable)
index d08d625..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env r
-for (pkg in rownames(installed.packages())) {
-       message(pkg)
-}
diff --git a/pkg/trunk/exec/help b/pkg/trunk/exec/help
deleted file mode 100755 (executable)
index 3eeabab..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-echo usage: cran2deb '<cmd> [args ...]'
-echo where '<cmd>' is one of
-grep '## [D]OC:' $1/exec/* | sed -e 's/.*[D]OC://'
-echo
-echo installation root is: $1
diff --git a/pkg/trunk/exec/latest_log b/pkg/trunk/exec/latest_log
deleted file mode 100644 (file)
index 055991a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb latest_log package1 package2 ...
-## DOC:     show the latest log output for <package>
-suppressMessages(library(cran2deb))
-
-if (exists('argv')) {
-    for (pkg in argv) {
-        cat(db_latest_build(pkg)$log)
-        cat('\n')
-    }
-}
diff --git a/pkg/trunk/exec/license b/pkg/trunk/exec/license
deleted file mode 100755 (executable)
index 74e01a5..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env r
-## DOC: cran2deb license
-## DOC:     add licenses and change acceptance/rejection of licenses
-## DOC:
-
-suppressPackageStartupMessages(library(cran2deb))
-suppressPackageStartupMessages(library(digest))
-
-exec_cmd <- function(argc, argv) {
-    usage <- function()
-        message(paste('usage: accept <license>'
-                     ,'       reject <license>'
-                     ,'       hash <license> (<path>|<hash>)'
-                     ,'       pkg <license> <pkg>'
-                     ,'       view <pkg>'
-                     ,'       ls'
-                     ,'       quit'
-                     ,sep='\n'))
-
-    if (argc < 1) {
-        exit()
-    }
-    cmd = argv[1]
-
-    if (cmd == 'accept' || cmd == 'reject') {
-        if (argc != 2) {
-            usage()
-            return()
-        }
-        action = (cmd == 'accept')
-        db_add_license_override(argv[2],action)
-    } else if (cmd == 'hash') {
-        if (argc != 3) {
-            usage()
-            return()
-        }
-        license = argv[2]
-        path = argv[3]
-        if (is.null(db_license_override_name(license))) {
-            error('license',license,'is not known; add it first')
-            return()
-        }
-        if (file.exists(path)) {
-            license_sha1 = digest(readChar(path,file.info(path)$size)
-                                 ,algo='sha1', serialize=FALSE)
-        } else if (length(grep('^[0-9a-f]{40}$',path))) {
-            license_sha1 = path
-        } else {
-            error(path,'does not exist and does not look like an SHA1 hash')
-            return()
-        }
-        db_add_license_hash(license,license_sha1)
-    } else if (cmd == 'pkg') {
-        if (argc != 3) {
-            usage()
-            return()
-        }
-        license <- argv[2]
-        pkg_name <- argv[3]
-        current_action <- db_license_override_name(license)
-        if (is.null(current_action)) {
-            notice('license',license,'is not known; add it')
-            return()
-        }
-        action = 'accept'
-        if (!current_action) {
-            action = 'reject'
-        }
-        notice('in future, will',action,'the package',pkg_name,'under license',license)
-        tmp <- setup()
-        success <- try((function() {
-            pkg <- prepare_pkg(tmp,pkg_name)
-            if (!('License' %in% names(pkg$description[1,]))) {
-                error('package',pkg$name,'has no License: field in DESCRIPTION')
-                return()
-            }
-            first_license = (strsplit(chomp(pkg$description[1,'License'])
-                                     ,'[[:space:]]*\\|[[:space:]]*')[[1]])[1]
-            license_sha1 <- get_license_hash(pkg,first_license)
-            db_add_license_hash(license,license_sha1)
-        })())
-        cleanup(tmp)
-        if (inherits(success,'try-error')) {
-            return()
-        }
-    } else if (cmd == 'view') {
-        if (argc != 2) {
-            usage()
-            return()
-        }
-        pkg_name <- argv[2]
-        tmp <- setup()
-        success <- try((function() {
-            pkg <- prepare_pkg(tmp,pkg_name)
-            if (!('License' %in% names(pkg$description[1,]))) {
-                error('package',pkg$name,'has no License: field in DESCRIPTION')
-                return()
-            }
-            first_license = (strsplit(chomp(pkg$description[1,'License'])
-                                     ,'[[:space:]]*\\|[[:space:]]*')[[1]])[1]
-            first_license = get_license(pkg,first_license)
-            cat(strwrap(first_license),file='|less')
-        })())
-        cleanup(tmp)
-        if (inherits(success,'try-error')) {
-            return()
-        }
-    } else if (cmd == 'ls') {
-        for (x in db_license_overrides()) print(x)
-    } else if (cmd == 'help') {
-        usage()
-        return()
-    } else if (cmd == 'quit') {
-        exit()
-    }
-}
-
-argc <- length(argv)
-if (argc > 1) {
-    exec_cmd(argc-1,argv[c(2:argc)])
-} else {
-    while(T) {
-        argv <- strsplit(readline('license> '),'[[:space:]]+')[[1]]
-        exec_cmd(length(argv),argv)
-    }
-}
diff --git a/pkg/trunk/exec/repopulate b/pkg/trunk/exec/repopulate
deleted file mode 100755 (executable)
index ab3ea60..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-## DOC: cran2deb repopulate
-## DOC:     repopulate the cran2deb database and configurations from a new cran2deb release
-## DOC:
-
-umask 002
-root=$1
-shift
-for x in $(find /etc/cran2deb/ -type f -name '*.in'); do
-    y=$(echo $x | sed -e 's,.in$,,')
-    sed -e "s:@ROOT@:$root:g" <"$x" >"$y"
-done
-
-# now do an update to reflect any config changes
-"$root/exec/update" "$root"
-
-(for fn in populate_licenses quit; do
-    cat "$root/data/$fn"
-done) | "$root/exec/license" "$root"
-
-(for fn in populate_depend_aliases populate_sysreq populate_forcedep quit; do
-    cat "$root/data/$fn"
-done) | "$root/exec/depend" "$root"
-
diff --git a/pkg/trunk/exec/root b/pkg/trunk/exec/root
deleted file mode 100755 (executable)
index 3133778..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-echo $1
diff --git a/pkg/trunk/exec/update b/pkg/trunk/exec/update
deleted file mode 100755 (executable)
index 7bcc78f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/rc
-## DOC: cran2deb update
-## DOC:     update the cran2deb cache and database
-## DOC: cran2deb update full
-## DOC:     force a full update of the cran2deb cache and database
-## DOC:
-
-umask 002
-root=$1
-shift
-mkdir -p /var/cache/cran2deb/results || exit 1
-mini-dinstall --batch -c /etc/cran2deb/mini-dinstall.conf || exit 1
-update_period=10800
-if (~ $1 full || ![ -e /var/cache/cran2deb/cache.rda ] ) {
-    delta=`{awk 'END{print '^$update_period^'+1}' </dev/null}
-    echo Forcing cache update
-} else {
-    delta=`{awk 'END{print '^`{date +%s}^-^`{stat -c '%Y' /var/cache/cran2deb/cache.rda}^'}' </dev/null}
-    echo Cache is $delta seconds out of date.
-}
-if (![ -e /var/cache/cran2deb/cache.rda ] || [ $delta -gt $update_period ]) {
-    mode=create
-    if ([ -e /var/cache/pbuilder/base-cran2deb.tgz ]) {
-        mode=update
-    }
-    sudo pbuilder $mode --override-config --configfile /etc/cran2deb/pbuilderrc
-    $root/exec/update_cache $root
-}
-
diff --git a/pkg/trunk/exec/update_cache b/pkg/trunk/exec/update_cache
deleted file mode 100755 (executable)
index 6893846..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env Rscript
-library(cran2deb)
-library(ctv)
-
-argv <- commandArgs()
-argv <- argv[-(1:match("--args", argv))]
-
-#mirror <- 'http://cran.uk.r-project.org/'
-mirror <- 'http://cran.r-project.org/'
-
-message('updating list of available R packages...')
-available <- available.packages(contrib.url(mirror))
-
-#available <- rbind(available,available.packages(contrib.url('http://www.bioconductor.org/')))
-#dupes <- duplicated(rownames(available), fromLast=T)
-#available <- available[!dupes,]
-
-message('updating list of available R task views...')
-ctv.available <- available.views(repo=mirror)
-
-message('updating list of base R packages...')
-base_pkgs <- readLines(pipe(paste('sudo pbuilder --execute --override-config --configfile'
-                                 ,shQuote(pbuilder_config),'-- /usr/bin/R --vanilla 2>&1 >/dev/null <'
-                                 ,shQuote(file.path(root,'exec/get_base_pkgs'))
-                                 ,'| grep -v ^W:')))
-
-message('updating list of existing Debian packages...')
-debian_pkgs <- readLines(pipe('apt-cache rdepends r-base-core | sed -e "/^  r-cran/{s/^[[:space:]]*r/r/;p}" -e d | sort -u'))
-
-save(debian_pkgs, base_pkgs, available, ctv.available, file=file.path(cache_root,'cache.rda'),eval.promises=T)
-
-message('synchronising database...')
-db_update_package_versions()
diff --git a/pkg/trunk/inst/doc/DB_NOTES b/pkg/trunk/inst/doc/DB_NOTES
deleted file mode 100644 (file)
index 0960026..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-this file documents some of R/db.R -- the DB interface code.
-
-
-table: sysreq_override
-fields: depend_alias TEXT, r_pattern TEXT
-
-SystemRequirements LIKE r_pattern are mapped onto the dependency alias
-depend_alias (this is a foreign key in debian_dependency).
-
-table: debian_dependency
-fields: id INTEGER PRIMARY KEY AUTOINCREMENT,
-        alias TEXT,
-        build INTEGER NOT NULL,
-        debian_pkg TEXT NOT NULL,
-        UNIQUE (alias,build,debian_pkg)
-
-sets up a dependency alias. each row is a Debian dependency entry, debian_pkg, which
-may be added to Depends: (and Build-Depends: if build = 1).
-
-table: forced_depends
-fields: r_name TEXT.
-        depend_alias TEXT,
-        PRIMARY KEY (r_name,depend_alias)'
-
-forces the R package r_name to have the dependencies implied by depend_alias (a foriegn
-key in debian_dependency).
-
-table: license_override
-fields: name TEXT PRIMARY KEY,
-        accept INT NOT NULL
-
-specifies whether the license, name, is accepted or rejected.
-
-table: license_hashes
-fields: name TEXT
-        sha1 TEXT PRIMARY KEY
-
-matches an SHA1 hash of the LICEN[CS]E file or part of the License: field to
-a particular license name (a foreign key in license_override).
-
-table: database_versions
-fields: version INTEGER PRIMARY KEY AUTOINCREMENT,
-        version_date INTEGER,
-        base_epoch INTEGER
-
-a version of the database. each time one of the above tables (but not the below
-tables) is updated, a new record is added to this table, indicating significant
-changes to the database. version_date indicates when this change occurred
-(seconds since UNIX epoch) and base_epoch is the Debian version epoch.
-
-in future, all of the above fields should be versioned and somehow linked to
-the packages that used them, so we only rebuild what is necessary.
-
-table: packages
-fields: package TEXT PRIMARY KEY,
-        latest_r_version TEXT
-
-a package, and its latest R version. this is a copy of the 'available'
-structure in the cran2deb R cache, and it is here as it allows queries on the
-'builds' table to be much simpler (and perhaps faster).
-
-table: builds
-fields: id INTEGER PRIMARY KEY AUTOINCREMENT,
-        package TEXT,
-        r_version TEXT,
-        deb_epoch INTEGER,
-        deb_revision INTEGER,
-        db_version INTEGER,
-        date_stamp TEXT,
-        git_revision TEXT,
-        success INTEGER,
-        log TEXT,
-        UNIQUE(package,r_version,deb_epoch,deb_revision,db_version)
-
-Each time a 'package' is built, its 'success' is logged, along with the
-particular database, cran2deb, R and Debian version information (db_version,
-git_revision, r_version, deb_epoch, deb_revision) and the current date
-(date_stamp). 'log' contains the output of the build process.
-
-A new 'deb_revision' is assigned to each successful build.
-
diff --git a/pkg/trunk/inst/doc/DEPENDS b/pkg/trunk/inst/doc/DEPENDS
deleted file mode 100644 (file)
index 471f240..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-A dependency alias (created in populated_depend_aliases) is some name (such as
-java) and some associated run and build time dependencies, specified like this:
-
-    alias_build java openjdk-6-jdk
-    alias_build java libgcj9-dev
-    alias_run java openjdk-6-jre
-
-So when cran2deb needs to use the 'java' build dependency, it will add
-"openjdk-6-jdk, libgcj9-dev" to the Build-Depends:. alias_run deals with
-Depends: only.
-Since in Debian you cannot Build-Depend: upon build-essential, there is a
-special 'ignore' dependency alias (this can be handy for dropping unnecessary
-system requirements)
-
-    alias_build ignore build-essential
-
-populate_forcedep contains like:
-
-    force java rJava
-
-which forces the R package rJava to use the dependency alias 'java'. This is
-for cases where there is no SystemRequirement.
-
-Finally, populate_sysreq has lines like:
-
-   sysreq quantlib quantlib%
-
-This says, whenever a part of a SystemRequirement matches the SQL LIKE pattern
-'quantlib%', use the dependency alias. SystemRequirements are converted to
-lower case and messed around with; details are in R/debcontrol.R in the
-sysreqs_as_debian function. R/debcontrol.R contains pretty much all of the code
-for dependencies (the database interface code is in R/db.R).
-
diff --git a/pkg/trunk/inst/doc/INSTALL_NOTES b/pkg/trunk/inst/doc/INSTALL_NOTES
deleted file mode 100644 (file)
index 4d47890..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-git clone git://github.com/blundellc/cran2deb.git
-
-apt-get system requirements from DESCRIPTION
-apt-get install cdbs
-
-# install a web server
-apt-get install thttpd
-
-# add a group for cran2deb people
-addgroup cran2deb
-usermod -a -G cran2deb cb
-usermod -a -G cran2deb edd
-
-# set up web space
-mkdir /var/www/cran2deb
-chgrp cran2deb /var/www/cran2deb
-chmod 3775 /var/www/cran2deb
-
-# install prereq R packages
-r -e "install.packages(c('ctv','RSQLite','DBI','digest'))"
-R CMD INSTALL cran2deb
-
-# set up cran2deb space, as per README
-cp /usr/local/lib/R/site-library/cran2deb/exec/cran2deb  /usr/local/bin
-root=$(cran2deb root)
-mkdir /etc/cran2deb
-chgrp cran2deb /etc/cran2deb
-chmod 3775 /etc/cran2deb
-copy ROOT/etc/* to /etc/cran2deb
-ln -s /var/www/cran2deb/ /etc/cran2deb/archive
-edit /etc/cran2deb/pbuilder.in:
-OTHERMIRROR='deb http://localhost/users/cb/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/users/cb/cran2deb/ unstable/all/'
-MIRRORSITE='http://ftp.debian.org/debian/'
-to
-OTHERMIRROR='deb http://localhost/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/cran2deb/ unstable/all/'
-MIRRORSITE='http://ftp.at.debian.org/debian/'
-
-# fix permissions for group usage.
-mkdir /var/cache/cran2deb
-chgrp cran2deb /var/cache/cran2deb
-chmod 3775 /var/cache/cran2deb
-chgrp -R cran2deb $root
-chmod 3775 $root
-chmod -R g+w $root
-
-(log out then log in to get gid cran2deb)
-
-# build pbuilder archive, initialise database
-cran2deb update
-
-# check it works
-cran2deb build zoo
-
-# is handy
-apt-get install sqlite3
-
diff --git a/pkg/trunk/inst/doc/PKG b/pkg/trunk/inst/doc/PKG
deleted file mode 100644 (file)
index de0a4b2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-One of the key data structures using by cran2deb is commonly called 'pkg'.
-It is constructed in R/getrpkg.R by prepare_pkg. prepare_pkg obtains
-an R package and converts the source package into something suitable for use
-with Debian.
-
-If a particular upstream version has already been used to create a Debian
-package, then the source tarball of that upstream version is expected to be
-available locally, and is used for building. In this case no conversion is
-performed, so the archive does not change. In future it may be desirable to
-obtain the source tarball from some central archive but this is not done at the
-moment.
-
-download_pkg in R/getrpkg.R obtains the tarball (archive) of the R package, either
-from the previous Debian build, or from the R archive. The field pkg$need_repack
-indicates if the obtained archive must be repacked into a form acceptable
-as a Debian source archive. This repacking, if necessary, is performed by
-repack_pkg in R/getrpkg.R
-
-
-Most of the creation of pkg is done by R/getrpkg.R. However some more build
-specific operations (such as determining the new build version pkg$debversion)
-are performed by R/debianpkg.R.
-
diff --git a/pkg/trunk/inst/doc/README b/pkg/trunk/inst/doc/README
deleted file mode 100644 (file)
index b521da0..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-To install:
-
-$ cd ..
-$ R CMD INSTALL cran2deb
-
-copy cran2deb/exec/cran2deb into somewhere in your executable path (e.g.,
-/usr/local/bin, $home/bin)
-
-
-
-To configure:
-
-1. You need a web server serving from say, /var/www/cran2deb/
-
-Let ROOT be the value returned by running: cran2deb root
-
-2. create /etc/cran2deb
-   a. copy ROOT/etc/* into /etc/cran2deb
-   b. /etc/cran2deb/archive should be a symlink pointing to /var/www/cran2deb/
-
-    $ ln -s /var/www/cran2deb/ /etc/cran2deb/archive
-
-   c. modify OTHERMIRROR of /etc/cran2deb/pbuilderrc.in to point to your webserver
-
-3. cran2deb needs a persistent cache outside of R's control. therefore, create
-    /var/cache/cran2deb, writable by whichever user(s) will run cran2deb.
-4. run: cran2deb update
-5. Try building a simple package: cran2deb build zoo
-   (The result will be in /var/cache/cran2deb/results)
-
-
-$ cran2deb help
-will display a short summary of help for each cran2deb command.
-
diff --git a/pkg/trunk/inst/etc/dput.cf.in b/pkg/trunk/inst/etc/dput.cf.in
deleted file mode 100644 (file)
index 8ae0ca6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[local]
-method = local
-incoming = /etc/cran2deb/archive/mini-dinstall/incoming
-allow_non-us_software = 1
-run_dinstall = 0
-run_lintian = 1
-post_upload_command = /usr/bin/mini-dinstall --batch -c /etc/cran2deb/mini-dinstall.conf
-allow_unsigned_uploads = 1
diff --git a/pkg/trunk/inst/etc/hook/A80rjava b/pkg/trunk/inst/etc/hook/A80rjava
deleted file mode 100755 (executable)
index 1d37c8b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ -n "$(which java)" ]
-then
-    R CMD javareconf
-fi
diff --git a/pkg/trunk/inst/etc/hook/B90lintian b/pkg/trunk/inst/etc/hook/B90lintian
deleted file mode 100755 (executable)
index 57fcfc4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# example file to be used with --hookdir
-#
-# run lintian on generated deb files
-apt-get install -y --force-yes lintian
-lintian /tmp/buildd/*.deb
diff --git a/pkg/trunk/inst/etc/hook/B91dpkg-i b/pkg/trunk/inst/etc/hook/B91dpkg-i
deleted file mode 100755 (executable)
index ee031bb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-# example file to be used with --hookdir
-#
-# try to install the resulting debs.
-
-echo "Trying to install resulting packages and test upgrades"
-set -ex
-
-
-PKGNAMES=$(cd /tmp/buildd && ls -1 *.deb | sed 's/_.*$//' )
-
-# install-remove check
-dpkg -i /tmp/buildd/*.deb
-dpkg --remove $PKGNAMES
-
-# install-purge check
-dpkg -i /tmp/buildd/*.deb
-dpkg --purge $PKGNAMES
-
-# upgrade-remove check
-apt-get install -y --force-yes  $PKGNAMES || true
-dpkg -i /tmp/buildd/*.deb
-dpkg --remove $PKGNAMES
-
-# upgrade-purge check
-apt-get install -y --force-yes $PKGNAMES || true
-dpkg -i /tmp/buildd/*.deb
-dpkg --purge $PKGNAMES
diff --git a/pkg/trunk/inst/etc/hook/B92test-pkg b/pkg/trunk/inst/etc/hook/B92test-pkg
deleted file mode 100755 (executable)
index 7372ca0..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-# example file to be used with --hookdir
-#
-# run tests. Current directory is top of source-code.
-#
-# 2005, 2007 Junichi Uekawa
-# 
-set -e 
-
-echo "Installing the prerequisites"
-for PKG in $(ls /tmp/buildd/*.deb | sed -e's,.*/,,;s,_.*,,' ); do
-    apt-get install -y --force-yes "$PKG" || true 
-    apt-get remove -y "$PKG" || true 
-done
-# ignore the failures since they are not the prime interest
-
-dpkg -i /tmp/buildd/*.deb
-
-if chmod a+x /tmp/buildd/*/debian/pbuilder-test/*; then
-    :
-else
-    echo "W: no pbuilder-test script found, skipping"
-    exit 0
-fi
-
-SUCCESS=0
-COUNT=0
-unset FAIL || true
-NOFAIL=1
-
-# The current directory is the top of the source-tree.
-cd /tmp/buildd/*/debian/..
-
-for SCRIPT in $(run-parts --test /tmp/buildd/*/debian/pbuilder-test) ; do
-    echo "--- BEGIN test: ${SCRIPT##*/}"
-    if "${SCRIPT}"; then
-       echo SUCCESS
-       ((SUCCESS=SUCCESS+1))
-    else
-       echo FAIL
-       FAIL[${#FAIL[@]}]="${SCRIPT##*/}"
-       NOFAIL=0
-    fi
-    echo "--- END test: ${SCRIPT##*/}"
-    ((COUNT=COUNT+1))
-done
-
-echo "Summary:"
-echo "=== $SUCCESS out of $COUNT tests passed"
-echo "${FAIL[@]/#/ failed }"
-echo "-- end of testsuite."
-
diff --git a/pkg/trunk/inst/etc/hook/D70aptupdate b/pkg/trunk/inst/etc/hook/D70aptupdate
deleted file mode 100755 (executable)
index 4d42b3d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/apt-get update
diff --git a/pkg/trunk/inst/etc/mini-dinstall.conf.in b/pkg/trunk/inst/etc/mini-dinstall.conf.in
deleted file mode 100644 (file)
index 56cd938..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-[DEFAULT]
-architectures = all, i386, amd64
-use_dnotify = 0
-verify_sigs = 0
-mail_on_success = 0
-archive_style = simple-subdir
-mail_log_level = NONE
-archivedir = /etc/cran2deb/archive
-logfile = @ROOT@/mini-dinstall.log
-
-[unstable]
-
diff --git a/pkg/trunk/inst/etc/pbuilderrc.in b/pkg/trunk/inst/etc/pbuilderrc.in
deleted file mode 100644 (file)
index 076ee17..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-BASETGZ=/var/cache/pbuilder/base-cran2deb.tgz
-HOOKDIR=/etc/cran2deb/hook
-BUILDRESULT=/var/cache/cran2deb/results
-EXTRAPACKAGES='debhelper r-base-dev cdbs r-base-core lintian xvfb xauth xfonts-base'
-REMOVEPACKAGES='lilo libldap-2.4-2 libopencdk10 libsasl2-2'
-# don't actually need aptitude, but pbuilder insists...
-#REMOVEPACKAGES+='aptitude libcwidget3 libept0 libncursesw5 libsigc++-2.0-0c2a libxapian15'
-DISTRIBUTION=unstable
-OTHERMIRROR='deb http://localhost/users/cb/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/users/cb/cran2deb/ unstable/all/'
-MIRRORSITE='http://ftp.debian.org/debian/'
-APTCACHE=''
-PBUILDERSATISFYDEPENDSCMD='/usr/lib/pbuilder/pbuilder-satisfydepends-classic'
diff --git a/trunk/DESCRIPTION b/trunk/DESCRIPTION
new file mode 100644 (file)
index 0000000..d591695
--- /dev/null
@@ -0,0 +1,11 @@
+Package: cran2deb
+Version: 0.0
+Date: 2008-07-14
+Title: Convert CRAN packages into Debian packages
+Author: Charles Blundell <blundellc@gmail.com>, with assistance from Dirk Eddelbuettel <>
+Maintainer: Charles Blundell <blundellc@gmail.com>
+Depends: ctv, utils, RSQLite, DBI, digest
+SystemRequirements: littler, rc, pbuilder, debian toolchain, web server, mini-dinstall, curl
+Description: Convert CRAN packages into Debian packages, mostly unassisted, easily
+ subverting the R package system.
+License: GPL-3
diff --git a/trunk/R/build.R b/trunk/R/build.R
new file mode 100644 (file)
index 0000000..4ca1923
--- /dev/null
@@ -0,0 +1,149 @@
+
+build <- function(name,extra_deps,force=F) {
+    # can't, and hence don't need to, build base packages
+    if (name %in% base_pkgs) {
+        return(T)
+    }
+    log_clear()
+    dir <- setup()
+
+    # obtain the Debian version-to-be
+    version <- try(new_build_version(name))
+    if (inherits(version,'try-error')) {
+        error('failed to build',name)
+        return(NULL)
+    }
+
+    result <- try((function() {
+        if (!force && !needs_build(name,version)) {
+            notice('skipping build of',name)
+            return(NULL)
+        }
+
+        pkg <- prepare_new_debian(prepare_pkg(dir,name),extra_deps)
+        if (pkg$debversion != version) {
+            fail('expected Debian version',version,'not equal to actual version',pkg$debversion)
+        }
+        # delete the current archive (XXX: assumes mini-dinstall)
+        for (subdir in c('mini-dinstall','unstable')) {
+            path = file.path(dinstall_archive,subdir)
+            if (file.exists(path)) {
+                unlink(path,recursive=T)
+            }
+        }
+
+        # delete notes of upload
+        file.remove(Sys.glob(file.path(pbuilder_results,'*.upload')))
+
+        # make mini-dinstall generate the skeleton of the archive
+        ret = log_system('umask 002;mini-dinstall --batch -c',dinstall_config)
+        if (ret != 0) {
+            fail('failed to create archive')
+        }
+
+        # pull in all the R dependencies
+        notice('R dependencies:',paste(pkg$depends$r,collapse=', '))
+        for (dep in pkg$depends$r) {
+            if (pkgname_as_debian(dep) %in% debian_pkgs) {
+                notice('using Debian package of',dep)
+                next
+            }
+            # otherwise, convert to source package name
+            srcdep = pkgname_as_debian(dep,binary=F)
+
+            notice('uploading',srcdep)
+            ret = log_system('umask 002;dput','-c',shQuote(dput_config),'local'
+                        ,changesfile(srcdep))
+            if (ret != 0) {
+                fail('upload of dependency failed! maybe you did not build it first?')
+            }
+        }
+        build_debian(pkg)
+
+        # upload the package
+        ret = log_system('umask 002;dput','-c',shQuote(dput_config),'local'
+                    ,changesfile(pkg$srcname,pkg$debversion))
+        if (ret != 0) {
+            fail('upload failed!')
+        }
+
+        # delete the current archive (XXX: assumes mini-dinstall)
+        # this is handy for group operation
+        for (subdir in c('mini-dinstall','unstable')) {
+            path = file.path(dinstall_archive,subdir)
+            if (file.exists(path)) {
+                unlink(path,recursive=T)
+            }
+        }
+
+        return(pkg$debversion)
+    })())
+    cleanup(dir)
+    if (is.null(result)) {
+        # nothing was done so escape asap.
+        return(result)
+    }
+
+    # otherwise record progress
+    failed = inherits(result,'try-error')
+    if (failed) {
+        error('failure of',name,'means these packages will fail:'
+                     ,paste(r_dependency_closure(name,forward_arcs=F),collapse=', '))
+    }
+    db_record_build(name, version, log_retrieve(), !failed)
+    return(!failed)
+}
+
+needs_build <- function(name,version) {
+    # see if the last build was successful
+    build <- db_latest_build(name)
+    if (!is.null(build) && build$success) {
+        # then something must have changed for us to attempt this
+        # build
+        if (build$r_version == version_upstream(version) &&
+            build$deb_epoch == version_epoch(version) &&
+            build$db_version == db_get_version()) {
+            return(F)
+        }
+    } else {
+        # always rebuild on failure or no record
+        return(T)
+    }
+    # see if it has already been built
+    srcname <- pkgname_as_debian(name,binary=F)
+    debname <- pkgname_as_debian(name,binary=T)
+    if (file.exists(changesfile(srcname, version))) {
+        notice('already built',srcname,'version',version)
+        return(F)
+    }
+
+    # XXX: what about building newer versions of Debian packages?
+    if (debname %in% debian_pkgs) {
+        notice(srcname,' exists in Debian (perhaps a different version)')
+        return(F)
+    }
+
+    rm(debname,srcname)
+    return(T)
+}
+
+build_debian <- function(pkg) {
+    wd <- getwd()
+    setwd(pkg$path)
+    notice('building Debian package'
+                 ,pkg$debname
+                 ,paste('(',pkg$debversion,')',sep='')
+                 ,'...')
+
+    cmd = paste('pdebuild --configfile',shQuote(pbuilder_config))
+    if (version_revision(pkg$debversion) > 2) {
+        cmd = paste(cmd,'--debbuildopts','-sd')
+        notice('build should exclude original source')
+    }
+    ret = log_system(cmd)
+    setwd(wd)
+    if (ret != 0) {
+        fail('Failed to build package.')
+    }
+}
+
diff --git a/trunk/R/db.R b/trunk/R/db.R
new file mode 100644 (file)
index 0000000..f6a4c07
--- /dev/null
@@ -0,0 +1,374 @@
+
+db_start <- function() {
+    drv <- dbDriver('SQLite')
+    con <- dbConnect(drv, dbname=file.path(cache_root,'cran2deb.db'))
+    if (!dbExistsTable(con,'sysreq_override')) {
+        dbGetQuery(con,paste('CREATE TABLE sysreq_override ('
+                  ,' depend_alias TEXT NOT NULL'
+                  ,',r_pattern TEXT PRIMARY KEY NOT NULL'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'debian_dependency')) {
+        dbGetQuery(con,paste('CREATE TABLE debian_dependency ('
+                  ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
+                  ,',alias TEXT NOT NULL'
+                  ,',build INTEGER NOT NULL'
+                  ,',debian_pkg TEXT NOT NULL'
+                  ,',UNIQUE (alias,build,debian_pkg)'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'forced_depends')) {
+        dbGetQuery(con,paste('CREATE TABLE forced_depends ('
+                  ,' r_name TEXT NOT NULL'
+                  ,',depend_alias TEXT NOT NULL'
+                  ,',PRIMARY KEY (r_name,depend_alias)'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'license_override')) {
+        dbGetQuery(con,paste('CREATE TABLE license_override ('
+                  ,' name TEXT PRIMARY KEY NOT NULL'
+                  ,',accept INT NOT NULL'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'license_hashes')) {
+        dbGetQuery(con,paste('CREATE TABLE license_hashes ('
+                  ,' name TEXT NOT NULL'
+                  ,',sha1 TEXT PRIMARY KEY NOT NULL'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'database_versions')) {
+        dbGetQuery(con,paste('CREATE TABLE database_versions ('
+                  ,' version INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
+                  ,',version_date INTEGER NOT NULL'
+                  ,',base_epoch INTEGER NOT NULL'
+                  ,')'))
+        db_add_version(con,1,0)
+    }
+    if (!dbExistsTable(con,'packages')) {
+        dbGetQuery(con,paste('CREATE TABLE packages ('
+                  ,' package TEXT PRIMARY KEY NOT NULL'
+                  ,',latest_r_version TEXT'
+                  ,')'))
+    }
+    if (!dbExistsTable(con,'builds')) {
+        dbGetQuery(con,paste('CREATE TABLE builds ('
+                  ,' id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
+                  ,',package TEXT NOT NULL'
+                  ,',r_version TEXT NOT NULL'
+                  ,',deb_epoch INTEGER NOT NULL'
+                  ,',deb_revision INTEGER NOT NULL'
+                  ,',db_version INTEGER NOT NULL'
+                  ,',date_stamp TEXT NOT NULL'
+                  ,',git_revision TEXT NOT NULL'
+                  ,',success INTEGER NOT NULL'
+                  ,',log TEXT'
+                  ,',UNIQUE(package,r_version,deb_epoch,deb_revision,db_version)'
+                  ,')'))
+    }
+    return(con)
+}
+
+db_stop <- function(con,bump=F) {
+    if (bump) {
+        db_bump(con)
+    }
+    dbDisconnect(con)
+}
+
+db_quote <- function(text) {
+    return(paste('\'', gsub('([\'"])','\\1\\1',text),'\'',sep=''))
+}
+
+db_now <- function() {
+    return(as.integer(gsub('-','',Sys.Date())))
+}
+
+db_cur_version <- function(con) {
+    return(as.integer(dbGetQuery(con, 'SELECT max(version) FROM database_versions')[[1]]))
+}
+
+db_base_epoch <- function(con) {
+    return(as.integer(dbGetQuery(con,
+        paste('SELECT max(base_epoch) FROM database_versions'
+             ,'WHERE version IN (SELECT max(version) FROM database_versions)'))[[1]]))
+}
+
+db_get_base_epoch <- function() {
+    con <- db_start()
+    v <- db_base_epoch(con)
+    db_stop(con)
+    return(v)
+}
+
+db_get_version <- function() {
+    con <- db_start()
+    v <- db_cur_version(con)
+    db_stop(con)
+    return(v)
+}
+
+db_add_version <- function(con, version, epoch) {
+    dbGetQuery(con,paste('INSERT INTO database_versions (version,version_date,base_epoch)'
+              ,'VALUES (',as.integer(version),',',db_now(),',',as.integer(epoch),')'))
+}
+
+db_bump <- function(con) {
+    db_add_version(con,db_cur_version(con)+1, db_base_epoch(con))
+}
+
+db_bump_epoch <- function(con) {
+    db_add_version(con,db_cur_version(con)+1, db_base_epoch(con)+1)
+}
+
+db_sysreq_override <- function(sysreq_text) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                    'SELECT DISTINCT depend_alias FROM sysreq_override WHERE'
+                            ,db_quote(tolower(sysreq_text)),'LIKE r_pattern'))
+    db_stop(con)
+    if (length(results) == 0) {
+        return(NULL)
+    }
+    return(results$depend_alias)
+}
+
+db_add_sysreq_override <- function(pattern,depend_alias) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                     'INSERT OR REPLACE INTO sysreq_override'
+                    ,'(depend_alias, r_pattern) VALUES ('
+                    ,' ',db_quote(tolower(depend_alias))
+                    ,',',db_quote(tolower(pattern))
+                    ,')'))
+    db_stop(con,TRUE)
+}
+
+db_sysreq_overrides <- function() {
+    con <- db_start()
+    overrides <- dbGetQuery(con,paste('SELECT * FROM sysreq_override'))
+    db_stop(con)
+    return(overrides)
+}
+
+db_get_depends <- function(depend_alias,build=F) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                    'SELECT DISTINCT debian_pkg FROM debian_dependency WHERE'
+                    ,db_quote(tolower(depend_alias)),'= alias'
+                    ,'AND',as.integer(build),'= build'))
+    db_stop(con)
+    return(results$debian_pkg)
+}
+
+db_add_depends <- function(depend_alias,debian_pkg,build=F) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                     'INSERT OR REPLACE INTO debian_dependency'
+                    ,'(alias, build, debian_pkg) VALUES ('
+                    ,' ',db_quote(tolower(depend_alias))
+                    ,',',as.integer(build)
+                    ,',',db_quote(tolower(debian_pkg))
+                    ,')'))
+    db_stop(con,TRUE)
+}
+
+db_depends <- function() {
+    con <- db_start()
+    depends <- dbGetQuery(con,paste('SELECT * FROM debian_dependency'))
+    db_stop(con)
+    return(depends)
+}
+
+db_get_forced_depends <- function(r_name) {
+    con <- db_start()
+    forced_depends <- dbGetQuery(con,
+                paste('SELECT depend_alias FROM forced_depends WHERE'
+                     ,db_quote(r_name),'= r_name'))
+    db_stop(con)
+    return(forced_depends$depend_alias)
+}
+
+db_add_forced_depends <- function(r_name, depend_alias) {
+    if (!length(db_get_depends(depend_alias,build=F)) &&
+        !length(db_get_depends(depend_alias,build=T))) {
+        fail('Debian dependency alias',depend_alias,'is not know,'
+                  ,'yet trying to force a dependency on it?')
+    }
+    con <- db_start()
+    dbGetQuery(con,
+            paste('INSERT OR REPLACE INTO forced_depends (r_name, depend_alias)'
+                 ,'VALUES (',db_quote(r_name),',',db_quote(depend_alias),')'))
+    db_stop(con,TRUE)
+}
+
+db_forced_depends <- function() {
+    con <- db_start()
+    depends <- dbGetQuery(con,paste('SELECT * FROM forced_depends'))
+    db_stop(con)
+    return(depends)
+}
+
+db_license_override_name <- function(name) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                    'SELECT DISTINCT accept FROM license_override WHERE'
+                            ,db_quote(tolower(name)),'= name'))
+    db_stop(con)
+    if (length(results) == 0) {
+        return(NULL)
+    }
+    return(as.logical(results$accept))
+}
+
+db_add_license_override <- function(name,accept) {
+    notice('adding',name,'accept?',accept)
+    if (accept != TRUE && accept != FALSE) {
+        fail('accept must be TRUE or FALSE')
+    }
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                     'INSERT OR REPLACE INTO license_override'
+                    ,'(name, accept) VALUES ('
+                    ,' ',db_quote(tolower(name))
+                    ,',',as.integer(accept)
+                    ,')'))
+    db_stop(con,TRUE)
+}
+
+db_license_override_hash <- function(license_sha1) {
+    con <- db_start()
+    results <- dbGetQuery(con,paste(
+                     'SELECT DISTINCT accept FROM license_override'
+                    ,'INNER JOIN license_hashes'
+                    ,'ON license_hashes.name = license_override.name WHERE'
+                    ,db_quote(tolower(license_sha1)),'= license_hashes.sha1'))
+    db_stop(con)
+    if (length(results) == 0) {
+        return(NULL)
+    }
+    return(as.logical(results$accept))
+}
+
+db_license_overrides <- function() {
+    con <- db_start()
+    overrides <- dbGetQuery(con,paste('SELECT * FROM license_override'))
+    hashes    <- dbGetQuery(con,paste('SELECT * FROM license_hashes'))
+    db_stop(con)
+    return(list(overrides=overrides,hashes=hashes))
+}
+
+db_add_license_hash <- function(name,license_sha1) {
+    if (is.null(db_license_override_name(name))) {
+        fail('license',name,'is not know, yet trying to add a hash for it?')
+    }
+    notice('adding hash',license_sha1,'for',name)
+    con <- db_start()
+    dbGetQuery(con,paste(
+         'INSERT OR REPLACE INTO license_hashes'
+        ,'(name, sha1) VALUES ('
+        ,' ',db_quote(tolower(name))
+        ,',',db_quote(tolower(license_sha1))
+        ,')'))
+    db_stop(con,TRUE)
+}
+
+
+db_update_package_versions <- function() {
+    con <- db_start()
+    for (package in available[,'Package']) {
+        dbGetQuery(con, paste('INSERT OR REPLACE INTO packages (package,latest_r_version)'
+                             ,'VALUES (',db_quote(package)
+                             ,',',db_quote(available[package,'Version']),')'))
+    }
+    db_stop(con)
+}
+
+db_record_build <- function(package, deb_version, log, success=F) {
+    con <- db_start()
+    dbGetQuery(con,paste('INSERT OR REPLACE INTO builds'
+                        ,'(package,r_version,deb_epoch,deb_revision,db_version,success,date_stamp,git_revision,log)'
+                        ,'VALUES'
+                        ,'(',db_quote(package)
+                        ,',',db_quote(version_upstream(deb_version))
+                        ,',',db_quote(version_epoch(deb_version))
+                        ,',',db_quote(version_revision(deb_version))
+                        ,',',db_cur_version(con)
+                        ,',',as.integer(success)
+                        ,',',db_quote(format(Sys.time(),'%a, %d %b %Y %H:%M:%S %z'))
+                        ,',',db_quote(git_revision)
+                        ,',',db_quote(paste(log, collapse='\n'))
+                        ,')'))
+    db_stop(con)
+}
+
+db_builds <- function(pkgname) {
+    # returns all successful builds
+    con <- db_start()
+    build <- dbGetQuery(con, paste('SELECT * FROM builds'
+                       ,'WHERE success = 1'
+                       ,'AND package =',db_quote(pkgname)))
+    db_stop(con)
+    if (length(build) == 0) {
+        return(NULL)
+    }
+    build$success <- as.logical(build$success)
+    return(build)
+}
+
+db_latest_build <- function(pkgname) {
+    con <- db_start()
+    build <- dbGetQuery(con, paste('SELECT * FROM builds'
+                       ,'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
+                       ,              'GROUP BY package) AS last'
+                       ,'WHERE id = max_id'
+                       ,'AND builds.package =',db_quote(pkgname)))
+    db_stop(con)
+    if (length(build) == 0) {
+        return(NULL)
+    }
+    build$success <- as.logical(build$success)
+    return(build)
+}
+
+db_latest_build_version <- function(pkgname) {
+    build <- db_latest_build(pkgname)
+    if (is.null(build)) {
+        return(NULL)
+    }
+    return(version_new(build$r_version, build$deb_revision, build$deb_epoch))
+}
+
+db_latest_build_status <- function(pkgname) {
+    build <- db_latest_build(pkgname)
+    if (is.null(build)) {
+        return(NULL)
+    }
+    return(list(build$success,build$log))
+}
+
+db_outdated_packages <- function() {
+    con <- db_start()
+    packages <- dbGetQuery(con,paste('SELECT packages.package FROM packages'
+               ,'LEFT OUTER JOIN ('
+               # extract the latest attempt at building each package
+               ,      'SELECT * FROM builds'
+               ,      'NATURAL JOIN (SELECT package,max(id) AS max_id FROM builds'
+               ,                    'GROUP BY package) AS last'
+               ,      'WHERE id = max_id) AS build'
+               ,'ON build.package = packages.package'
+               # outdated iff:
+               # - there is no latest build
+               ,'WHERE build.package IS NULL'
+               # - the database has changed since last build
+               ,'OR build.db_version < (SELECT max(version) FROM database_versions)'
+               # - the debian epoch has been bumped up
+               ,'OR build.deb_epoch < (SELECT max(base_epoch) FROM database_versions'
+               ,                        'WHERE version IN ('
+               ,                            'SELECT max(version) FROM database_versions))'
+               # - the latest build is not of the latest R version
+               ,'OR build.r_version != packages.latest_r_version'
+               ))$package
+    db_stop(con)
+    return(packages)
+}
+
diff --git a/trunk/R/debcontrol.R b/trunk/R/debcontrol.R
new file mode 100644 (file)
index 0000000..84d9933
--- /dev/null
@@ -0,0 +1,167 @@
+get_dependencies <- function(pkg,extra_deps) {
+    # determine dependencies
+    dependencies <- r_dependencies_of(description=pkg$description)
+    depends <- list()
+    # these are used for generating the Depends fields
+    as_deb <- function(r,build) {
+        return(pkgname_as_debian(paste(dependencies[r,]$name)
+                                ,version=dependencies[r,]$version
+                                ,repopref=pkg$repo
+                                ,build=build))
+    }
+    depends$bin <- lapply(rownames(dependencies), as_deb, build=F)
+    depends$build <- lapply(rownames(dependencies), as_deb, build=T)
+    # add the command line dependencies
+    depends$bin = c(extra_deps$deb,depends$bin)
+    depends$build = c(extra_deps$deb,depends$build)
+    # add the system requirements
+    if ('SystemRequirements' %in% colnames(pkg$description)) {
+        sysreq <- sysreqs_as_debian(pkg$description[1,'SystemRequirements'])
+        depends$bin = c(sysreq$bin,depends$bin)
+        depends$build = c(sysreq$build,depends$build)
+    }
+
+    forced <- forced_deps_as_debian(pkg$name)
+    if (length(forced)) {
+        notice('forced build dependencies:',paste(forced$build, collapse=', '))
+        notice('forced binary dependencies:',paste(forced$bin, collapse=', '))
+        depends$bin = c(forced$bin,depends$bin)
+        depends$build = c(forced$build,depends$build)
+    }
+
+    # make sure we depend upon R in some way...
+    if (!length(grep('^r-base',depends$build))) {
+        depends$build = c(depends$build,pkgname_as_debian('R',version='>= 2.7.0',build=T))
+        depends$bin   = c(depends$bin,  pkgname_as_debian('R',version='>= 2.7.0',build=F))
+    }
+    # also include stuff to allow tcltk to build (suggested by Dirk)
+    depends$build = c(depends$build,'xvfb','xauth','xfonts-base')
+
+    # make all bin dependencies build dependencies.
+    depends$build = c(depends$build, depends$bin)
+
+    # remove duplicates
+    depends <- lapply(depends,unique)
+
+    # append the Debian dependencies
+    depends$build=c(depends$build,'debhelper (>> 4.1.0)','cdbs')
+    if (pkg$archdep) {
+        depends$bin=c(depends$bin,'${shlibs:Depends}')
+    }
+
+    # the names of dependent source packages (to find the .changes file to
+    # upload via dput). these can be found recursively.
+    depends$r = r_dependency_closure(dependencies)
+    # append command line dependencies
+    depends$r = c(extra_deps$r, depends$r)
+    return(depends)
+}
+
+sysreqs_as_debian <- function(sysreq_text) {
+    # form of this field is unspecified (ugh) but most people seem to stick
+    # with this
+    aliases <- c()
+    sysreq_text <- gsub('[[:space:]]and[[:space:]]',' , ',tolower(sysreq_text))
+    for (sysreq in strsplit(sysreq_text,'[[:space:]]*,[[:space:]]*')[[1]]) {
+        startreq = sysreq
+        # constant case
+        sysreq = tolower(sysreq)
+        # drop version information/comments for now
+        sysreq = gsub('[[][^])]*[]]','',sysreq)
+        sysreq = gsub('\\([^)]*\\)','',sysreq)
+        sysreq = gsub('[[][^])]*[]]','',sysreq)
+        sysreq = gsub('version','',sysreq)
+        sysreq = gsub('from','',sysreq)
+        sysreq = gsub('[<>=]*[[:space:]]*[[:digit:]]+[[:digit:].+:~-]*','',sysreq)
+        # byebye URLs
+        sysreq = gsub('(ht|f)tps?://[[:alnum:]!?*"\'(),%$_@.&+/=-]*','',sysreq)
+        # squish out space
+        sysreq = chomp(gsub('[[:space:]]+',' ',sysreq))
+        alias <- db_sysreq_override(sysreq)
+        if (is.null(alias)) {
+            error('do not know what to do with SystemRequirement:',sysreq)
+            error('original SystemRequirement:',startreq)
+            fail('unmet system requirement')
+        }
+        notice('mapped SystemRequirement',startreq,'onto',alias,'via',sysreq)
+        aliases = c(aliases,alias)
+    }
+    return(map_aliases_to_debian(aliases))
+}
+
+forced_deps_as_debian <- function(r_name) {
+    aliases <- db_get_forced_depends(r_name)
+    return(map_aliases_to_debian(aliases))
+}
+
+map_aliases_to_debian <- function(aliases) {
+    if (!length(aliases)) {
+        return(aliases)
+    }
+    debs <- list()
+    debs$bin = unlist(sapply(aliases, db_get_depends))
+    debs$build = unlist(sapply(aliases, db_get_depends, build=T))
+    debs$bin = debs$bin[debs$bin != 'build-essential']
+    debs$build = debs$build[debs$build != 'build-essential']
+    return(debs)
+}
+
+generate_control <- function(pkg) {
+    # construct control file
+    control = data.frame()
+    control[1,'Source'] = pkg$srcname
+    control[1,'Section'] = 'math'
+    control[1,'Priority'] = 'optional'
+    control[1,'Maintainer'] = maintainer
+    control[1,'Build-Depends'] = paste(pkg$depends$build,collapse=', ')
+    control[1,'Standards-Version'] = '3.8.0'
+
+    control[2,'Package'] = pkg$debname
+    control[2,'Architecture'] = 'all'
+    if (pkg$archdep) {
+        control[2,'Architecture'] = 'any'
+    }
+    control[2,'Depends'] = paste(pkg$depends$bin,collapse=', ')
+
+#   # bundles provide virtual packages of their contents
+#   # unnecessary for now; cran2deb converts R bundles itself
+#    if (pkg$is_bundle) {
+#        control[2,'Provides'] = paste(
+#                    lapply(r_bundle_contains(pkg$name)
+#                          ,function(name) return(pkgname_as_debian(paste(name)
+#                                                                  ,repopref=pkg$repo)))
+#                          ,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']
+    }
+
+    if (length(long_descr) < 1) {
+        # bypass lintian extended-description-is-empty for which we care not.
+        long_descr <- paste('The author/maintainer of this package'
+                           ,'did not care to enter a longer 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', 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)
+}
+
diff --git a/trunk/R/debiannaming.R b/trunk/R/debiannaming.R
new file mode 100644 (file)
index 0000000..83c0ab5
--- /dev/null
@@ -0,0 +1,52 @@
+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')
+    }
+    if (length(grep('bioc',url))) {
+        return('bioc')
+    }
+    fail('unknown repository',url)
+}
+
+pkgname_as_debian <- function(name,repopref=NULL,version=NULL,binary=T,build=F) {
+    # generate the debian package name corresponding to the R package name
+    if (name %in% base_pkgs) {
+        name = 'R'
+    }
+    if (name == 'R') {
+        # R is special.
+        if (binary) {
+            if (build) {
+                debname='r-base-dev'
+            } else {
+                debname='r-base-core'
+            }
+        } else {
+            debname='R'
+        }
+    } else {
+        # XXX: data.frame rownames are unique, so always override repopref for
+        #      now.
+        if (!(name %in% rownames(available))) {
+            bundle <- r_bundle_of(name)
+            if (!is.null(bundle)) {
+                name <- bundle
+            }
+        }
+        debname = tolower(name)
+        if (binary) {
+            if (name %in% rownames(available)) {
+                repopref <- tolower(repourl_as_debian(available[name,'Repository']))
+            } else if (is.null(repopref)) {
+                repopref <- 'unknown'
+            }
+            debname = paste('r',repopref,debname,sep='-')
+        }
+    }
+    if (!is.null(version) && length(version) > 1) {
+        debname = paste(debname,' (',version,')',sep='')
+    }
+    return(debname)
+}
+
diff --git a/trunk/R/debianpkg.R b/trunk/R/debianpkg.R
new file mode 100644 (file)
index 0000000..416a911
--- /dev/null
@@ -0,0 +1,144 @@
+append_build_from_pkg <- function(pkg, builds) {
+    pkg_build <- data.frame(id = -1     # never used
+                           ,package = pkg$name
+                           ,r_version = version_upstream(pkg$debversion)
+                           ,deb_epoch = version_epoch(pkg$debversion)
+                           ,deb_revision = version_revision(pkg$debversion)
+                           ,db_version = db_get_version()
+                           ,date_stamp = pkg$date_stamp
+                           ,git_revision = git_revision
+                           ,success = 1 # never used
+                           ,log = ''    # never used
+                           )
+    return(cbind(data.frame(srcname=pkg$srcname), rbind(builds, pkg_build)))
+}
+
+generate_changelog <- function(pkg) {
+    # TODO: ``Writing R extensions'' mentions that a package may also have
+    # {NEWS,ChangeLog} files.
+    builds <- append_build_from_pkg(pkg, db_builds(pkg$name))
+    sapply(rev(rownames(builds)), function(b, changelog) generate_changelog_entry(builds[b,], changelog), pkg$debfile('changelog.in'))
+}
+
+generate_changelog_entry <- function(build, changelog) {
+    # TODO: should say 'New upstream release' when necessary
+    debversion <- version_new(build$r_version, build$deb_revision, build$deb_epoch)
+    cat(paste(paste(build$srcname,' (',debversion,') unstable; urgency=low',sep='')
+             ,'' ,paste('  * cran2deb ',build$git_revision
+                       ,' with DB version ',as.integer(build$db_version),'.',sep='')
+             ,'',paste(' --',maintainer,'',build$date_stamp)
+             ,'','','',sep='\n'),file=changelog, append=TRUE)
+}
+
+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'))
+    Sys.chmod(pkg$debfile('rules'),'0700')
+}
+
+generate_copyright <- function(pkg) {
+    # generate_copyright file; we trust DESCRIPTION
+
+    # if maintainer is missing then try to use author
+    if (!('Maintainer' %in% colnames(pkg$description))) {
+        if ('Author' %in% colnames(pkg$description)) {
+            maintainer = pkg$description[1,'Author']
+        } else {
+            fail('Maintainer and Author not defined in R DESCRIPTION')
+        }
+    } else {
+        maintainer = pkg$description[1,'Maintainer']
+    }
+    # likewise if author is missing then try to use maintainer
+    if (!('Author' %in% colnames(pkg$description))) {
+        author = maintainer
+    } else {
+        author = pkg$description[1,'Author']
+    }
+
+    writeLines(strwrap(
+        paste('This Debian package of the GNU R package',pkg$name
+             ,'was generated automatically using cran2deb by'
+             ,paste(maintainer,'.',sep='')
+             ,''
+             ,'The original GNU R package is Copyright (C) '
+             # TODO: copyright start date, true copyright date
+             ,format(Sys.time(),'%Y')
+             ,author
+             ,'and possibly others.'
+             ,''
+             ,'The original GNU R package is maintained by'
+             ,maintainer,'and was obtained from:'
+             ,''
+             ,pkg$repoURL
+             ,''
+             ,''
+             ,'The GNU R package DESCRIPTION offers a'
+             ,'Copyright licenses under the terms of the license:'
+             ,pkg$license,'.  On a Debian GNU/Linux system, common'
+             ,'licenses are included in the directory'
+             ,'/usr/share/common-licenses/.'
+             ,''
+             ,'The DESCRIPTION file for the original GNU R package '
+             ,'can be found in '
+             ,file.path('/usr/lib/R/site-library'
+                   ,pkg$debname
+                   ,'DESCRIPTION'
+                   )
+             ,sep='\n'), width=72), con=pkg$debfile('copyright.in'))
+}
+
+prepare_new_debian <- function(pkg,extra_deps) {
+    # generate Debian version and name
+    pkg$debversion = new_build_version(pkg$name)
+
+    # make the debian/ directory
+    debdir <- file.path(pkg$path,'debian')
+    pkg$debfile <- function(x) { file.path(debdir,x) }
+    unlink(debdir,recursive=T)
+    dir.create(debdir)
+
+    # see if this is an architecture-dependent package.
+    # heuristic: if /src/ exists in pkg$path, then this is an
+    #            architecture-dependent package.
+    # CRAN2DEB.pm is a bit fancier about this but ``Writing R extensions''
+    # 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.
+    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()
+    }
+
+    pkg$license <- accept_license(pkg)
+    pkg$depends <- get_dependencies(pkg,extra_deps)
+    generate_changelog(pkg)
+    generate_rules(pkg)
+    generate_copyright(pkg)
+    generate_control(pkg)
+
+    # convert text to utf8 (who knows what the original character set is --
+    # let's hope iconv DTRT).
+    for (file in c('control','changelog','copyright')) {
+        log_system('iconv -o ',shQuote(pkg$debfile(file))
+                    ,' -t utf8 -c '
+                    ,shQuote(pkg$debfile(paste(file,'in',sep='.'))))
+        file.remove(pkg$debfile(paste(file,'in',sep='.')))
+    }
+    return(pkg)
+}
diff --git a/trunk/R/getrpkg.R b/trunk/R/getrpkg.R
new file mode 100644 (file)
index 0000000..5273a1f
--- /dev/null
@@ -0,0 +1,172 @@
+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()
+}
+
+download_pkg <- function(dir, pkgname) {
+    # download pkgname into dir, and construct some metadata
+
+    # record some basic information
+    pkg <- pairlist()
+    pkg$date_stamp = format(Sys.time(),'%a, %d %b %Y %H:%M:%S %z')
+    pkg$name = pkgname
+    pkg$repoURL = available[pkgname,'Repository']
+    pkg$repo = repourl_as_debian(pkg$repoURL)
+    if (!length(grep('^[A-Za-z0-9][A-Za-z0-9+.-]+$',pkg$name))) {
+        fail('Cannot convert package name into a Debian name',pkg$name)
+    }
+    pkg$srcname = pkgname_as_debian(pkg$name,binary=F)
+    pkg$debname = pkgname_as_debian(pkg$name,repo=pkg$repo)
+    pkg$version <- available[pkgname,'Version']
+
+    # see if we have already built this release and uploaded it.
+    debfn <- file.path(pbuilder_results, paste(pkg$srcname, '_', pkg$version, '.orig.tar.gz', sep=''))
+    pkg$need_repack = FALSE
+    if (file.exists(debfn)) {
+        # if so, use the existing archive. this is good for three reasons:
+        # 1. it saves downloading the archive again
+        # 2. the repacking performed below changes the MD5 sum of the archive
+        #    which upsets some Debian archive software.
+        # 3. why repack more than once?
+        pkg$archive <- file.path(dir, basename(debfn))
+        file.copy(debfn,pkg$archive)
+        pkg$path = file.path(dir, paste(pkg$srcname ,pkg$version ,sep='-'))
+    } else {
+        # see if we have a local mirror in /srv/R
+        use_local = FALSE
+        if (pkg$repo == 'cran') {
+            localfn = file.path('/srv/R/Repositories/CRAN/src/contrib',paste(pkg$name,'_',pkg$version,'.tar.gz',sep=''))
+            use_local = file.exists(localfn)
+        } else if (pkg$repo == 'bioc') {
+            localfn = file.path('/srv/R/Repositories/Bioconductor/release/bioc/src/contrib',paste(pkg$name,'_',pkg$version,'.tar.gz',sep=''))
+            use_local = file.exists(localfn)
+        }
+
+        fn <- paste(pkgname, '_', pkg$version, '.tar.gz', sep='')
+        archive <- file.path(dir, fn)
+
+        if (use_local) {
+            file.copy(localfn, archive)
+        } else {
+            # use this instead of download.packages as it is more resilient to
+            # dodgy network connections (hello BT 'OpenWorld', bad ISP)
+            url <- paste(available[pkgname,'Repository'], fn, sep='/')
+            # don't log the output -- we don't care!
+            ret <- system(paste('curl','-o',shQuote(archive),'-m 720 --retry 5',shQuote(url)))
+            if (ret != 0) {
+                fail('failed to download',url)
+            }
+            # end of download.packages replacement
+        }
+
+        if (length(grep('\\.\\.',archive)) || normalizePath(archive) != archive) {
+            fail('funny looking path',archive)
+        }
+        pkg$path = sub("_\\.(zip|tar\\.gz)", ""
+                      ,gsub(.standard_regexps()$valid_package_version, ""
+                      ,archive))
+        pkg$archive = archive
+        # this is not a Debian conformant archive
+        pkg$need_repack = TRUE
+    }
+    return(pkg)
+}
+
+repack_pkg <- function(pkg) {
+    # re-pack into a Debian-named archive with a Debian-named directory.
+    debpath = file.path(dirname(pkg$archive)
+                   ,paste(pkg$srcname
+                         ,pkg$version
+                         ,sep='-'))
+    file.rename(pkg$path, debpath)
+    pkg$path = debpath
+    debarchive = file.path(dirname(pkg$archive)
+                          ,paste(pkg$srcname,'_'
+                                ,pkg$version,'.orig.tar.gz'
+                                ,sep=''))
+    wd <- getwd()
+    setwd(dirname(pkg$path))
+    # remove them pesky +x files
+    # BUT EXCLUDE configure and cleanup
+    log_system('find',shQuote(basename(pkg$path))
+                ,'-type f -a '
+                ,   '! \\( -name configure -o -name cleanup \\)'
+                ,'-exec chmod -x {} \\;')
+    # tar it all back up
+    log_system('tar -czf',shQuote(debarchive),shQuote(basename(pkg$path)))
+    setwd(wd)
+    file.remove(pkg$archive)
+    pkg$archive = debarchive
+    pkg$need_repack = FALSE
+    return(pkg)
+}
+
+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
+
+    # first a little trick; change pkgname if pkgname is contained in a bundle
+    if (!(pkgname %in% rownames(available))) {
+        bundle <- r_bundle_of(pkgname)
+        if (is.null(bundle)) {
+            fail('package',pkgname,'is unavailable')
+        }
+        pkgname <- bundle
+    }
+
+    # grab the archive and some metadata
+    pkg <- download_pkg(dir, pkgname)
+
+    # now extract the archive
+    if (!length(grep('\\.tar\\.gz',pkg$archive))) {
+        fail('archive is not tarball')
+    }
+    wd <- getwd()
+    setwd(dir)
+    ret = log_system('tar','xzf',shQuote(pkg$archive))
+    setwd(wd)
+    if (ret != 0) {
+        fail('Extraction of archive',pkg$archive,'failed.')
+    }
+
+    # if necessary, repack the archive into Debian-conformant format
+    if (pkg$need_repack) {
+        pkg <- repack_pkg(pkg)
+    }
+    if (!file.info(pkg$path)[,'isdir']) {
+        fail(pkg$path,'is not a directory and should be.')
+    }
+
+    # extract the DESCRIPTION file, which contains much metadata
+    pkg$description = read.dcf(file.path(pkg$path,'DESCRIPTION'))
+
+    # ensure consistency of version numbers
+    if ('Version' %in% names(pkg$description[1,])) {
+        if (pkg$description[1,'Version'] != available[pkg$name,'Version']) {
+            # should never happen since available is the basis upon which the
+            # package is retrieved.
+            error('available version:',available[pkg$name,'Version'])
+            error('package version:',pkg$description[1,'Version'])
+            fail('inconsistency between R package version and cached R version')
+        }
+    }
+
+    pkg$is_bundle = 'Bundle' %in% names(pkg$description[1,])
+    # note subtly of short circuit operators (no absorption)
+    if ((!pkg$is_bundle && pkg$description[1,'Package'] != pkg$name) ||
+        ( pkg$is_bundle && pkg$description[1,'Bundle'] != pkg$name)) {
+        fail('package name mismatch')
+    }
+    return(pkg)
+}
+
diff --git a/trunk/R/license.R b/trunk/R/license.R
new file mode 100644 (file)
index 0000000..846cf56
--- /dev/null
@@ -0,0 +1,155 @@
+is_acceptable_license <- function(license) {
+    # determine if license text is acceptable
+
+    if (length(grep('^file ',license))) {
+        # skip file licenses
+        return(FALSE)
+    }
+    license <- license_text_reduce(license)
+    action = db_license_override_name(license)
+    if (!is.null(action)) {
+        return(action)
+    }
+    license <- license_text_further_reduce(license)
+    action = db_license_override_name(license)
+    if (!is.null(action)) {
+        warn('Accepting/rejecting wild license as',license,'. FIX THE PACKAGE!')
+        return(action)
+    }
+    license <- license_text_extreme_reduce(license)
+    action = db_license_override_name(license)
+    if (!is.null(action)) {
+        warn('Accepting/rejecting wild license as',license,'. FIX THE PACKAGE!')
+        return(action)
+    }
+    error('Wild license',license,'did not match classic rules; rejecting')
+    return(F)
+}
+
+license_text_reduce <- function(license) {
+    # these reduction steps are sound for all conformant R license
+    # specifications.
+
+    # compress spaces into a single space
+    license = gsub('[[:space:]]+',' ',license)
+    # make all characters lower case
+    license = tolower(license)
+    # don't care about versions of licenses
+    license = chomp(sub('\\( ?[<=>!]+ ?[0-9.-]+ ?\\)',''
+                    ,sub('-[0-9.-]+','',license)))
+    # remove any extra space introduced
+    license = chomp(gsub('[[:space:]]+',' ',license))
+    return(license)
+}
+
+license_text_further_reduce <- function(license) {
+    # these reduction steps are heuristic and may lead to
+    # in correct acceptances, if care is not taken.
+
+    # uninteresting urls
+    license = gsub('http://www.gnu.org/[[:alnum:]/._-]*','',license)
+    license = gsub('http://www.x.org/[[:alnum:]/._-]*','',license)
+    license = gsub('http://www.opensource.org/[[:alnum:]/._-]*','',license)
+    # remove all punctuation
+    license = gsub('[[:punct:]]+','',license)
+    # remove any extra space introduced
+    license = chomp(gsub('[[:space:]]+',' ',license))
+    # redundant
+    license = gsub('the','',license)
+    license = gsub('see','',license)
+    license = gsub('standard','',license)
+    license = gsub('licen[sc]e','',license)
+    license = gsub('(gnu )?(gpl|general public)','gpl',license)
+    license = gsub('(mozilla )?(mpl|mozilla public)','mpl',license)
+    # remove any extra space introduced
+    license = chomp(gsub('[[:space:]]+',' ',license))
+    return(license)
+}
+
+license_text_extreme_reduce <- function(license) {
+    # remove everything that may or may not be a version specification
+    license = gsub('(ver?sion|v)? *[0-9.-]+ *(or *(higher|later|newer|greater|above))?',''
+                   ,license)
+    # remove any extra space introduced
+    license = chomp(gsub('[[:space:]]+',' ',license))
+    return(license)
+}
+
+license_text_hash_reduce <- function(text) {
+    # reduction of license text, suitable for hashing.
+    return(chomp(tolower(gsub('[[:space:]]+',' ',text))))
+}
+
+get_license <- function(pkg,license) {
+    license <- chomp(gsub('[[:space:]]+',' ',license))
+    if (length(grep('^file ',license))) {
+        if (length(grep('^file LICEN[CS]E$',license))) {
+            file = gsub('file ','',license)
+            path = file.path(pkg$path, file)
+            if (file.exists(path)) {
+                license <- license_text_reduce(readChar(path,file.info(path)$size))
+            } else {
+                path = file.path(pkg$path, 'inst', file)
+                if (file.exists(path)) {
+                    license <- license_text_reduce(readChar(path,file.info(path)$size))
+                } else {
+                    error('said to look at a license file but license file is missing')
+                }
+            }
+        } else {
+            error('invalid license file specification',license)
+            return(NA)
+        }
+    }
+    return(license)
+}
+
+get_license_hash <- function(pkg,license) {
+    return(digest(get_license(pkg,license),algo='sha1',serialize=FALSE))
+}
+
+is_acceptable_hash_license <- function(pkg,license) {
+    license_sha1 <- get_license_hash(pkg,license)
+    if (is.null(license_sha1)) {
+        return(FALSE)
+    }
+    action = db_license_override_hash(license_sha1)
+    if (is.null(action)) {
+        action = FALSE
+    }
+    if (action) {
+        warn('Wild license',license,'accepted via hash',license_sha1)
+    }
+    return(action)
+}
+
+
+accept_license <- function(pkg) {
+    # check the license
+    if (!('License' %in% names(pkg$description[1,]))) {
+        fail('package has no License: field in description!')
+    }
+    accept=NULL
+    for (license in strsplit(chomp(pkg$description[1,'License'])
+                            ,'[[:space:]]*\\|[[:space:]]*')[[1]]) {
+        if (is_acceptable_license(license)) {
+            accept=license
+            break
+        }
+        if (is_acceptable_hash_license(pkg,license)) {
+            accept=license
+            break
+        }
+    }
+    if (is.null(accept)) {
+        fail('No acceptable license:',pkg$description[1,'License'])
+    } else {
+        notice('Auto-accepted license',accept)
+    }
+    if (accept == 'Unlimited') {
+        # definition of Unlimited from ``Writing R extensions''
+        accept=paste('Unlimited (no restrictions on distribution or'
+                    ,'use other than those imposed by relevant laws)')
+    }
+    return(accept)
+}
diff --git a/trunk/R/log.R b/trunk/R/log.R
new file mode 100644 (file)
index 0000000..2a9be4e
--- /dev/null
@@ -0,0 +1,65 @@
+log_messages <- list()
+
+log_clear <- function() {
+    assign('log_messages',list(),envir=.GlobalEnv)
+}
+
+log_add <- function(text,print=T) {
+    if (print) {
+        message(text)
+    }
+    assign('log_messages',c(log_messages, text),envir=.GlobalEnv)
+}
+
+log_retrieve <- function() {
+    return(log_messages)
+}
+
+notice <- function(...) {
+    log_add(paste('N:',...))
+}
+
+warn <- function(...) {
+    log_add(paste('W:',...))
+}
+
+error <- function(...) {
+    log_add(paste('E:',...))
+}
+
+fail <- function(...) {
+    txt <- paste('E:',...)
+    log_add(txt)
+    stop(txt)
+}
+
+log_system <- function(...) {
+    r <- try((function() {
+        # pipe() does not appear useful here, since
+        # we want the return value!
+        # XXX: doesn't work with ; or | !
+        tmp <- tempfile('log_system')
+        on.exit(unlink(tmp))
+        cmd <- paste(...)
+        # unfortunately this destroys ret
+        #cmd <- paste(cmd,'2>&1','| tee',tmp)
+        cmd <- paste(cmd,'>',tmp,'2>&1')
+        ret <- system(cmd)
+        f <- file(tmp)
+        output <- readLines(f)
+        close(f)
+        unlink(tmp)
+        return(list(ret,output))
+    })())
+    if (inherits(r,'try-error')) {
+        fail('system failed on:',paste(...))
+    }
+    for (line in r[[2]]) {
+        if (!length(grep('^[WENI]:',line))) {
+            line = paste('I:',line)
+        }
+        log_add(line) #,print=F)
+    }
+    return(r[[1]])
+}
+
diff --git a/trunk/R/rdep.R b/trunk/R/rdep.R
new file mode 100644 (file)
index 0000000..141453b
--- /dev/null
@@ -0,0 +1,155 @@
+
+r_bundle_of <- function(pkgname) {
+    # returns the bundle containing pkgname or NA
+    bundles <- names(available[!is.na(available[, 'Bundle']), 'Contains'])
+    # use the first bundle
+    for (bundle in bundles) {
+        if (pkgname %in% r_bundle_contains(bundle)) {
+            return(bundle)
+        }
+    }
+    return(NULL)
+}
+
+r_bundle_contains <- function(bundlename) {
+    return(strsplit(available[bundlename,'Contains'],'[[:space:]]+')[[1]])
+}
+
+r_requiring <- function(names) {
+    for (name in names) {
+        if (!(name %in% base_pkgs) && !(name %in% rownames(available))) {
+            bundle <- r_bundle_of(name)
+            if (!is.null(bundle)) {
+                name = bundle
+                names <- c(names,bundle)
+            }
+        }
+        if (name %in% rownames(available) && !is.na(available[name,'Contains'])) {
+            names <- c(names,r_bundle_contains(name))
+        }
+    }
+    # approximately prune first into a smaller availability
+    candidates <- rownames(available)[sapply(rownames(available)
+                                            ,function(name)
+                                                length(grep(paste(names,collapse='|')
+                                                           ,available[name,r_depend_fields])) > 0)]
+    if (length(candidates) == 0) {
+        return(c())
+    }
+    # find a logical index into available of every package/bundle
+    # whose dependency field contains at least one element of names.
+    # (this is not particularly easy to read---sorry---but is much faster than
+    # the alternatives i could think of)
+    prereq=c()
+    dep_matches <- function(dep) chomp(gsub('\\([^\\)]+\\)','',dep)) %in% names
+    any_dep_matches <- function(name,field=NA)
+                any(sapply(strsplit(chomp(available[name,field])
+                                   ,'[[:space:]]*,[[:space:]]*')
+                          ,dep_matches))
+
+    for (field in r_depend_fields) {
+        matches = sapply(candidates, any_dep_matches, field=field)
+        if (length(matches) > 0) {
+            prereq = c(prereq,candidates[matches])
+        }
+    }
+    return(unique(prereq))
+}
+
+r_dependencies_of <- function(name=NULL,description=NULL) {
+    # find the immediate dependencies (children in the dependency graph) of an
+    # R package
+    if (!is.null(name) && (name == 'R' || name %in% base_pkgs)) {
+        return(data.frame())
+    }
+    if (is.null(description) && is.null(name)) {
+        fail('must specify either a description or a name.')
+    }
+    if (is.null(description)) {
+        if (!(name %in% rownames(available))) {
+            bundle <- r_bundle_of(name)
+            if (!is.null(bundle)) {
+                name <- bundle
+            } else {
+                # unavailable packages don't depend upon anything
+                return(data.frame())
+            }
+        }
+        description <- data.frame()
+        # keep only the interesting fields
+        for (field in r_depend_fields) {
+            if (!(field %in% names(available[name,]))) {
+                next
+            }
+            description[1,field] = available[name,field]
+        }
+    }
+    # extract the dependencies from the description
+    deps <- data.frame()
+    for (field in r_depend_fields) {
+        if (!(field %in% names(description[1,]))) {
+            next
+        }
+        new_deps <- lapply(strsplit(chomp(description[1,field])
+                                   ,'[[:space:]]*,[[:space:]]*')[[1]]
+                          ,r_parse_dep_field)
+        deps <- iterate(lapply(new_deps[!is.na(new_deps)],rbind),deps,rbind)
+    }
+    return (deps)
+}
+
+r_parse_dep_field <- function(dep) {
+    if (is.na(dep)) {
+        return(NA)
+    }
+    # remove other comments
+    dep = gsub('(\\(\\)|\\([[:space:]]*[^<=>!].*\\))','',dep)
+    # squish spaces
+    dep = chomp(gsub('[[:space:]]+',' ',dep))
+    # parse version
+    pat = '^([^ ()]+) ?(\\( ?([<=>!]+ ?[0-9.-]+) ?\\))?$'
+    if (!length(grep(pat,dep))) {
+        fail('R dependency',dep,'does not appear to be well-formed')
+    }
+    version = sub(pat,'\\3',dep)
+    dep = sub(pat,'\\1',dep)
+    if (!(dep %in% rownames(available))) {
+        depb <- r_bundle_of(dep)
+        if (!is.null(depb)) {
+            dep <- depb
+        }
+    }
+    return(list(name=dep,version=version))
+}
+
+r_dependency_closure <- function(fringe, forward_arcs=T) {
+    # find the transitive closure of the dependencies/prerequisites of some R
+    # packages
+    closure <- list()
+    if (is.data.frame(fringe)) {
+        fringe <- as.list(fringe$name)
+    }
+    fun = function(x) r_dependencies_of(name=x)$name
+    if (!forward_arcs) {
+        fun = r_requiring
+    }
+    while(length(fringe) > 0) {
+        # pop off the top
+        top <- fringe[[1]]
+        if (length(fringe) > 1) {
+            fringe <- fringe[2:length(fringe)]
+        } else {
+            fringe <- list()
+        }
+        src <- pkgname_as_debian(top,binary=F)
+        if (src == 'R') {
+            next
+        }
+        newdeps <- fun(top)
+        closure=c(closure,top)
+        fringe=c(fringe,newdeps)
+    }
+    # build order
+    return(rev(unique(closure,fromLast=T)))
+}
+
diff --git a/trunk/R/util.R b/trunk/R/util.R
new file mode 100644 (file)
index 0000000..e10951e
--- /dev/null
@@ -0,0 +1,25 @@
+iterate <- function(xs,z,fun) {
+    y <- z
+    for (x in xs)
+        y <- fun(y,x)
+    return(y)
+}
+
+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)
+}
+
+err <- function(...) {
+    error(...)
+    exit()
+}
+
+exit <- function() {
+    q(save='no')
+}
diff --git a/trunk/R/version.R b/trunk/R/version.R
new file mode 100644 (file)
index 0000000..184ec23
--- /dev/null
@@ -0,0 +1,92 @@
+version_new <- function(rver,debian_revision=1, debian_epoch=db_get_base_epoch()) {
+    # generate a string representation of the Debian version of an
+    # R version of a package
+    pkgver = rver
+
+    # ``Writing R extensions'' says that the version consists of at least two
+    # non-negative integers, separated by . or -
+    if (!length(grep('^([0-9]+[.-])+[0-9]+$',rver))) {
+        fail('Not a valid R package version',rver)
+    }
+
+    # Debian policy says that an upstream version should start with a digit and
+    # may only contain ASCII alphanumerics and '.+-:~'
+    if (!length(grep('^[0-9][A-Za-z0-9.+:~-]*$',rver))) {
+        fail('R package version',rver
+                  ,'does not obviously translate into a valid Debian version.')
+    }
+
+    # if rver contains a : then the Debian version must also have a colon
+    if (debian_epoch == 0 && length(grep(':',pkgver)))
+        debian_epoch = 1
+
+    # if the epoch is non-zero then include it
+    if (debian_epoch != 0)
+        pkgver = paste(debian_epoch,':',pkgver,sep='')
+
+    # always add the '-1' Debian release; nothing is lost and rarely will R
+    # packages be Debian packages without modification.
+    return(paste(pkgver,'-',debian_revision,sep=''))
+}
+
+version_epoch <- function(pkgver) {
+    # return the Debian epoch of a Debian package version
+    if (!length(grep(':',pkgver)))
+        return(0)
+    return(as.integer(sub('^([0-9]+):.*','\\1',pkgver)))
+}
+# version_epoch . version_new(x,y) = id
+# version_epoch(version_new(x,y)) = base_epoch
+
+version_revision <- function(pkgver) {
+    # return the Debian revision of a Debian package version
+    return(as.integer(sub('.*-([0-9]+)$','\\1',pkgver)))
+}
+# version_revision . version_new(x) = id
+# version_revision(version_new(x)) = 1
+
+version_upstream <- function(pkgver) {
+    # return the upstream version of a Debian package version
+    return(sub('-[0-9]+$','',sub('^[0-9]+:','',pkgver)))
+}
+# version_upstream . version_new = id
+
+version_update <- function(rver, prev_pkgver, prev_success) {
+    # return the next debian package version
+    prev_rver <- version_upstream(prev_pkgver)
+    if (prev_rver == rver) {
+        # increment the Debian revision if the previous build was successful
+        inc = 0
+        if (prev_success) {
+            inc = 1
+        }
+        return(version_new(rver
+                          ,debian_revision = version_revision(prev_pkgver)+inc
+                          ,debian_epoch    = version_epoch(prev_pkgver)
+                          ))
+    }
+    # new release
+    # TODO: implement Debian ordering over version and then autoincrement
+    #       Debian epoch when upstream version does not increment.
+    return(version_new(rver
+                      ,debian_epoch = version_epoch(prev_pkgver)
+                      ))
+}
+
+new_build_version <- function(pkgname) {
+    if (!(pkgname %in% rownames(available))) {
+        bundle <- r_bundle_of(pkgname)
+        if (is.null(bundle)) {
+            fail('tried to discover new version of',pkgname,'but it does not appear to be available')
+        }
+        name <- bundle
+    }
+    db_ver <- db_latest_build_version(pkgname)
+    db_succ <- db_latest_build_status(pkgname)[[1]]
+    latest_r_ver <- available[pkgname,'Version']
+    if (!is.null(db_ver)) {
+        return(version_update(latest_r_ver, db_ver, db_succ))
+    }
+    return(version_new(latest_r_ver))
+}
+
diff --git a/trunk/R/zzz.R.in b/trunk/R/zzz.R.in
new file mode 100644 (file)
index 0000000..e486f50
--- /dev/null
@@ -0,0 +1,24 @@
+.First.lib <- function(libname, pkgname) {
+    global <- function(name,value) assign(name,value,envir=.GlobalEnv)
+    global("maintainer", 'cran2deb autobuild <cran2deb@example.org>')
+    global("root", system.file(package='cran2deb'))
+    global("cache_root", '/var/cache/cran2deb')
+    global("pbuilder_results", '/var/cache/cran2deb/results')
+    global("pbuilder_config", '/etc/cran2deb/pbuilderrc')
+    global("dput_config", '/etc/cran2deb/dput.cf')
+    global("dinstall_config", '/etc/cran2deb/mini-dinstall.conf')
+    global("dinstall_archive", '/etc/cran2deb/archive')
+    global("r_depend_fields", c('Depends','Imports')) # Suggests, Enhances
+    # git_revision {
+    # git_revision }
+    global("changesfile", function(srcname,version='*') {
+        return(file.path(pbuilder_results
+                        ,paste(srcname,'_',version,'_'
+                              ,host_arch(),'.changes',sep='')))
+    })
+
+    cache <- file.path(cache_root,'cache.rda')
+    if (file.exists(cache)) {
+        load(cache,envir=.GlobalEnv)
+    }
+}
diff --git a/trunk/README b/trunk/README
new file mode 120000 (symlink)
index 0000000..a6047ac
--- /dev/null
@@ -0,0 +1 @@
+inst/doc/README
\ No newline at end of file
diff --git a/trunk/configure b/trunk/configure
new file mode 100755 (executable)
index 0000000..106c58a
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+# stamp the source with the originating git revision.
+git_rev=$(git show --pretty'=oneline' 'HEAD' | head -n1 | cut -f1 -d' ')
+#git_r='assign("git_revision","'$git_rev'",envir=.GlobalEnv)'
+git_r='    global("git_revision","'$git_rev'")'
+
+awk -v "git_r=$git_r" '
+/# git_revision }/ {suppress=0}
+suppress == 0 {print}
+/# git_revision {/ {print git_r; suppress=1}
+' <R/zzz.R.in >R/zzz.R
diff --git a/trunk/data/populate_depend_aliases b/trunk/data/populate_depend_aliases
new file mode 100644 (file)
index 0000000..d7dc09a
--- /dev/null
@@ -0,0 +1,75 @@
+alias_build boost libboost-dev 
+alias_build boost libboost-graph-dev 
+alias_build ggobi ggobi 
+alias_run ggobi ggobi 
+alias_build glade libglade2-dev 
+alias_run glade libglade2-0 
+alias_build glib libglib2.0-dev 
+alias_run glib libglib2.0-0 
+alias_build glu libglu1-mesa-dev 
+alias_run glu libglu1-mesa 
+alias_build gmp libgmp3-dev 
+alias_run gmp libgmp3c2 
+alias_build gsl libgsl0-dev 
+alias_run gsl libgsl0ldbl 
+alias_build ignore build-essential 
+alias_build java openjdk-6-jdk 
+alias_build java libgcj9-dev 
+alias_run java openjdk-6-jre 
+alias_build libatk libatk1.0-dev 
+alias_run libatk libatk1.0-0 
+alias_build libcairo libcairo2-dev 
+alias_run libcairo libcairo2 
+alias_run libcurl libcurl3 
+alias_build libcurl libcurl4-openssl-dev 
+alias_build libdieharder libdieharder-dev 
+alias_run libdieharder libdieharder2 
+alias_build libfontconfig libfontconfig1-dev 
+alias_run libfontconfig libfontconfig1 
+alias_build libfreetype libfreetype6-dev 
+alias_run libfreetype libfreetype6 
+alias_build libgdal libgdal1-dev 
+alias_run libgdal libgdal1-1.5.0 
+alias_build libgd libgd2-noxpm-dev 
+alias_run libgd libgd2-noxpm 
+alias_build libgraphviz libgraphviz-dev 
+alias_run libgraphviz libgraphviz4 
+alias_build libgtk libgtk2.0-dev 
+alias_run libgtk libgtk2.0-0 
+alias_build libjpeg libjpeg62-dev 
+alias_run libjpeg libjpeg62 
+alias_build libmagick libmagick9-dev 
+alias_run libmagick libmagick9 
+alias_build libpango libpango1.0-dev 
+alias_run libpango libpango1.0-0 
+alias_build libpng libpng12-dev 
+alias_run libpng libpng12-0 
+alias_build libxml libxml2-dev 
+alias_run libxml libxml2 
+alias_build msttcorefonts msttcorefonts 
+alias_run msttcorefonts msttcorefonts 
+alias_run netcdf libnetcdf4 
+alias_build netcdf libnetcdf-dev 
+alias_build opengl libgl1-mesa-dev 
+alias_run opengl libgl1-mesa-glx 
+alias_build pari-gp pari-gp 
+alias_run pari-gp pari-gp 
+alias_build proj proj 
+alias_run proj proj 
+alias_build quantlib libquantlib0-dev 
+alias_run quantlib libquantlib-0.9.6 
+alias_run sqlite libsqlite3-0 
+alias_build sqlite libsqlite3-dev 
+alias_build zlib zlib1g-dev 
+alias_run zlib zlib1g 
+alias_build cshell tcsh|csh|c-shell 
+alias_run cshell tcsh|csh|c-shell 
+alias_build autotools autotools-dev 
+alias_build tcl tcl8.4-dev 
+alias_build tk tk8.4-dev 
+alias_build odbc unixodbc-dev 
+alias_build mysql libmysqlclient15-dev 
+alias_build mpi libopenmpi-dev 
+alias_build pvm pvm-dev 
+alias_build hdf5 libhdf5-serial-dev 
+alias_build sprng libsprng2-dev 
diff --git a/trunk/data/populate_forcedep b/trunk/data/populate_forcedep
new file mode 100644 (file)
index 0000000..799d286
--- /dev/null
@@ -0,0 +1,18 @@
+force java rJava 
+force autotools rJava 
+force sqlite RSQLite 
+force sqlite SQLiteDF 
+force boost RBGL 
+force netcdf ncdf 
+force cshell dse 
+force libgtk cairoDevice 
+force tcl tkrplot 
+force tk tkrplot 
+force mysql RMySQL 
+force mpi Rmpi 
+force pvm rpvm 
+force hdf5 hdf5 
+force libgtk rggobi 
+force libxml rggobi 
+force sprng rsprng 
+force gmp rsprng 
diff --git a/trunk/data/populate_licenses b/trunk/data/populate_licenses
new file mode 100644 (file)
index 0000000..ad791bd
--- /dev/null
@@ -0,0 +1,99 @@
+accept AGPL
+accept APACHE
+accept ARTISTIC
+accept BSD
+accept CeCILL
+accept CPL
+accept GPL
+accept GPLQA
+accept GPL+QHULL
+accept LGPL
+accept MIT
+accept MPL
+accept TCLTK2
+accept UNLIMITED
+accept X11
+reject distrib-noncomm
+reject GPL+ACM
+reject MCLUST
+reject UNCLEAR
+hash APACHE /usr/share/common-licenses/Apache-2.0
+hash ARTISTIC /usr/share/common-licenses/Artistic
+hash BSD /usr/share/common-licenses/BSD
+hash GPL /usr/share/common-licenses/GPL-2
+hash GPL /usr/share/common-licenses/GPL-3
+hash LGPL /usr/share/common-licenses/LGPL-2
+hash LGPL /usr/share/common-licenses/LGPL-2.1
+hash LGPL /usr/share/common-licenses/LGPL-3
+pkg BSD minpack.lm
+pkg CeCILL LLAhclust
+pkg CPL lmom
+pkg distrib-noncomm Bhat
+pkg distrib-noncomm conf.design
+pkg distrib-noncomm gpclib
+pkg distrib-noncomm mlbench
+pkg distrib-noncomm poplab
+pkg distrib-noncomm PredictiveRegression
+pkg distrib-noncomm PTAk
+pkg distrib-noncomm siggenes
+pkg GPL+ACM akima
+pkg GPL+ACM tripack
+pkg GPL degreenet
+pkg GPL ergm
+pkg GPL gmodels
+pkg GPL ICE
+pkg GPL latentnet
+pkg GPL network
+pkg GPL networksis
+pkg GPL pastecs
+pkg GPL pbatR
+pkg GPL PKtools
+pkg GPL+QHULL geometry
+pkg GPL reldist
+pkg GPL RXshrink
+pkg GPL snpMatrix
+pkg GPL splancs
+pkg GPL statnet
+pkg GPL uroot
+pkg LGPL R.huge
+pkg MCLUST mclust
+pkg TCLTK2 tcltk2
+pkg UNCLEAR adapt
+pkg UNCLEAR cat
+pkg UNCLEAR cosmo
+pkg UNCLEAR mix
+pkg UNCLEAR mlmm
+pkg UNCLEAR norm
+pkg UNCLEAR pan
+pkg UNCLEAR titecrm
+pkg UNCLEAR tlnise
+pkg UNLIMITED boolean
+pkg GPLQA regtest
+pkg GPL gllm
+pkg GPL rake
+pkg GPL Rigroup
+pkg GPL ICEinfer
+pkg GPL partsm
+pkg GPL timsac
+pkg GPL HTMLapplets
+pkg GPL moc
+pkg GPL ibdreg
+pkg AGPL accuracy
+pkg AGPL Zelig
+pkg GPL TWIX
+pkg GPL aplpack
+accept distrib-noncomm
+accept GPL+ACM
+accept MCLUST
+accept UNCLEAR
+accept acepack
+accept ff
+pkg acepack acepack
+pkg ff ff
+pkg AGPL AIS
+pkg AGPL BARD
+accept NISTnls
+pkg NISTnls NISTnls
+pkg GPL NMMAPSlite
+pkg GPL PET
+pkg distrib-noncomm RLadyBug
diff --git a/trunk/data/populate_sysreq b/trunk/data/populate_sysreq
new file mode 100644 (file)
index 0000000..b8f4b3e
--- /dev/null
@@ -0,0 +1,37 @@
+sysreq ignore gcc 
+sysreq ignore gnu make 
+sysreq ignore % if present 
+sysreq ignore none 
+sysreq libcurl curl 
+sysreq ggobi ggobi 
+sysreq libatk atk 
+sysreq libcairo cairo 
+sysreq libdieharder dieharder% 
+sysreq libfontconfig fontconfig 
+sysreq libfreetype freetype 
+sysreq libfreetype %freetype 
+sysreq libgd libgd 
+sysreq libgdal %gdal% 
+sysreq opengl opengl 
+sysreq glade %glade 
+sysreq glib glib 
+sysreq glu glu library 
+sysreq gmp gmp 
+sysreq libgraphviz graphviz 
+sysreq gsl gnu gsl% 
+sysreq gsl gnu scientific library 
+sysreq libgtk gtk% 
+sysreq libjpeg libjpeg% 
+sysreq libmagick imagemagick 
+sysreq libpango pango 
+sysreq libpng libpng 
+sysreq quantlib quantlib% 
+sysreq libxml libxml% 
+sysreq msttcorefonts msttcorefonts 
+sysreq pari-gp pari/gp 
+sysreq proj proj% 
+sysreq zlib zlib 
+sysreq java java 
+sysreq odbc %odbc% 
+sysreq ignore drivers. see readme. 
+sysreq ignore r must be compiled with --enable-r-shlib if the server is to be built 
diff --git a/trunk/data/quit b/trunk/data/quit
new file mode 100644 (file)
index 0000000..ff60466
--- /dev/null
@@ -0,0 +1 @@
+quit
diff --git a/trunk/exec/autobuild b/trunk/exec/autobuild
new file mode 100755 (executable)
index 0000000..0b24cba
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env r
+## DOC: cran2deb autobuild
+## DOC:     automatically builds all out of date packages.
+## DOC:
+suppressMessages(library(cran2deb))
+
+if (exists('argv')) { # check for littler
+    db_update_package_versions()
+    outdated <- db_outdated_packages()
+    build_order <- r_dependency_closure(outdated)
+    notice('build order',paste(build_order,collapse=', '))
+    for (pkg in build_order) {
+        build(pkg,c())
+    }
+}
diff --git a/trunk/exec/build b/trunk/exec/build
new file mode 100755 (executable)
index 0000000..b875e60
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env r
+## DOC: cran2deb build [-D extra_dep1,extra_dep2,...] package1 package2 ...
+## DOC:     builds a particular package.
+## DOC:
+suppressMessages(library(cran2deb))
+
+if (exists('argv')) { # check for littler
+    argc <- length(argv)
+    extra_deps = list()
+    extra_deps$deb = c()
+    extra_deps$r = c()
+    opts = c('-D','-R')
+    # first argument is the root --- this is dealt with elsewhere.
+    for (i in 2:argc) {
+        if (!(argv[i] %in% opts)) {
+            if (argc >= i) {
+                argv <- argv[i:argc]
+            } else {
+                argv <- list()
+            }
+            argc = argc - i + 1
+            break
+        }
+        if (i == argc) {
+            err('missing argument')
+        }
+        if (argv[i] == '-D') {
+            extra_deps$deb = c(extra_deps$deb,strsplit(chomp(argv[i+1]),',')[[1]])
+        }
+        if (argv[i] == '-R') {
+            extra_deps$r = c(extra_deps$r,strsplit(chomp(argv[i+1]),',')[[1]])
+            extra_deps$deb = c(extra_deps$deb,lapply(extra_deps$r,pkgname_as_debian))
+        }
+    }
+    if (argc == 0) {
+        err('usage: cran2deb [-D extra_dep1,extra_dep2,...] package package ...')
+    }
+    build_order <- r_dependency_closure(c(extra_deps$r,argv))
+    notice('build order',paste(build_order,collapse=', '))
+    for (pkg in build_order) {
+        build(pkg,extra_deps,force=pkg %in% argv)
+    }
+}
diff --git a/trunk/exec/build_ctv b/trunk/exec/build_ctv
new file mode 100755 (executable)
index 0000000..1e39e04
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+## DOC: cran2deb build_ctv
+## DOC:     build all CRAN TaskViews. warning and error logs in ./ctv/
+## DOC:
+
+for ctv in $(cran2deb cran_pkgs query); do
+    echo task view $ctv...
+    if [ ! -e "ctv/$ctv" ]; then
+        cran2deb build_some "$ctv"
+        mkdir -p "ctv/$ctv"
+        mv warn fail "ctv/$ctv"
+    fi
+done
+
diff --git a/trunk/exec/build_some b/trunk/exec/build_some
new file mode 100755 (executable)
index 0000000..f02af9d
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/rc
+## DOC: cran2deb build_some [taskview1 taskview2 ...]
+## DOC:     build some packages, logging warnings into ./warn/$package
+## DOC:     and failures into ./fail/$package. with no arguments a random
+## DOC:     sample of packages is built.  the file ./all_pkgs overrides this
+## DOC:     behaviour and is expected to be a list of packages to build.
+## DOC:
+
+mkdir -p warn fail
+shift
+if [ ! -e all_pkgs ]; then
+    cran2deb cran_pkgs $* >all_pkgs
+fi
+
+for pkg in $(cat all_pkgs); do
+    if (~ $pkg *..* */*) {
+        echo bad name $pkg >>fail/ERROR
+    } else if ([ -e warn/$pkg ]) {
+        echo skipping $pkg...
+    } else if ([ -e fail/$pkg ]) {
+        echo skipping failed $pkg...
+    } else {
+        echo -n .. package $pkg
+        fail=0
+        cran2deb build $pkg >fail/$pkg >[2=1] || fail=1
+        if (~ $fail 0) {
+            echo success
+            grep '^[WE]:' fail/$pkg >warn/$pkg
+#            if (~ `{stat -c '%s' warn/$pkg} 0) {
+#                rm -f warn/$pkg
+#            }
+            rm -f fail/$pkg
+        } else {
+            echo FAILED
+        }
+    }
+done
diff --git a/trunk/exec/copy_find b/trunk/exec/copy_find
new file mode 100755 (executable)
index 0000000..eebcec1
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/rc
+## DOC: cran2deb copy_find path
+## DOC:     a tool for finding (heuristically) some copyright notices.
+## DOC:
+kwords='copyright|warranty|redistribution|modification|patent|trademark|licen[cs]e|permission'
+nl=`` () {printf '\n'}
+ifs=$nl {
+    files=`{find $1 ! -path '*debian*' -type f}
+    lines=()
+    for (file in $files) {
+        notices=`{grep -H '(C)' $file}
+        notices=($notices `{grep -HEi $kwords $file})
+        lines=($lines `{{for (notice in $notices) echo $notice} | sort -u})
+    }
+    # let's hope no file has a : in it
+    ifs=() { seen_files=`{{for (line in $lines) echo $line} | cut -d: -f1} }
+    missing_copyright=()
+    for (file in $files) {
+        if (echo -n $seen_files | grep -q '^'^$file^'$') {
+        } else {
+            missing_copyright=($missing_copyright $file)
+        }
+    }
+    echo 'Suspect copyright notices:'
+    for (line in $lines) echo '    '$line
+    echo 'Files without *suspect* copyright notices:'
+    for (missing in $missing_copyright) {
+        echo '    '$missing
+        echo '       type: '`{file $missing}
+        echo '      chars: '`{wc -c $missing | awk '{print $1}'}
+        echo '      lines: '`{wc -l $missing | awk '{print $1}'}
+    }
+}
diff --git a/trunk/exec/cran2deb b/trunk/exec/cran2deb
new file mode 100755 (executable)
index 0000000..7efedc7
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+umask 002
+root=$(r -e 'suppressMessages(library(cran2deb));cat(system.file(package="cran2deb"),file=stdout())')
+cmd=$1
+shift
+if [ ! -x "$root/exec/$cmd" ]; then
+    echo unknown command $cmd
+    exit 1
+fi
+"$root/exec/$cmd" "$root" $*
diff --git a/trunk/exec/cran_pkgs b/trunk/exec/cran_pkgs
new file mode 100755 (executable)
index 0000000..b8a2dcb
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env r
+## DOC: cran2deb cran_pkgs
+## DOC:     print a list of 800 packages picked at random
+## DOC: cran2deb cran_pkgs query
+## DOC:     print the names of all CRAN TaskViews
+## DOC: cran2deb cran_pkgs taskview1 taskview2 ...
+## DOC:     print the names of all packages in a particular CRAN TaskView
+## DOC:
+
+library(cran2deb)
+
+if (length(argv) == 1) {
+    writeLines(sample(dimnames(available)[[1]],800))
+} else {
+    argv = argv[2:length(argv)]
+    if (argv[1] == 'query') {
+        for (ctv in ctv.available) {
+            writeLines(ctv$name)
+        }
+        q(save='no')
+    }
+    # list of task lists
+    for (ctv in ctv.available) {
+        if (ctv$name %in% argv) {
+            writeLines(ctv$packagelist$name)
+        }
+    }
+}
diff --git a/trunk/exec/depend b/trunk/exec/depend
new file mode 100755 (executable)
index 0000000..2552d8f
--- /dev/null
@@ -0,0 +1,95 @@
+#!/usr/bin/env r
+## DOC: cran2deb depend
+## DOC:     add dependency aliases, system requirements and forced dependencies
+## DOC:
+
+suppressPackageStartupMessages(library(cran2deb))
+suppressPackageStartupMessages(library(digest))
+
+exec_cmd <- function(argc, argv) {
+    usage <- function()
+        message(paste('usage: alias <alias> <debian_pkg>'
+                     ,'       alias_run <alias> <debian_pkg>'
+                     ,'       alias_build <alias> <debian_pkg>'
+                     ,'       sysreq <alias> <sysreq sql pattern>'
+                     ,'       force <alias> <r_pkg>'
+                     ,'       ls [aliases|force|sysreq]'
+                     ,'       quit'
+                     ,sep='\n'))
+
+    if (argc < 1) {
+        return()
+    }
+    cmd = argv[1]
+
+    if (cmd == 'alias') {
+        if (argc < 3) {
+            usage()
+            return()
+        }
+        alias = argv[2]
+        pkg = argv[3]
+        db_add_depends(alias, pkg, build=T)
+        pkg = gsub('-dev$','',pkg)
+        db_add_depends(alias, pkg, build=F)
+    } else if (cmd == 'alias_run' || cmd == 'alias_build') {
+        if (argc < 3) {
+            usage()
+            return()
+        }
+        db_add_depends(argv[2], argv[3], cmd == 'alias_build')
+    } else if (cmd == 'sysreq') {
+        if (argc < 3) {
+            usage()
+            return()
+        }
+        sysreq = paste(argv[3:argc],collapse=' ')
+        db_add_sysreq_override(sysreq,argv[2])
+    } else if (cmd == 'force') {
+        if (argc < 3) {
+            usage()
+            return()
+        }
+        db_add_forced_depends(argv[3],argv[2])
+    } else if (cmd == 'ls') {
+        if (argc < 2 || argv[2] == 'aliases') {
+            aliases <- db_depends()
+            for (i in rownames(aliases)) {
+                type = 'alias_run'
+                if (as.logical(aliases[i,'build'])) {
+                    type = 'alias_build'
+                }
+                cat(paste(type,aliases[i,'alias'],aliases[i,'debian_pkg'],'\n'))
+            }
+        } else if (argv[2] == 'sysreq') {
+            sysreqs <- db_sysreq_overrides()
+            for (i in rownames(sysreqs)) {
+                cat(paste('sysreq',sysreqs[i,'depend_alias'],sysreqs[i,'r_pattern'],'\n'))
+            }
+        } else if (argv[2] == 'force') {
+            forced <- db_forced_depends()
+            for (i in rownames(forced)) {
+                cat(paste('force',forced[i,'depend_alias'],forced[i,'r_name'],'\n'))
+            }
+        } else {
+            usage()
+            return()
+        }
+    } else if (cmd == 'quit') {
+        exit()
+    } else if (cmd == '#') {
+    } else {
+        usage()
+        return()
+    }
+}
+
+argc <- length(argv)
+if (argc > 1) {
+    exec_cmd(argc-1,argv[c(2:argc)])
+} else {
+    while(T) {
+        argv <- strsplit(readline('depend> '),'[[:space:]]+')[[1]]
+        exec_cmd(length(argv),argv)
+    }
+}
diff --git a/trunk/exec/diagnose b/trunk/exec/diagnose
new file mode 100755 (executable)
index 0000000..3740b50
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/rc
+
+success=`{ls /var/cache/cran2deb/results/*.deb | wc -l}
+echo $success successful packages
+total=$success
+
+fn count_dup { sort | uniq -c | sort -n}# | awk '$1 > 1{print}' }
+fn collapse { a=`{echo $^* | sed -e 's/ | /|/g'}; echo $^a }
+echo 'warnings:'
+{for (x in (warn/* /dev/null)) cut -d: -f3- <$x | sort -u} | awk '{print $1}' | count_dup
+echo
+
+faildep=('^Error: package ''.*'' could not be loaded'
+     '|' '^ERROR: lazy loading failed for package ''.*'''
+     '|' '^[[:space:]]*package .* is not available'
+     '|' 'there is no package called ''.*''')
+faildeb='do not know what to do with SystemRequirement:'
+faillic=('No acceptable license: ')
+failspc=': No space left on device'
+failhdr='error: .*\.hp?p?: No such file or directory'
+faildep=`{collapse $faildep}
+faildep=$^faildep
+faillic=`{collapse $faillic}
+faillic=$^faillic
+other=''
+
+nfaildep=`{grep -El $faildep fail/* /dev/null | wc -l}
+echo $nfaildep failed R dependencies.
+grep -Eh $faildep fail/* | count_dup
+other=$faildep
+#total=$total+$nfaildep
+echo
+
+nfaillic=`{grep -El $faillic `{grep -EL $other fail/*} /dev/null | wc -l}
+echo $nfaillic failed licenses.
+grep -Eh $faillic `{grep -EL $other fail/*} | count_dup
+other=$other^'|'^$faillic
+total=$total+$nfaillic
+echo
+
+nfailspc=`{grep -El $failspc `{grep -EL $other fail/*} /dev/null | wc -l}
+echo $nfailspc out of space
+other=$other^'|'^$failspc
+total=$total+$nfailspc
+echo
+
+nfailhdr=`{grep -El $failhdr `{grep -EL $other fail/*} /dev/null | wc -l}
+echo $nfailhdr missing C header
+grep -Eh $failhdr `{grep -EL $other fail/* /dev/null} | count_dup
+other=$other^'|'^$failhdr
+total=$total+$nfailhdr
+echo
+
+nfaildeb=`{grep -El $faildeb `{grep -EL $other fail/*} /dev/null | wc -l}
+echo $nfaildeb system requirement failures.
+grep -Eh $faildeb `{grep -EL $other fail/* /dev/null} | count_dup
+other=$other^'|'^$faildeb
+total=$total+$nfaildeb
+echo
+
+nfailother=`{hoc -e `{grep -EL $other fail/* /dev/null | wc -l}^-1}
+echo $nfailother other failures.
+
+total=`{hoc -e $total}
+succrate=`{hoc -e $success/'('$total')*100'}
+echo $succrate% success rate '('$total' total)'
+#total=`{hoc -e $total-$nfaillic-$nfailspc-$nfailhdr}
+total=`{hoc -e $total-$nfaillic-$nfailspc}
+succrate=`{hoc -e $success/'('$total')*100'}
+echo $succrate% success rate with exclusions '('$total' total)'
+grep -EL $other fail/* /dev/null | xargs tail -n 20
+
diff --git a/trunk/exec/diagnose_ctv b/trunk/exec/diagnose_ctv
new file mode 100755 (executable)
index 0000000..5e7ef03
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+(for x in ctv/*; do echo;echo;echo "$x: "; cd "$x" && cran2deb diagnose && cd ../..; done) >ctv.results
diff --git a/trunk/exec/get_base_pkgs b/trunk/exec/get_base_pkgs
new file mode 100755 (executable)
index 0000000..d08d625
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env r
+for (pkg in rownames(installed.packages())) {
+       message(pkg)
+}
diff --git a/trunk/exec/help b/trunk/exec/help
new file mode 100755 (executable)
index 0000000..3eeabab
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo usage: cran2deb '<cmd> [args ...]'
+echo where '<cmd>' is one of
+grep '## [D]OC:' $1/exec/* | sed -e 's/.*[D]OC://'
+echo
+echo installation root is: $1
diff --git a/trunk/exec/latest_log b/trunk/exec/latest_log
new file mode 100644 (file)
index 0000000..055991a
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env r
+## DOC: cran2deb latest_log package1 package2 ...
+## DOC:     show the latest log output for <package>
+suppressMessages(library(cran2deb))
+
+if (exists('argv')) {
+    for (pkg in argv) {
+        cat(db_latest_build(pkg)$log)
+        cat('\n')
+    }
+}
diff --git a/trunk/exec/license b/trunk/exec/license
new file mode 100755 (executable)
index 0000000..74e01a5
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/bin/env r
+## DOC: cran2deb license
+## DOC:     add licenses and change acceptance/rejection of licenses
+## DOC:
+
+suppressPackageStartupMessages(library(cran2deb))
+suppressPackageStartupMessages(library(digest))
+
+exec_cmd <- function(argc, argv) {
+    usage <- function()
+        message(paste('usage: accept <license>'
+                     ,'       reject <license>'
+                     ,'       hash <license> (<path>|<hash>)'
+                     ,'       pkg <license> <pkg>'
+                     ,'       view <pkg>'
+                     ,'       ls'
+                     ,'       quit'
+                     ,sep='\n'))
+
+    if (argc < 1) {
+        exit()
+    }
+    cmd = argv[1]
+
+    if (cmd == 'accept' || cmd == 'reject') {
+        if (argc != 2) {
+            usage()
+            return()
+        }
+        action = (cmd == 'accept')
+        db_add_license_override(argv[2],action)
+    } else if (cmd == 'hash') {
+        if (argc != 3) {
+            usage()
+            return()
+        }
+        license = argv[2]
+        path = argv[3]
+        if (is.null(db_license_override_name(license))) {
+            error('license',license,'is not known; add it first')
+            return()
+        }
+        if (file.exists(path)) {
+            license_sha1 = digest(readChar(path,file.info(path)$size)
+                                 ,algo='sha1', serialize=FALSE)
+        } else if (length(grep('^[0-9a-f]{40}$',path))) {
+            license_sha1 = path
+        } else {
+            error(path,'does not exist and does not look like an SHA1 hash')
+            return()
+        }
+        db_add_license_hash(license,license_sha1)
+    } else if (cmd == 'pkg') {
+        if (argc != 3) {
+            usage()
+            return()
+        }
+        license <- argv[2]
+        pkg_name <- argv[3]
+        current_action <- db_license_override_name(license)
+        if (is.null(current_action)) {
+            notice('license',license,'is not known; add it')
+            return()
+        }
+        action = 'accept'
+        if (!current_action) {
+            action = 'reject'
+        }
+        notice('in future, will',action,'the package',pkg_name,'under license',license)
+        tmp <- setup()
+        success <- try((function() {
+            pkg <- prepare_pkg(tmp,pkg_name)
+            if (!('License' %in% names(pkg$description[1,]))) {
+                error('package',pkg$name,'has no License: field in DESCRIPTION')
+                return()
+            }
+            first_license = (strsplit(chomp(pkg$description[1,'License'])
+                                     ,'[[:space:]]*\\|[[:space:]]*')[[1]])[1]
+            license_sha1 <- get_license_hash(pkg,first_license)
+            db_add_license_hash(license,license_sha1)
+        })())
+        cleanup(tmp)
+        if (inherits(success,'try-error')) {
+            return()
+        }
+    } else if (cmd == 'view') {
+        if (argc != 2) {
+            usage()
+            return()
+        }
+        pkg_name <- argv[2]
+        tmp <- setup()
+        success <- try((function() {
+            pkg <- prepare_pkg(tmp,pkg_name)
+            if (!('License' %in% names(pkg$description[1,]))) {
+                error('package',pkg$name,'has no License: field in DESCRIPTION')
+                return()
+            }
+            first_license = (strsplit(chomp(pkg$description[1,'License'])
+                                     ,'[[:space:]]*\\|[[:space:]]*')[[1]])[1]
+            first_license = get_license(pkg,first_license)
+            cat(strwrap(first_license),file='|less')
+        })())
+        cleanup(tmp)
+        if (inherits(success,'try-error')) {
+            return()
+        }
+    } else if (cmd == 'ls') {
+        for (x in db_license_overrides()) print(x)
+    } else if (cmd == 'help') {
+        usage()
+        return()
+    } else if (cmd == 'quit') {
+        exit()
+    }
+}
+
+argc <- length(argv)
+if (argc > 1) {
+    exec_cmd(argc-1,argv[c(2:argc)])
+} else {
+    while(T) {
+        argv <- strsplit(readline('license> '),'[[:space:]]+')[[1]]
+        exec_cmd(length(argv),argv)
+    }
+}
diff --git a/trunk/exec/repopulate b/trunk/exec/repopulate
new file mode 100755 (executable)
index 0000000..ab3ea60
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+## DOC: cran2deb repopulate
+## DOC:     repopulate the cran2deb database and configurations from a new cran2deb release
+## DOC:
+
+umask 002
+root=$1
+shift
+for x in $(find /etc/cran2deb/ -type f -name '*.in'); do
+    y=$(echo $x | sed -e 's,.in$,,')
+    sed -e "s:@ROOT@:$root:g" <"$x" >"$y"
+done
+
+# now do an update to reflect any config changes
+"$root/exec/update" "$root"
+
+(for fn in populate_licenses quit; do
+    cat "$root/data/$fn"
+done) | "$root/exec/license" "$root"
+
+(for fn in populate_depend_aliases populate_sysreq populate_forcedep quit; do
+    cat "$root/data/$fn"
+done) | "$root/exec/depend" "$root"
+
diff --git a/trunk/exec/root b/trunk/exec/root
new file mode 100755 (executable)
index 0000000..3133778
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo $1
diff --git a/trunk/exec/update b/trunk/exec/update
new file mode 100755 (executable)
index 0000000..7bcc78f
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/rc
+## DOC: cran2deb update
+## DOC:     update the cran2deb cache and database
+## DOC: cran2deb update full
+## DOC:     force a full update of the cran2deb cache and database
+## DOC:
+
+umask 002
+root=$1
+shift
+mkdir -p /var/cache/cran2deb/results || exit 1
+mini-dinstall --batch -c /etc/cran2deb/mini-dinstall.conf || exit 1
+update_period=10800
+if (~ $1 full || ![ -e /var/cache/cran2deb/cache.rda ] ) {
+    delta=`{awk 'END{print '^$update_period^'+1}' </dev/null}
+    echo Forcing cache update
+} else {
+    delta=`{awk 'END{print '^`{date +%s}^-^`{stat -c '%Y' /var/cache/cran2deb/cache.rda}^'}' </dev/null}
+    echo Cache is $delta seconds out of date.
+}
+if (![ -e /var/cache/cran2deb/cache.rda ] || [ $delta -gt $update_period ]) {
+    mode=create
+    if ([ -e /var/cache/pbuilder/base-cran2deb.tgz ]) {
+        mode=update
+    }
+    sudo pbuilder $mode --override-config --configfile /etc/cran2deb/pbuilderrc
+    $root/exec/update_cache $root
+}
+
diff --git a/trunk/exec/update_cache b/trunk/exec/update_cache
new file mode 100755 (executable)
index 0000000..6893846
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env Rscript
+library(cran2deb)
+library(ctv)
+
+argv <- commandArgs()
+argv <- argv[-(1:match("--args", argv))]
+
+#mirror <- 'http://cran.uk.r-project.org/'
+mirror <- 'http://cran.r-project.org/'
+
+message('updating list of available R packages...')
+available <- available.packages(contrib.url(mirror))
+
+#available <- rbind(available,available.packages(contrib.url('http://www.bioconductor.org/')))
+#dupes <- duplicated(rownames(available), fromLast=T)
+#available <- available[!dupes,]
+
+message('updating list of available R task views...')
+ctv.available <- available.views(repo=mirror)
+
+message('updating list of base R packages...')
+base_pkgs <- readLines(pipe(paste('sudo pbuilder --execute --override-config --configfile'
+                                 ,shQuote(pbuilder_config),'-- /usr/bin/R --vanilla 2>&1 >/dev/null <'
+                                 ,shQuote(file.path(root,'exec/get_base_pkgs'))
+                                 ,'| grep -v ^W:')))
+
+message('updating list of existing Debian packages...')
+debian_pkgs <- readLines(pipe('apt-cache rdepends r-base-core | sed -e "/^  r-cran/{s/^[[:space:]]*r/r/;p}" -e d | sort -u'))
+
+save(debian_pkgs, base_pkgs, available, ctv.available, file=file.path(cache_root,'cache.rda'),eval.promises=T)
+
+message('synchronising database...')
+db_update_package_versions()
diff --git a/trunk/inst/doc/DB_NOTES b/trunk/inst/doc/DB_NOTES
new file mode 100644 (file)
index 0000000..0960026
--- /dev/null
@@ -0,0 +1,81 @@
+this file documents some of R/db.R -- the DB interface code.
+
+
+table: sysreq_override
+fields: depend_alias TEXT, r_pattern TEXT
+
+SystemRequirements LIKE r_pattern are mapped onto the dependency alias
+depend_alias (this is a foreign key in debian_dependency).
+
+table: debian_dependency
+fields: id INTEGER PRIMARY KEY AUTOINCREMENT,
+        alias TEXT,
+        build INTEGER NOT NULL,
+        debian_pkg TEXT NOT NULL,
+        UNIQUE (alias,build,debian_pkg)
+
+sets up a dependency alias. each row is a Debian dependency entry, debian_pkg, which
+may be added to Depends: (and Build-Depends: if build = 1).
+
+table: forced_depends
+fields: r_name TEXT.
+        depend_alias TEXT,
+        PRIMARY KEY (r_name,depend_alias)'
+
+forces the R package r_name to have the dependencies implied by depend_alias (a foriegn
+key in debian_dependency).
+
+table: license_override
+fields: name TEXT PRIMARY KEY,
+        accept INT NOT NULL
+
+specifies whether the license, name, is accepted or rejected.
+
+table: license_hashes
+fields: name TEXT
+        sha1 TEXT PRIMARY KEY
+
+matches an SHA1 hash of the LICEN[CS]E file or part of the License: field to
+a particular license name (a foreign key in license_override).
+
+table: database_versions
+fields: version INTEGER PRIMARY KEY AUTOINCREMENT,
+        version_date INTEGER,
+        base_epoch INTEGER
+
+a version of the database. each time one of the above tables (but not the below
+tables) is updated, a new record is added to this table, indicating significant
+changes to the database. version_date indicates when this change occurred
+(seconds since UNIX epoch) and base_epoch is the Debian version epoch.
+
+in future, all of the above fields should be versioned and somehow linked to
+the packages that used them, so we only rebuild what is necessary.
+
+table: packages
+fields: package TEXT PRIMARY KEY,
+        latest_r_version TEXT
+
+a package, and its latest R version. this is a copy of the 'available'
+structure in the cran2deb R cache, and it is here as it allows queries on the
+'builds' table to be much simpler (and perhaps faster).
+
+table: builds
+fields: id INTEGER PRIMARY KEY AUTOINCREMENT,
+        package TEXT,
+        r_version TEXT,
+        deb_epoch INTEGER,
+        deb_revision INTEGER,
+        db_version INTEGER,
+        date_stamp TEXT,
+        git_revision TEXT,
+        success INTEGER,
+        log TEXT,
+        UNIQUE(package,r_version,deb_epoch,deb_revision,db_version)
+
+Each time a 'package' is built, its 'success' is logged, along with the
+particular database, cran2deb, R and Debian version information (db_version,
+git_revision, r_version, deb_epoch, deb_revision) and the current date
+(date_stamp). 'log' contains the output of the build process.
+
+A new 'deb_revision' is assigned to each successful build.
+
diff --git a/trunk/inst/doc/DEPENDS b/trunk/inst/doc/DEPENDS
new file mode 100644 (file)
index 0000000..471f240
--- /dev/null
@@ -0,0 +1,33 @@
+A dependency alias (created in populated_depend_aliases) is some name (such as
+java) and some associated run and build time dependencies, specified like this:
+
+    alias_build java openjdk-6-jdk
+    alias_build java libgcj9-dev
+    alias_run java openjdk-6-jre
+
+So when cran2deb needs to use the 'java' build dependency, it will add
+"openjdk-6-jdk, libgcj9-dev" to the Build-Depends:. alias_run deals with
+Depends: only.
+Since in Debian you cannot Build-Depend: upon build-essential, there is a
+special 'ignore' dependency alias (this can be handy for dropping unnecessary
+system requirements)
+
+    alias_build ignore build-essential
+
+populate_forcedep contains like:
+
+    force java rJava
+
+which forces the R package rJava to use the dependency alias 'java'. This is
+for cases where there is no SystemRequirement.
+
+Finally, populate_sysreq has lines like:
+
+   sysreq quantlib quantlib%
+
+This says, whenever a part of a SystemRequirement matches the SQL LIKE pattern
+'quantlib%', use the dependency alias. SystemRequirements are converted to
+lower case and messed around with; details are in R/debcontrol.R in the
+sysreqs_as_debian function. R/debcontrol.R contains pretty much all of the code
+for dependencies (the database interface code is in R/db.R).
+
diff --git a/trunk/inst/doc/INSTALL_NOTES b/trunk/inst/doc/INSTALL_NOTES
new file mode 100644 (file)
index 0000000..4d47890
--- /dev/null
@@ -0,0 +1,56 @@
+git clone git://github.com/blundellc/cran2deb.git
+
+apt-get system requirements from DESCRIPTION
+apt-get install cdbs
+
+# install a web server
+apt-get install thttpd
+
+# add a group for cran2deb people
+addgroup cran2deb
+usermod -a -G cran2deb cb
+usermod -a -G cran2deb edd
+
+# set up web space
+mkdir /var/www/cran2deb
+chgrp cran2deb /var/www/cran2deb
+chmod 3775 /var/www/cran2deb
+
+# install prereq R packages
+r -e "install.packages(c('ctv','RSQLite','DBI','digest'))"
+R CMD INSTALL cran2deb
+
+# set up cran2deb space, as per README
+cp /usr/local/lib/R/site-library/cran2deb/exec/cran2deb  /usr/local/bin
+root=$(cran2deb root)
+mkdir /etc/cran2deb
+chgrp cran2deb /etc/cran2deb
+chmod 3775 /etc/cran2deb
+copy ROOT/etc/* to /etc/cran2deb
+ln -s /var/www/cran2deb/ /etc/cran2deb/archive
+edit /etc/cran2deb/pbuilder.in:
+OTHERMIRROR='deb http://localhost/users/cb/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/users/cb/cran2deb/ unstable/all/'
+MIRRORSITE='http://ftp.debian.org/debian/'
+to
+OTHERMIRROR='deb http://localhost/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/cran2deb/ unstable/all/'
+MIRRORSITE='http://ftp.at.debian.org/debian/'
+
+# fix permissions for group usage.
+mkdir /var/cache/cran2deb
+chgrp cran2deb /var/cache/cran2deb
+chmod 3775 /var/cache/cran2deb
+chgrp -R cran2deb $root
+chmod 3775 $root
+chmod -R g+w $root
+
+(log out then log in to get gid cran2deb)
+
+# build pbuilder archive, initialise database
+cran2deb update
+
+# check it works
+cran2deb build zoo
+
+# is handy
+apt-get install sqlite3
+
diff --git a/trunk/inst/doc/PKG b/trunk/inst/doc/PKG
new file mode 100644 (file)
index 0000000..de0a4b2
--- /dev/null
@@ -0,0 +1,23 @@
+One of the key data structures using by cran2deb is commonly called 'pkg'.
+It is constructed in R/getrpkg.R by prepare_pkg. prepare_pkg obtains
+an R package and converts the source package into something suitable for use
+with Debian.
+
+If a particular upstream version has already been used to create a Debian
+package, then the source tarball of that upstream version is expected to be
+available locally, and is used for building. In this case no conversion is
+performed, so the archive does not change. In future it may be desirable to
+obtain the source tarball from some central archive but this is not done at the
+moment.
+
+download_pkg in R/getrpkg.R obtains the tarball (archive) of the R package, either
+from the previous Debian build, or from the R archive. The field pkg$need_repack
+indicates if the obtained archive must be repacked into a form acceptable
+as a Debian source archive. This repacking, if necessary, is performed by
+repack_pkg in R/getrpkg.R
+
+
+Most of the creation of pkg is done by R/getrpkg.R. However some more build
+specific operations (such as determining the new build version pkg$debversion)
+are performed by R/debianpkg.R.
+
diff --git a/trunk/inst/doc/README b/trunk/inst/doc/README
new file mode 100644 (file)
index 0000000..b521da0
--- /dev/null
@@ -0,0 +1,34 @@
+To install:
+
+$ cd ..
+$ R CMD INSTALL cran2deb
+
+copy cran2deb/exec/cran2deb into somewhere in your executable path (e.g.,
+/usr/local/bin, $home/bin)
+
+
+
+To configure:
+
+1. You need a web server serving from say, /var/www/cran2deb/
+
+Let ROOT be the value returned by running: cran2deb root
+
+2. create /etc/cran2deb
+   a. copy ROOT/etc/* into /etc/cran2deb
+   b. /etc/cran2deb/archive should be a symlink pointing to /var/www/cran2deb/
+
+    $ ln -s /var/www/cran2deb/ /etc/cran2deb/archive
+
+   c. modify OTHERMIRROR of /etc/cran2deb/pbuilderrc.in to point to your webserver
+
+3. cran2deb needs a persistent cache outside of R's control. therefore, create
+    /var/cache/cran2deb, writable by whichever user(s) will run cran2deb.
+4. run: cran2deb update
+5. Try building a simple package: cran2deb build zoo
+   (The result will be in /var/cache/cran2deb/results)
+
+
+$ cran2deb help
+will display a short summary of help for each cran2deb command.
+
diff --git a/trunk/inst/etc/dput.cf.in b/trunk/inst/etc/dput.cf.in
new file mode 100644 (file)
index 0000000..8ae0ca6
--- /dev/null
@@ -0,0 +1,8 @@
+[local]
+method = local
+incoming = /etc/cran2deb/archive/mini-dinstall/incoming
+allow_non-us_software = 1
+run_dinstall = 0
+run_lintian = 1
+post_upload_command = /usr/bin/mini-dinstall --batch -c /etc/cran2deb/mini-dinstall.conf
+allow_unsigned_uploads = 1
diff --git a/trunk/inst/etc/hook/A80rjava b/trunk/inst/etc/hook/A80rjava
new file mode 100755 (executable)
index 0000000..1d37c8b
--- /dev/null
@@ -0,0 +1,4 @@
+if [ -n "$(which java)" ]
+then
+    R CMD javareconf
+fi
diff --git a/trunk/inst/etc/hook/B90lintian b/trunk/inst/etc/hook/B90lintian
new file mode 100755 (executable)
index 0000000..57fcfc4
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+# example file to be used with --hookdir
+#
+# run lintian on generated deb files
+apt-get install -y --force-yes lintian
+lintian /tmp/buildd/*.deb
diff --git a/trunk/inst/etc/hook/B91dpkg-i b/trunk/inst/etc/hook/B91dpkg-i
new file mode 100755 (executable)
index 0000000..ee031bb
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+# example file to be used with --hookdir
+#
+# try to install the resulting debs.
+
+echo "Trying to install resulting packages and test upgrades"
+set -ex
+
+
+PKGNAMES=$(cd /tmp/buildd && ls -1 *.deb | sed 's/_.*$//' )
+
+# install-remove check
+dpkg -i /tmp/buildd/*.deb
+dpkg --remove $PKGNAMES
+
+# install-purge check
+dpkg -i /tmp/buildd/*.deb
+dpkg --purge $PKGNAMES
+
+# upgrade-remove check
+apt-get install -y --force-yes  $PKGNAMES || true
+dpkg -i /tmp/buildd/*.deb
+dpkg --remove $PKGNAMES
+
+# upgrade-purge check
+apt-get install -y --force-yes $PKGNAMES || true
+dpkg -i /tmp/buildd/*.deb
+dpkg --purge $PKGNAMES
diff --git a/trunk/inst/etc/hook/B92test-pkg b/trunk/inst/etc/hook/B92test-pkg
new file mode 100755 (executable)
index 0000000..7372ca0
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/bash
+# example file to be used with --hookdir
+#
+# run tests. Current directory is top of source-code.
+#
+# 2005, 2007 Junichi Uekawa
+# 
+set -e 
+
+echo "Installing the prerequisites"
+for PKG in $(ls /tmp/buildd/*.deb | sed -e's,.*/,,;s,_.*,,' ); do
+    apt-get install -y --force-yes "$PKG" || true 
+    apt-get remove -y "$PKG" || true 
+done
+# ignore the failures since they are not the prime interest
+
+dpkg -i /tmp/buildd/*.deb
+
+if chmod a+x /tmp/buildd/*/debian/pbuilder-test/*; then
+    :
+else
+    echo "W: no pbuilder-test script found, skipping"
+    exit 0
+fi
+
+SUCCESS=0
+COUNT=0
+unset FAIL || true
+NOFAIL=1
+
+# The current directory is the top of the source-tree.
+cd /tmp/buildd/*/debian/..
+
+for SCRIPT in $(run-parts --test /tmp/buildd/*/debian/pbuilder-test) ; do
+    echo "--- BEGIN test: ${SCRIPT##*/}"
+    if "${SCRIPT}"; then
+       echo SUCCESS
+       ((SUCCESS=SUCCESS+1))
+    else
+       echo FAIL
+       FAIL[${#FAIL[@]}]="${SCRIPT##*/}"
+       NOFAIL=0
+    fi
+    echo "--- END test: ${SCRIPT##*/}"
+    ((COUNT=COUNT+1))
+done
+
+echo "Summary:"
+echo "=== $SUCCESS out of $COUNT tests passed"
+echo "${FAIL[@]/#/ failed }"
+echo "-- end of testsuite."
+
diff --git a/trunk/inst/etc/hook/D70aptupdate b/trunk/inst/etc/hook/D70aptupdate
new file mode 100755 (executable)
index 0000000..4d42b3d
--- /dev/null
@@ -0,0 +1 @@
+/usr/bin/apt-get update
diff --git a/trunk/inst/etc/mini-dinstall.conf.in b/trunk/inst/etc/mini-dinstall.conf.in
new file mode 100644 (file)
index 0000000..56cd938
--- /dev/null
@@ -0,0 +1,12 @@
+[DEFAULT]
+architectures = all, i386, amd64
+use_dnotify = 0
+verify_sigs = 0
+mail_on_success = 0
+archive_style = simple-subdir
+mail_log_level = NONE
+archivedir = /etc/cran2deb/archive
+logfile = @ROOT@/mini-dinstall.log
+
+[unstable]
+
diff --git a/trunk/inst/etc/pbuilderrc.in b/trunk/inst/etc/pbuilderrc.in
new file mode 100644 (file)
index 0000000..076ee17
--- /dev/null
@@ -0,0 +1,12 @@
+BASETGZ=/var/cache/pbuilder/base-cran2deb.tgz
+HOOKDIR=/etc/cran2deb/hook
+BUILDRESULT=/var/cache/cran2deb/results
+EXTRAPACKAGES='debhelper r-base-dev cdbs r-base-core lintian xvfb xauth xfonts-base'
+REMOVEPACKAGES='lilo libldap-2.4-2 libopencdk10 libsasl2-2'
+# don't actually need aptitude, but pbuilder insists...
+#REMOVEPACKAGES+='aptitude libcwidget3 libept0 libncursesw5 libsigc++-2.0-0c2a libxapian15'
+DISTRIBUTION=unstable
+OTHERMIRROR='deb http://localhost/users/cb/cran2deb/ unstable/$(ARCH)/ | deb http://localhost/users/cb/cran2deb/ unstable/all/'
+MIRRORSITE='http://ftp.debian.org/debian/'
+APTCACHE=''
+PBUILDERSATISFYDEPENDSCMD='/usr/lib/pbuilder/pbuilder-satisfydepends-classic'