summaryrefslogtreecommitdiffstats
path: root/nix-script-update-package-def.sh
blob: 7b764325d786185d21a78c2b30fcc02cb0df1e03 (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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env bash

#
#
# Updates a package definition by downloading the patch from monitor.nixos.org,
# creating a branch in the nixpkgs repo for it, applying the patch and
# test-building the package if you want to.
#
#

source $(dirname ${BASH_SOURCE[0]})/nix-utils.sh

usage() {
    cat <<EOS
    $(help_synopsis "${BASH_SOURCE[0]}" "[-y] [-b] [-c] [-g <nixpkgs path>] [-j <n>] [-C <n>] [-p <yes|no>] -u <url>")

        -y          Don't ask before executing things (optional) (not implemented yet)
        -b          Also test-build the package (optional)
        -u <url>    Download and apply this url
        -g <path>   Path of nixpkgs clone (Default: '$RC_NIXPKGS')
        -c          Don't check out another branch for update
        -d          Don't checkout base branch after successfull run.
        -j <n>      Pass "-j <n>" to nix-build
        -C <n>      Pass "--cores <n>" to nix-build
        -p <yes|no> Do a git-push after successful run. (remote specified in config file)
        -h          Show this help and exit

        Helper for developers of Nix packages.

        With this command you can
            - Download package update diffs
            - Create package update commits on a new branch
            - Test build the updated package
        and everything in one step. All you need is the URL of the
        patch.

        The script asks before building the package, so you can abort if
        the script fails to find the package name.

        You really should base the update branch on the commit your
        current system is based on. This way you don't need to rebuild
        the whole world.

        Example usage:

            # Create in the current directory (which should be a clone
            # of the nixpkgs repo) a new branch for updateing ffmpeg,
            # download the patch and apply it (commit message gets generated
            # for you) and then test build it.
            # Verbosity is on.
            nix-script -v update-package-def -b -u http://monitor.nixos.org/patch?p=ffmpeg-full&v=2.7.1&m=Matthias+Beyer

$(help_rcvars                                                           \
    "RC_UPD_NIX_BUILD_J     - Default number to pass to 'nix-build -j'" \
    "RC_UPD_NIX_BUILD_CORES - Default number to pass to 'nix-build --cores'" \
    "RC_UPD_PUSH            - Set to 1 to enable git-push after applying the patch (and building it)"\
    "RC_UPD_PUSH_REMOTE     - git remote(s) to push to"
)

$(help_end "${BASH_SOURCE[0]}")
EOS
}

YES=0
TESTBUILD=0
NIXPKGS=$RC_NIXPKGS
URL=
CHECKOUT=1
DONT_CHECKOUT_BASE=
J="$RC_UPD_NIX_BUILD_J"
CORES="$RC_UPD_NIX_BUILD_CORES"
DO_PUSH=

while getopts "ybu:g:cdj:C:p:h" OPTION
do
    case $OPTION in
        y)
            YES=1
            dbg "Setting YES"
            ;;

        b)
            TESTBUILD=1
            dbg "Test-building enabled"
            ;;

        u)
            URL="$OPTARG"
            dbg "URL = $URL"
            ;;

        g)
            NIXPKGS="$OPTARG"
            dbg "NIXPKGS = $NIXPKGS"
            ;;

        c)
            CHECKOUT=0
            stdout "CHECKOUT = $CHECKOUT"
            ;;

        d)
            DONT_CHECKOUT_BASE=1
            stdout "DONT_CHECKOUT_BASE = $DONT_CHECKOUT_BASE"
            ;;

        j)
            J="$OPTARG"
            stderr "J = $J"
            ;;

        C)
            CORES="$OPTARG"
            stderr "CORES = $CORES"
            ;;

        p)
            [[ "$OPTARG" == "yes" ]] && DO_PUSH=1
            [[ "$OPTARG" == "no" ]]  && DO_PUSH=0
            stdout "DO_PUSH = $DO_PUSH"
            ;;

        h)
            usage
            exit 0
            ;;

    esac
done

if [ -z "$URL" ]
then
    stderr "No URL for the patch"
    exit 1
fi

if [ -z "$NIXPKGS" ]
then
    stderr "No nixpkgs passed."
    stderr "Checking whether the current directory is a git repository!"
    stderr "(this could possibly blow up pretty badly)"
    continue_question "Continue execution" || exit 1

    if [[ -d ./.git ]]
    then
        stdout "Git directory found"
        NIXPKGS="."
    else
        stderr "No git directory"
        exit 1
    fi
fi

stdout "Making temp directory"
TMP=$(mktemp)
dbg "TMP = $TMP"

stdout "Fetching patch"
curl $URL > $TMP

stdout "Parsing subject to branch name"
PKG=$(cat $TMP | grep Subject | cut -d: -f 2 | sed -r 's,(\ *)(.*)(\ *),\2,')

#translate subject line if necessary
if [[ $(cat $TMP | grep "update from") ]]
then
    sed -i -r 's;Subject\:\ (.*)\:\ update from (.*) to (.*);Subject: \1\:\ \2 \ -> \3;' $TMP
fi

CURRENT_BRANCH=$(__git_current_branch "$NIXPKGS")

[[ $CHECKOUT == 1 ]] && __git "$NIXPKGS" checkout -b update-$PKG || true

if [[ $? -ne 0 ]]
then
    stderr "Switching to branch update-$PKG failed."
    exit 1
fi

cat $TMP | __git "$NIXPKGS" am

if [[ $? -eq 0 ]]
then
    stdout "Patch applied."
else
    stderr "Patch apply failed. I'm exiting now"
    __git "$NIXPKGS" am --abort
    exit 1
fi

if [[ $TESTBUILD -eq 1 ]]
then
    __j=""
    [[ ! -z "$J" ]] && __j="-j $J"

    __cores=""
    [[ ! -z "$CORES" ]] && __cores="--cores $CORES"

    ask_execute "Build '$PKG' in nixpkgs clone at '$NIXPKGS'" nix-build -A $PKG -I $NIXPKGS $__j $__cores
fi

#
# If the config says yes and is not overridden
# OR
# If the config is overridden with yes
#
if [[ ($RC_UPD_PUSH -eq 1 && -z "$DO_PUSH") || ! -z "$DO_PUSH" && $DO_PUSH -eq 1 ]]
then
    dbg "RC_UPD_PUSH enabled or overridden"
    dbg "Starting performing git-push"

    if [[ ! -z "$RC_UPD_PUSH_REMOTE" ]]
    then
        __git "$NIXPKGS" push $RC_UPD_PUSH_REMOTE
        stdout "git-push done"
    else
        stderr "Cannot git-push: No remote set in configuration"
        stderr "Aborting git-push."
        continue_question "Continue execution?" || exit 1
    fi

else
    dbg "git-push won't be performed"
fi

#
# If we checked out a new branch, we go back, too.
#
if [[ $CHECKOUT == 1 && -z "$DONT_CHECKOUT_BASE" ]]
then
    stdout "Switching back to old commit which was current before we started."
    stdout "Switching to '$CURRENT_BRANCH'"
    __git "$NIXPKGS" checkout $CURRENT_BRANCH

    if [[ $? -ne 0 ]]
    then
        stderr "Switching back to '$CURRENT_BRANCH' failed. Please check manually"
        exit 1
    fi
fi