summaryrefslogtreecommitdiff
path: root/eclass/darcs.eclass
blob: 1fc1b28b0521bab0ba6f0a1225d602836f0aee8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

# @ECLASS: darcs.eclass
# @MAINTAINER:
# "Gentoo's Haskell Language team" <haskell@gentoo.org>
# Sergei Trofimovich <slyfox@gentoo.org>
# @AUTHOR:
# Original Author: Jeffrey Yasskin <jyasskin@mail.utexas.edu>
#               <rphillips@gentoo.org> (tla eclass author)
# Andres Loeh   <kosmikus@gentoo.org> (darcs.eclass author)
# Alexander Vershilov <alexander.vershilov@gmail.com> (various contributions)
# @BLURB: This eclass provides functions for fetch and unpack darcs repositories
# @DESCRIPTION:
# This eclass provides the generic darcs fetching functions.
#
# Define the EDARCS_REPOSITORY variable at least.
# The ${S} variable is set to ${WORKDIR}/${P}.

# TODO:

# support for tags

inherit eutils # eshopts_{push,pop}

# Don't download anything other than the darcs repository
SRC_URI=""

# You shouldn't change these settings yourself! The ebuild/eclass inheriting
# this eclass will take care of that.

# --- begin ebuild-configurable settings

# darcs command to run
# @ECLASS-VARIABLE: EDARCS_DARCS_CMD
# @DESCRIPTION:
# Path to darcs binary.
: ${EDARCS_DARCS_CMD:=darcs}

# darcs commands with command-specific options

# @ECLASS-VARIABLE: EDARCS_GET_CMD
# @DESCRIPTION:
# First fetch darcs command.
: ${EDARCS_GET_CMD:=get --lazy}

# @ECLASS-VARIABLE: EDARCS_UPDATE_CMD
# @DESCRIPTION:
# Repo update darcs command.
: ${EDARCS_UPDATE_CMD:=pull}

# @ECLASS-VARIABLE: EDARCS_OPTIONS
# @DESCRIPTION:
# Options to pass to both the "get" and "update" commands
: ${EDARCS_OPTIONS:=--set-scripts-executable}

# @ECLASS-VARIABLE: EDARCS_TOP_DIR
# @DESCRIPTION:
# Where the darcs repositories are stored/accessed
: ${EDARCS_TOP_DIR:=${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/darcs-src}

# @ECLASS-VARIABLE: EDARCS_REPOSITORY
# @DESCRIPTION:
# The URI to the repository.
: ${EDARCS_REPOSITORY:=}

# @ECLASS-VARIABLE: EDARCS_OFFLINE
# @DESCRIPTION:
# Set this variable to a non-empty value to disable the automatic updating of
# a darcs repository. This is intended to be set outside the darcs source
# tree by users. Defaults to EVCS_OFFLINE value.
: ${EDARCS_OFFLINE:=${EVCS_OFFLINE}}

# @ECLASS-VARIABLE: EDARCS_CLEAN
# @DESCRIPTION:
# Set this to something to get a clean copy when updating
# (removes the working directory, then uses EDARCS_GET_CMD to
# re-download it.)
: ${EDARCS_CLEAN:=}

# --- end ebuild-configurable settings ---

DEPEND="dev-vcs/darcs
	net-misc/rsync"

# @FUNCTION: darcs_patchcount
# @DESCRIPTION:
# Internal function to determine amount of patches in repository.
darcs_patchcount() {
	set -- $(HOME="${EDARCS_TOP_DIR}" ${EDARCS_DARCS_CMD} show repo --repodir="${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}" | grep "Num Patches")
	# handle string like: "    Num Patches: 3860"
	echo ${3}
}

# @FUNCTION: darcs_fetch
# @DESCRIPTION:
# Internal function is called from darcs_src_unpack
darcs_fetch() {
	# The local directory to store the repository (useful to ensure a
	# unique local name); relative to EDARCS_TOP_DIR
	[[ -z ${EDARCS_LOCALREPO} ]] && [[ -n ${EDARCS_REPOSITORY} ]] \
		&& EDARCS_LOCALREPO=${EDARCS_REPOSITORY%/} \
		&& EDARCS_LOCALREPO=${EDARCS_LOCALREPO##*/}

	debug-print-function ${FUNCNAME} $*

	if [[ -n ${EDARCS_CLEAN} ]]; then
		addwrite "${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}"
		rm -rf "${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}"
	fi

	# create the top dir if needed
	if [[ ! -d ${EDARCS_TOP_DIR} ]]; then
		# note that the addwrite statements in this block are only there to allow creating EDARCS_TOP_DIR;
		# we've already allowed writing inside it
		# this is because it's simpler than trying to find out the parent path of the directory, which
		# would need to be the real path and not a symlink for things to work (so we can't just remove
		# the last path element in the string)
		debug-print "${FUNCNAME}: checkout mode. creating darcs directory"
		addwrite /foobar
		addwrite /
		mkdir -p "${EDARCS_TOP_DIR}"
		export SANDBOX_WRITE="${SANDBOX_WRITE//:\/foobar:\/}"
	fi

	# in case EDARCS_DARCS_DIR is a symlink to a dir, get the real
	# dir's path, otherwise addwrite() doesn't work.
	pushd .
	cd -P "${EDARCS_TOP_DIR}" > /dev/null
	EDARCS_TOP_DIR="`/bin/pwd`"

	# disable the sandbox for this dir
	addwrite "${EDARCS_TOP_DIR}"

	# determine checkout or update mode and change to the right directory.
	if [[ ! -d "${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}/_darcs" ]]; then
		mode=get
		cd "${EDARCS_TOP_DIR}"
	else
		mode=update
		cd "${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}"
	fi

	# commands to run
	local    cmdget="${EDARCS_DARCS_CMD} ${EDARCS_GET_CMD}          ${EDARCS_OPTIONS} --repo-name=${EDARCS_LOCALREPO} ${EDARCS_REPOSITORY}"
	local cmdupdate="${EDARCS_DARCS_CMD} ${EDARCS_UPDATE_CMD} --all ${EDARCS_OPTIONS}                                 ${EDARCS_REPOSITORY}"

	if [[ ${mode} == "get" ]]; then
		einfo "Running ${cmdget}"
		HOME="${EDARCS_TOP_DIR}" ${cmdget} || die "darcs get command failed"
	elif [[ -n ${EDARCS_OFFLINE} ]] ; then
		einfo "Offline update"
	elif [[ ${mode} == "update" ]]; then
		einfo "Running ${cmdupdate}"
		HOME="${EDARCS_TOP_DIR}" ${cmdupdate} || die "darcs update command failed"
	fi

	export EDARCS_PATCHCOUNT=$(darcs_patchcount)
	einfo "    patches in repo: ${EDARCS_PATCHCOUNT}"

	popd
}

# @FUNCTION: darcs_src_unpack
# @DESCRIPTION:
# src_upack function
darcs_src_unpack() {
	# The local directory to store the repository (useful to ensure a
	# unique local name); relative to EDARCS_TOP_DIR
	[[ -z ${EDARCS_LOCALREPO} ]] && [[ -n ${EDARCS_REPOSITORY} ]] \
		&& EDARCS_LOCALREPO=${EDARCS_REPOSITORY%/} \
		&& EDARCS_LOCALREPO=${EDARCS_LOCALREPO##*/}

	debug-print-function ${FUNCNAME} $*

	debug-print "${FUNCNAME}: init:
	EDARCS_DARCS_CMD=${EDARCS_DARCS_CMD}
	EDARCS_GET_CMD=${EDARCS_GET_CMD}
	EDARCS_UPDATE_CMD=${EDARCS_UPDATE_CMD}
	EDARCS_OPTIONS=${EDARCS_OPTIONS}
	EDARCS_TOP_DIR=${EDARCS_TOP_DIR}
	EDARCS_REPOSITORY=${EDARCS_REPOSITORY}
	EDARCS_LOCALREPO=${EDARCS_LOCALREPO}
	EDARCS_CLEAN=${EDARCS_CLEAN}"

	einfo "Fetching darcs repository ${EDARCS_REPOSITORY} into ${EDARCS_TOP_DIR}..."
	darcs_fetch

	einfo "Copying ${EDARCS_LOCALREPO} from ${EDARCS_TOP_DIR}..."
	debug-print "Copying ${EDARCS_LOCALREPO} from ${EDARCS_TOP_DIR}..."

	# probably redundant, but best to make sure
	# Use ${WORKDIR}/${P} rather than ${S} so user can point ${S} to something inside.
	mkdir -p "${WORKDIR}/${P}"

	eshopts_push -s dotglob	# get any dotfiles too.
	rsync -rlpgo "${EDARCS_TOP_DIR}/${EDARCS_LOCALREPO}"/* "${WORKDIR}/${P}"
	eshopts_pop

	einfo "Darcs repository contents are now in ${WORKDIR}/${P}"

}

EXPORT_FUNCTIONS src_unpack