= repoman(1)

== NAME

repoman - Frugalware's program to build and maintain packages

== SYNOPSIS

repoman [global options] [command] [command options]

== DESCRIPTION

repoman is a tool for users to automatically build and install packages on the
target host. This can be handy when there is no binary package available due to
license problems for a given software (like Opera or Skype).

It's also a tool for Frugalware developers to upload, delete or register source
tarballs or fpm packages.

== INSTALLING PACKAGES

NOTE: This section is for users. If you're a developer, just skip it.

Here is a reference comparing pacman-g2 and repoman:

|====
| pacman-g2 -Sy     | repoman upd
| pacman-g2 -S pkg  | repoman merge pkg
| pacman-g2 -Si pkg | repoman info pkg
| pacman-g2 -Ss foo | repoman search foo
|====

There is a possibility to alter the result of the merge without editing the
buildscript for some packages. To build the development version of a package,
type:

----
# USE_DEVEL=y repoman merge pkg
----

== MAINTAINING PACKAGES

NOTE: This section is for developers. If you're a user, just skip it.

A typical package update should be done as follows:

=== Configuring repoman

----
$ echo 'current_servers=("<nick>@git.frugalware.org:/pub/frugalware/frugalware-current")' \
	> ~/.repoman.conf
$ echo 'fst_root=~/git' >> ~/.repoman.conf
----

Replace <nick> with your nick and make sure that you have the git tree in
\~/git/current.

If you want to use more than one (conflicting, ie.: current and stable) trees,
then please add the <reponame>_pushonly=y option to each repo except one.
Example: if the host system is -current and you want to enable current and
stable, then add stable_pushonly="y" to your config.

=== Getting the repo

Example for the first time:

----
$ cd ~/git
$ git clone <nick>@git.frugalware.org:/pub/frugalware/frugalware-current current
----

Getting other git repos is similar. For example, to get the pacman-tools repo, type:

----
$ git clone <nick>@git.frugalware.org:/pub/other/pacman-tools/pacman-tools
----

Now set some defaults:

----
$ cd current
$ git config user.name "John Smith"
$ git config user.email john@frugalware.org
$ git config remote.origin.receivepack "sudo -u <owner> git-receive-pack"
$ git config branch.master.rebase true
$ git config push.default simple
$ git config core.whitespace trailing-space,space-before-tab,indent-with-non-tab
----

To set your default editor and pager you can do:

----
$ git config core.editor <your_editor>
$ git config core.pager <your_pager>
----
 
Here you should substitute <owner> with the nick of the repo owner, currently
'repo'.

=== Updating the repo

If you already got the repo, a simple 'git pull' should be enough.

=== Making changes and building the package

Now it's time to edit the FrugalBuild and make changes.

Build the package with 'sudo makepkg -c'.

Then if you would like to add new file(s) to the source, run this:

----
$ git add glibc.install
----

To remove file(s) from the source, run this:

----
$ git rm at-3.1.8r11-makefile.patch
----

Or if you would like to rename a file in the source, run this:

----
$ git mv glibc-2.5-foo.patch glibc-2.5-bar.patch
----

=== Committing the changes

Simply run 'git commit -a'.

When recording the patch (if this is a package upgrade), the first line must be
'$pkgname-$pkgver-$pkgrel-$arch'. You can use 'repoman rec' which will fill in
this first line automatically for you.

For example:

glibc-2.5-1-i686

This is the same as the full package name without trailing '.fpm'.

=== Delete the old source package(s)

If you only do a rebuild, then, of course, skip this step. For example:

----
$ repoman del source/base/readline/readline-5.0.tar.g
----

=== Push the FrugalBuild/.install/etc patch

Here you only have to do a simple 'git push'.

This command uploads the changes you made locally, to the server.

=== Upload the new source package(s)

If you only do a rebuild, then, of course, skip this step.

For example:

----
$ repoman up zsh-4.2.5.tar.bz2 /source/apps/zsh/
$ repoman up zsh-doc-4.2.5.tar.bz2 /source/apps/zsh/
----

NOTE: If the original mirror is fast, then just skip this step and 'repoman cl'
(see later) will download the sources for you. If the mirror is slower than
your upload bandwidth then it worth to upload it now or you'll have to wait
till the server downloads it!

=== Upload the new fpm package

For example (see the 'up' command description for more details!):

----
$ repoman up sendmail-8.13.4-2-i686.fpm frugalware-i686/
----

=== Delete the old fpm package

For example:

----
$ repoman del frugalware-i686/glibc-2.5-1-i686.fpm
----

=== Generate a Changelog

You can do this along with updating the '.fdb' and SQL database, downloading
the missing sources and updating the documentation:

For example:

----
$ repoman cl perl
----

=== All in one

Once you understand this procedure, you can do all this at once:

----
$ repoman -k push
----

Will be interactive only in case there is some unrecorded change.

It's recommended to do the following:

----
$ repoman rec
$ repoman -k push
----

WARNING: You should not use 'repoman push' unless you understand what it
does!

Also, if you built a package locally, tested it, but you do not want to
upload it (lack of bandwidth, avoid some oddity in your local build
environment, etc.), you can do a simple:

----
$ git push
----

and buildservers will build the binary package for you.

IMPORTANT: Never use the above command to publish packages you did not
test locally!

== Removing packages

Removing a package means that you want to remove the buildscript and
other tracked files, the mirrored upstream source, you want to delete
the package database (fdb) entry for the package and you also want to
remove it from the sql website database.

In this example, we'll remove the synaptics package:

----
$ cd ~/git/current/source/x11-extra/synaptics
$ repoman ci <1>
$ cd ..
$ rm -rf synaptics
$ use commit command generated by repoman ci
$ dg push -a <2>
$ repoman clean x11-extra/synaptics <3>
----
<1> This will generate a nice patch name and give you the git commit command.
<2> This removes the buildscript and other tracked files
<3> This removes everything else

== Moving packages between categories

If a package has `groups=('foo' 'bar')`, then it's located under
`/source/foo/pkgname`. Now if you change the first item of the groups
array, you have to move the package. Here are the steps to do so:

----
$ cd ~/git/current/source
$ git mv network/netkit-rsh network-extra
$ cd network-extra/netkit-rsh
$ vi FrugalBuild <1>
$ repoman ci <2>
$ use commit command generated by repoman ci
$ dg push -a <3>
----
<1> Edit the FrugalBuild: increment the pkgrel value by one
<2> This will generate a nice patch name and give you the git commit command.
<3> This will move the tracked files and then the git hook will move the untracked files as well

NOTE: Incrementing the pkgrel value is not a must, for huge packages it
may be easier to just do a `repoman cl` for each arch, but that's a bit
ugly, better to just let `syncpkgd` to rebuild the package.

== Reverting package changes

Let's see an example: mc-4.7.5.3-1 was upgraded to 4.7.5.4-1, but later
it turned it was a bad idea. Here are the steps to revert that change:

----
$ cd ~/git/current/source/apps/mc
$ git revert $commit <1>
$ vi FrugalBuild <2>
$ git commit --amend FrugalBuild <3>
----
<1> $commit is the sha1 hash of the problematic commit, introducing the upgrade
<2> Increment pkgrel (from 1 to 2 in this case) and add `options=('force')`
<3> This will make your changes to FrugalBuild be part of the revert commit

Once this is done, do the usual 'build', 'test' and 'push' tasks, and
you're done.

== WIP REPOS

=== Introduction

WIP stands for "Work In Progress". Such repos are used usually only for a few
days or weeks, if you except that a package upgrade will break several others,
then it's good to create a WIP repo, and merge when you fixed all the revdeps.

In general, if you expect that the breakage you introduce takes more
than a workday to fix, please use a WIP repo. If you do so, nobody will
urge you to finish your work quickly -- and it's free, so if you are
unsure, use this feature.

=== Before you begin

If the repo you use for your work already exists, it may need some work:

* Remove the already merged fpms manually. This usually means all fpms.

* Remove the obsolete entries from the fdb, or just remove the file if no fpms
  are left in the repo.

=== The How

Choose a name. It should not have to be too meaningful, using anything other
than a-z 0-9 and underscore may or may not work. For "flac 1.1.3" I have used
flac113.

First, clone current to your personal directory on the server:

----
$ cd /pub/other/people/nick
$ git clone /pub/frugalware/frugalware-current flac113
----

You _need_ hooks. See here for more info: $$ http://frugalware.org/docs/repos#_enabling_hooks_for_your_repository $$

If you need syncpkgd support, read this as well: $$ http://frugalware.org/docs/repos#_enabling_syncpkgd_support_for_a_wip_repo $$

Okay now you can git clone your repo to localhost:

----
$ git clone nick@git.frugalware.org:/pub/other/people/nick/flac113
----

Now you have to configure repoman and pacman-g2.

Just append your '\~/.repoman.conf':

----
repos=(${repos[@]} 'flac113')
flac113_servers=("nick@git.frugalware.org:/pub/other/people/nick/flac113")
----

If the repo is owned by an other developer, then you have to add a
line to indicate that:

----
flac113_sudo="<nick of the other developer>"
----

On the server, set up your '\~/.repoman.conf' like this:

----
fst_root=~/git
repos=('current' 'flac113')
current_servers=("nick@git.frugalware.org:/pub/frugalware/frugalware-current")
flac113_servers=("nick@git.frugalware.org:/pub/other/people/nick/flac113")
----

Finally symlink `/pub/frugalware/frugalware-current` to `\~/git/current`,
`/pub/other/people/nick/flac113` to `\~/git/flac113`.

Switch back to the client, and create a file named `~/.pacman-g2/repos/flac113`:

----
[flac113]
Server = http://ftp.frugalware.org/pub/other/people/nick/flac113/frugalware-$arch/
----

Building a package will be a bit more complicated than 'sudo makepkg -c', so
let's create an alias:

----
alias flacbuild='sudo makepkg -t flac113,current -c'
----

Then you can build with:

----
$ flacbuild
----

You can record using the usual:

----
$ repoman rec
----

and push with:

----
$ repoman -t flac113 -k push
----

=== Merge

Once you are ready, go to '\~/git/current'. Push your local commits if
you have ones. If you don't have any, just pull, so that you can be sure
you will be able to push the result of the merge. Perform the merge
using:

----
$ git pull --no-rebase --no-ff nick@git.frugalware.org:/pub/other/people/nick/flac113 master
----

This will merge your WIP repo to your local current repo. If there are
conflicts, resolve them.

NOTE: If you get a nontrivial conflict (e.g. you changed pkgrel from 1 to 2 in
flac113 and that happened in current as well, and you resolve it with setting
pkgrel to 3), it's better to merge current to flac113 first, and once you have
the up to date binary packages in the flac113, you can do the real merge.

Push your changes and transfer the fpms from your repo and run a repoman cl for
each package:

----
$ repoman fpmmerge flac113
----

=== Reuse

After merge, you may want to reuse your WIP repo. To do so, you need to:

- remove existing fpms/fdbs (`rm -f frugalware-*/*`)
- clean the repo by doing : (`git clean -x -d -f`)
- update the repo on the server (`ssh git.frugalware.org; cd /pub/other/people/nick/flac113; git pull -r`)

== GLOBAL OPTIONS

-d|--dry-run::
	Don't do anything, just print what would happen.

-f|--force::
	Enable 'I know what I am doing' mode. Currently it lets 'repoman
	merge' not to check if essential packages (like a C compiler) are
	installed.

-h|--help::
	This manpage.

-k::
	Don't be interactive.

-t|--tree::
	Specify a tree to work with, if the default is not sufficient.

	Example: 'current' or 'stable'.

-v|--verbose::
	More output.

--version::
	Just repoman's version and exit.

== COMMANDS

c|clean [--nofdb] [--exclusivearch <arch>] <package>::

	Removes the package from the package database. The optional `--nofdb`
	parameter means that only the source directory will be removed, but the
	fdb database will be left untouched. The other optional `--exclusivearch` parameter means that only the fdb of the given arch

cl|changelog [<group>/]<package>::

	Registers a package in the package database. If the group is omitted
	then the first group from the current directory's FrugalBuild will be used (it
	is correct in most cases). If you specify a group, too then you can run this
	command in any directory.

del|delete <path>::

	Removes a file from the FST which is not under source control (use
	'git rm' to remove those).

fpmmerge <repo>::

	Merges fpms from an other repo to the current one.

info <pkg>::

	Display dependency information for a given package. This will
	search through all repositories for a matching package and display the
	dependencies, conflicts, etc.

ls|list <path> [<options>]::

	Lists a given directory of the FST. It can be handy to determine which
	old files you need to remove.

	Example: 'repoman ls source/base/db/ -l'

m|merge <package>::

	To be used by users. Build a package from source and install it. You
	can configure the build options in the 'makepkg_opts' directive of
	'/etc/repoman.conf'.

	By default 'repoman' will install the missing dependencies with
	'pacman-g2', clean up the leftover work files, install the package, and
	write the resulting package to the 'pacman-g2' package cache.

push::

	All-in-one command to transfer your fpm package and changes to its
	buildscript to the server.

rec|record [commit message]::

	A frontend to 'git commit'. If parameters are given then it won't be
	interactive and the parameters are appended to the history as a long comment.

s|search [regexp]::

	To be used by users. Search in those FrugalBuilds which are only available in
	source form. If the optional regexp parameter is omitted, it will list all
	source-only packages.

sync::

	Same as 'repoman push', but it will never update the buildscripts on
	the server. Used by 'syncpkgd'.

up|upload <local file> <path in FST>::

	Adds a file to the FST which is not under source control (use 'git add'
	to add those).

upd|update::

	To be used by users. Update the repositories listed in '/etc/repoman.conf'. If a
	repository does not exist yet, then 'repoman' will download it (it may take
	some time!).  If you want to blacklist a repository then add
	'<reponame>_pushonly="y"' to '/etc/repoman.d/<reponame>'.

upgrade::

	To be used by users. Merge the newer version of all installed
	nobuild packages. The 'upgrade_ignore' variable in repoman.conf
	can contain packages to be ignored during the upgrade.

== ENVIRONMENT

'repoman' utilizes the following environment variable:

'arch': Operate on packages different to 'uname -m'.

Example:

----
$ arch=x86_64 repoman cl foo
----

will update the entry of the 'foo-version-x86_64.fpm' in the x86_64 'fdb' as if
it would be invoked in an x86_64 machine.

== AUTHORS

Written by Miklos Vajna and Laszlo Dvornik.

== REPORTING BUGS

Please report bugs to the <http://bugs.frugalware.org/> bug tracking system.

== SEE ALSO

*git*(7), *pacman-g2*(8)
