Hi ports@,

a few weeks ago i tried to integrate node packages 
into the OpenBSD ports tree but i finaly gave up after a while.
Basically i tried to mimic the behavior of ruby/python/perl 
ports where each NPM package would get its own Makefile Wrapper
in the portstree. 


I remebered that there was a GSOC project which should
solve the integration of module installation frameworks.

"OpenBSD Ports contain many small ports for Ruby gems, 
CPAN modules and so on. Those ports are mostly simple "wrappers" 
that rely on corresponding port modules. There are a few 
problems with this design: 
1) in OpenBSD Ports, it's needed to manually duplicate 
   version requirements from upstream package; 
2) maintaining a full port structure for each small 
   upstream package consumes too much time from maintainers. "


Today i tried another solution  which turns out to be more like
what is described above.

Each NPM package fetches and installs it's dependencies in a
recursive fashion under its root dir. 

SOLUTION:

So the general idea was to:
 1) let npm (node's package manager) fetch, (compile) and 
    install a package with all its dependencies
    and then create a OpenBSD package from it.

    The resulting OpenBSD packages have only one dependency
    which is lang/node. All other deps are contained in
    the package.
    
 2) query npm's registry [0]
    for relevant / updated packages and repackage them.

    (relevant are in my opinion only packages which 
    provide executables. packages which provide only
    libs are generally not installed globaly)

 3) provide a package repository which people can add
    to their PKG_PATH to fetch packages/updates.


I have a simple prototype shell script [1][and below] 
which handles 1) and uploaded some manualy picked 
test packages here [2]. Current packages are:

node-bower-1.3.3.tgz
node-coffee-script-1.7.1.tgz
node-component-0.19.9.tgz
node-docpad-6.64.3.tgz
node-downpress-0.1.21.tgz
node-eslint-0.5.1.tgz
node-github-markdown-0.3.1.tgz
node-grunt-cli-0.1.13.tgz
node-grunt-init-0.3.2.tgz
node-gulp-3.6.2.tgz
node-json-0.0.14.tgz
node-karma-cli-0.0.4.tgz
node-markdown-0.5.0.tgz
node-mocha-1.18.2.tgz
node-typescript-1.0.0.tgz

Add [2] to your PKG_PATH and try "pkg_add node-github-markdown"
if you like. Packages are not signed ;(

New packages can be created by calling "repackager npmpkg"
where npmpkg is a valid npm package name.



Before tackling 2), 3) and improving 1), i would like to 
hear what you are thinking?

Is this total crap and i should move on, or is it worth to invest 
some more time.


Feedback highly appreciated.

Ceers,
Fabian


[0] https://www.npmjs.org/doc/misc/npm-registry.html
[1] https://github.com/Mischi/npmopenbsdrepackager/
[2] http://mischi.selfhost.bz/packages/amd64/

repackager
---------------------
#!/bin/ksh
#
# Copyright (c) 2014 Fabian Raetz <fabian.ra...@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

arch=$(arch -s)
nodever=$(node -v | sed -e "s/v//")

prefix=/usr/local

nodepkg_name=$1
obsdpkg=node-$nodepkg_name

# XXX adjust fakedirbase to your setup
fakedirbase=/home/mischi/code/npm-openbsdports-repackager/fake
fakedir="$fakedirbase/$nodepkg_name/fake-$arch"
fakedirprefix="$fakedir$prefix"

plist=$fakedir/plist
descr=$fakedir/descr

make_fake() {
        mkdir -p $fakedirprefix
        npm install -g $nodepkg_name --prefix $fakedirprefix
        sudo chown -R root:wheel $fakedirprefix
}

make_parsepkg() {
        
nodepkg_conf="$fakedirprefix/lib/node_modules/$nodepkg_name/package.json"
        nodepkg_ver=$(jq -r '.version' $nodepkg_conf)
        nodepkg_homepage=$(jq -r '.homepage' $nodepkg_conf)
        nodepkg_descr=$(jq -r '.description' $nodepkg_conf)
        nodepkg_license=$(jq -r '.licenses[].type' $nodepkg_conf)

        descrlen=$(echo $nodepkg_descr | wc -m)
        if [ $descrlen -ge 60 ]; then
                print "Timming description ..."
                nodepkg_comment=$(echo $nodepkg_descr | cut -c -59)
        else
                nodepkg_comment=$nodepkg_descr
        fi
}

make_plist() {
        print "Creating plist ..."
        for i in $(find $fakedirprefix); do
                if [ $i == $fakedirprefix ]; then
                        continue
                fi

                s=$(echo $i | sed -e "s,$fakedirprefix/,,")

                if [ $s == lib -o $s == bin ]; then
                        continue
                fi

                if [ -f $i -a -x $i ]; then
                        echo "@bin $s" >> $plist
                elif [ -d $i ]; then
                        echo "@dir $s" >> $plist
                else
                        echo "$s" >> $plist
                fi
        done
}

make_descr() {
        # XXX parse $nodepkg_conf readme from markfown to txt and use 
        # that instead of description`
        echo $nodepkg_descr > $descr
}

make_pkg() {
        print "Creating package ..."
        # XXX parse $nodepkg_license and use it for -DFTP / -DCDROM
        pkg_create \
                -A $arch \
                -B $fakedir \
                -f $plist \
                -d $descr \
                -DCOMMENT="$nodepkg_comment" \
                -DHOMEPAGE="$nodepkg_homepage" \
                -DFULLPKGPATH="www/$obsdpkg" \
                -DMAINTAINER="Fabian Raetz <fabian.ra...@gmail.com>" \
                -DCDROM="Yes" \
                -DFTP="Yes" \
                -P "lang/node:node->=0.6.17p2:node-$nodever" \
                -p $prefix \
                $obsdpkg-$nodepkg_ver.tgz
}

make_clean() {
        print "Cleaning up fake ..."
        sudo rm -rf 
/home/mischi/code/npm-openbsdports-repackager/fake/$nodepkg_name
}

make_fake
make_parsepkg
make_plist
make_descr
make_pkg
make_clean
#!/bin/ksh
#
# Copyright (c) 2014 Fabian Raetz <fabian.ra...@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

arch=$(arch -s)
nodever=$(node -v | sed -e "s/v//")

prefix=/usr/local

nodepkg_name=$1
obsdpkg=node-$nodepkg_name

fakedirbase=/home/mischi/code/npm-openbsdports-repackager/fake
fakedir="$fakedirbase/$nodepkg_name/fake-$arch"
fakedirprefix="$fakedir$prefix"

plist=$fakedir/plist
descr=$fakedir/descr

#nodepkg_ver=""
#nodepkg_homepage=""
#nodepkg_descr=""
#nodepkg_comment=""
#nodepkg_license=""

make_fake() {
        mkdir -p $fakedirprefix
        npm install -g $nodepkg_name --prefix $fakedirprefix
        sudo chown -R root:wheel $fakedirprefix
}

make_parsepkg() {
        
nodepkg_conf="$fakedirprefix/lib/node_modules/$nodepkg_name/package.json"
        nodepkg_ver=$(jq -r '.version' $nodepkg_conf)
        nodepkg_homepage=$(jq -r '.homepage' $nodepkg_conf)
        nodepkg_descr=$(jq -r '.description' $nodepkg_conf)
        nodepkg_license=$(jq -r '.licenses[].type' $nodepkg_conf)

        descrlen=$(echo $nodepkg_descr | wc -m)
        if [ $descrlen -ge 60 ]; then
                print "Timming description ..."
                nodepkg_comment=$(echo $nodepkg_descr | cut -c -59)
        else
                nodepkg_comment=$nodepkg_descr
        fi
}

make_plist() {
        print "Creating plist ..."
        for i in $(find $fakedirprefix); do
                if [ $i == $fakedirprefix ]; then
                        continue
                fi

                s=$(echo $i | sed -e "s,$fakedirprefix/,,")

                if [ $s == lib -o $s == bin ]; then
                        continue
                fi

                if [ -f $i -a -x $i ]; then
                        echo "@bin $s" >> $plist
                elif [ -d $i ]; then
                        echo "@dir $s" >> $plist
                else
                        echo "$s" >> $plist
                fi
        done
}

make_descr() {
        # XXX parse $nodepkg_conf readme from markfown to txt and use 
        # that instead of description`
        echo $nodepkg_descr > $descr
}

make_pkg() {
        print "Creating package ..."
        # XXX parse $nodepkg_license and use it for -DFTP / -DCDROM
        pkg_create \
                -A $arch \
                -B $fakedir \
                -f $plist \
                -d $descr \
                -DCOMMENT="$nodepkg_comment" \
                -DHOMEPAGE="$nodepkg_homepage" \
                -DFULLPKGPATH="www/$obsdpkg" \
                -DMAINTAINER="Fabian Raetz <fabian.ra...@gmail.com>" \
                -DCDROM="Yes" \
                -DFTP="Yes" \
                -P "lang/node:node->=0.6.17p2:node-$nodever" \
                -p $prefix \
                $obsdpkg-$nodepkg_ver.tgz
}

make_clean() {
        print "Cleaning up fake ..."
        sudo rm -rf 
/home/mischi/code/npm-openbsdports-repackager/fake/$nodepkg_name
}

make_fake
make_parsepkg
make_plist
make_descr
make_pkg
#make_clean

Reply via email to