Merge branch 'green-to-purple' of https://github.com/jtojnar/nix-update into green-to-purple

This commit is contained in:
Ryan Mulligan 2018-04-03 20:39:46 -07:00
commit e3b149b2c6
7 changed files with 168 additions and 117 deletions

View File

@ -1,20 +0,0 @@
#! /usr/bin/env bash
set -euxo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
GITHUB_TOKEN="$(cat "$SCRIPT_DIR"/github_token.txt)"
export GITHUB_TOKEN
# shellcheck source=setup-nixpkgs.sh
source "$SCRIPT_DIR/setup-nixpkgs.sh"
git fetch --prune origin
git fetch --prune upstream
git checkout master
git reset --hard upstream/master
git branch -ra --merged | grep "origin/auto-update/" | sed -e 's|^ remotes/origin/\(.*\)|git push origin :\1|' | while IFS= read -r line; do eval "$line"; done || true
git branch -a --merged | grep "auto-update/" | sed -e 's|^\(.*\)|git branch -d \1|' | while IFS= read -r line; do eval "$line"; done

View File

@ -1,50 +0,0 @@
#!/usr/bin/env bash
set -euxo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
GITHUB_TOKEN="$(cat "$SCRIPT_DIR"/github_token.txt)"
export GITHUB_TOKEN
# shellcheck source=setup-nixpkgs.sh
source "$SCRIPT_DIR/setup-nixpkgs.sh"
PACKAGE_NAME=$1
OLD_VERSION=$2
NEW_VERSION=$3
DERIVATION_FILE=$4
ATTR_PATH=$5
OLD_SRC_URL=$6
OLD_DERIVATION_NAME=$(nix eval -f ~/p/nixpkgs --raw "pkgs.$ATTR_PATH.name")
NEW_DERIVATION_NAME=$(sed "s|$OLD_VERSION|$NEW_VERSION|" <<< "$OLD_DERIVATION_NAME")
NAME=$(nix eval --raw "(let pkgs = import ./. {}; in (builtins.parseDrvName pkgs.$ATTR_PATH.name).name)")
if grep -q "name = \"$NEW_DERIVATION_NAME\"" "$DERIVATION_FILE"
then
# Separate name and version
sed -i "s|$NEW_DERIVATION_NAME|$NAME-\${version}|" "$DERIVATION_FILE"
grep -q "name = \"$NAME-\${version}\"" "$DERIVATION_FILE"
# shellcheck disable=SC2016
sed -i 's|^\([ ]*\)\(name = "'"$NAME"'-\${version}";\)|\1\2\n\1version = "'"$NEW_VERSION"'";|' "$DERIVATION_FILE"
grep -q "version = \"$NEW_VERSION\";" "$DERIVATION_FILE"
fi
ESCAPED_NEW_VERSION="${NEW_VERSION//\./\\.}"
DOWNLOADS=$(curl "https://repology.org/api/v1/metapackage/$PACKAGE_NAME" | jq '.[].downloads | select(values) | .[] ')
FILTERED_DOWNLOADS=$(echo "$DOWNLOADS" | grep "$ESCAPED_NEW_VERSION" | grep -vE "${ESCAPED_NEW_VERSION}[^/]+\\.tar" | grep -vE "${ESCAPED_NEW_VERSION}[^/]+\\.zip" | sed 's|"||g')
for d in $FILTERED_DOWNLOADS
do
OLD_URL="$OLD_SRC_URL"
OLD_URL=$(sed "s|$OLD_DERIVATION_NAME|\${name}|g" <<< "$OLD_URL")
OLD_URL=$(sed "s|$OLD_VERSION|\${version}|g" <<< "$OLD_URL")
NEW_URL=$(sed "s|$NEW_DERIVATION_NAME|\${name}|g" <<< "$d" | sed "s|$NEW_VERSION|\${version}|g")
sed -i "s|$OLD_URL|$NEW_URL|" "$DERIVATION_FILE"
grep -q 'url = "'"$NEW_URL"'";' "$DERIVATION_FILE" || continue
nix-prefetch-url -A "$ATTR_PATH.src" && exit 0
done
exit 1

View File

@ -15,6 +15,7 @@ dependencies:
- shelly >= 1.6 && < 1.8 - shelly >= 1.6 && < 1.8
- text - text
- filepath - filepath
- optparse-applicative
- regex-applicative - regex-applicative
executables: executables:

53
src/Clean.hs Normal file
View File

@ -0,0 +1,53 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
module Clean (fixSrcUrl) where
import Control.Applicative ((<|>), some)
import Data.Function ((&))
import qualified Data.Text as T
import Control.Monad (forM_)
import Data.Maybe (isNothing)
import Data.Text (Text)
import Utils (Version, succeded, setupNixpkgs)
import Data.Semigroup ((<>))
import Shelly
import qualified Text.Regex.Applicative as RE
import Text.Regex.Applicative (RE, (=~))
default (T.Text)
-- | Construct regex: ${version}[^/]+\.(tar|zip)
archiveRegex :: Version -> RE Char ()
archiveRegex version = (\_ _ _ _ -> ()) <$> RE.string (T.unpack version) <*> some (RE.psym (/= '/')) <*> RE.sym '.' <*> (RE.string "tar" <|> RE.string "zip")
fixSrcUrl :: Text -> Version -> Version -> Text -> Text -> Text -> Sh Text
fixSrcUrl packageName oldVersion newVersion derivationFile attrPath oldSrcUrl = do
nixpkgsPath <- setupNixpkgs
oldDerivationName <- cmd "nix" "eval" "-f" nixpkgsPath "--raw" ("pkgs." <> attrPath <> ".name")
let newDerivationName = T.replace oldVersion newVersion oldDerivationName
name <- cmd "nix" "eval" "--raw" ("(let pkgs = import ./. {}; in (builtins.parseDrvName pkgs." <> attrPath <> ".name).name)")
whenM (succeded $ cmd "grep" "-q" ("name = \"" <> newDerivationName <> "\"") derivationFile) $ do
-- Separate name and version
cmd "sed" "-i" ("s|" <> newDerivationName <> "|" <> name <> "-${version}|") derivationFile
cmd "grep" "-q" ("name = \"" <> name <> "-${version}\"") derivationFile
cmd "sed" "-i" ("s|^\\([ ]*\\)\\(name = \"" <> name <> "-${version}\";\\)|\\1\\2\n\\1version = \"" <> newVersion <> "\";|") derivationFile
cmd "grep" "-q" ("version = \"" <> newVersion <> "\";") derivationFile
downloads <- cmd "curl" ("https://repology.org/api/v1/metapackage/" <> packageName) -|- cmd "jq" ".[].downloads | select(values) | .[]"
let filteredDownloads = downloads & T.lines & filter (\url -> newVersion `T.isInfixOf` url && isNothing (T.unpack url =~ archiveRegex newVersion)) & map (T.replace "\"" "")
forM_ filteredDownloads $ \downloadUrl -> do
let oldUrl = T.replace oldVersion "${version}" (T.replace oldDerivationName "${name}" oldSrcUrl)
let newUrl = T.replace newVersion "${version}" (T.replace newDerivationName "${name}" downloadUrl)
cmd "sed" "-i" ("s|" <> oldUrl <> "|" <> newUrl <> "|") derivationFile
cmd "grep" "-q" ("url = \"" <> newUrl <> "\";") derivationFile
whenM (succeded $ cmd "grep" "-q" ("url = \"" <> newUrl <> "\";") derivationFile) $ do
whenM (succeded $ cmd "nix-prefetch-url" "-A" (attrPath <> ".src")) (exit 0)
exit 1

37
src/DeleteMerged.hs Normal file
View File

@ -0,0 +1,37 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
module DeleteMerged (deleteMerged) where
import Data.Function ((&))
import qualified Data.Text as T
import Control.Monad (forM_)
import Data.Maybe (mapMaybe)
import Utils (setupNixpkgs)
import Data.Semigroup ((<>))
import Shelly
default (T.Text)
deleteMerged :: Sh ()
deleteMerged = do
setupNixpkgs
cmd "git" "fetch" "--prune" "origin"
cmd "git" "fetch" "--prune" "upstream"
cmd "git" "checkout" "master"
cmd "git" "reset" "--hard" "upstream/master"
mergedRemoteBranches <- T.lines <$> cmd "git" "branch" "-ra" "--merged"
let mergedRemoteAutoUpdateBranches = mergedRemoteBranches & filter ("origin/auto-update/" `T.isInfixOf`) & mapMaybe (T.stripPrefix "remotes/origin/" . T.strip)
forM_ mergedRemoteAutoUpdateBranches $ \branch -> do
cmd "git" "push" "origin" (":" <> branch)
mergedBranches <- T.lines <$> cmd "git" "branch" "-a" "--merged"
let mergedAutoUpdateBranches = mergedBranches & filter ("auto-update/" `T.isInfixOf`)
forM_ mergedAutoUpdateBranches $ \branch -> do
cmd "git" "branch" "-d" branch

View File

@ -1,21 +1,38 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-}
import Control.Applicative ((<|>), (<**>))
import Control.Exception import Control.Exception
import qualified Data.Text as T import qualified Data.Text as T
import Shelly import Shelly
import Prelude hiding (log) import Prelude hiding (log)
import Utils (Options(..), Version, ExitCode(..), setupNixpkgs, parseUpdates, tRead, canFail) import Utils (Options(..))
import Data.Text (Text) import Data.Text (Text)
import Data.Maybe (isJust) import Data.Maybe (isJust)
import Update (updatePackage) import DeleteMerged (deleteMerged)
import Update (updateAll)
import Data.Semigroup ((<>)) import Data.Semigroup ((<>))
import qualified Options.Applicative as Opt
default (T.Text) default (T.Text)
log' logFile msg = do data Mode =
runDate <- cmd "date" "-Iseconds" Update
appendfile logFile (runDate <> msg) | DeleteMerged
modeParser :: Opt.Parser Mode
modeParser =
Opt.flag' Update (Opt.long "update" <> Opt.help "Update packages (default mode)" )
<|> Opt.flag' DeleteMerged ( Opt.long "delete-merged" <> Opt.help "Delete branches that were already merged" )
programInfo :: Opt.ParserInfo Mode
programInfo = Opt.info (modeParser <**> Opt.helper)
(Opt.fullDesc
<> Opt.progDesc "Update packages in nixpkgs repository"
<> Opt.header "nixpkgs-update" )
makeOptions :: Sh Options makeOptions :: Sh Options
@ -32,45 +49,12 @@ setUpEnvironment options = do
main :: IO () main :: IO ()
main = shelly $ do main = shelly $ do
mode <- liftIO $ Opt.execParser programInfo
options <- makeOptions options <- makeOptions
let logFile = workingDir options </> "ups.log"
mkdir_p (workingDir options)
touchfile logFile
setUpEnvironment options setUpEnvironment options
updates <- cmd "cat" "packages-to-update.txt" case mode of
DeleteMerged -> deleteMerged
setupNixpkgs Update -> updateAll options
let log = log' logFile
appendfile logFile "\n\n"
log "New run of ups.sh"
loop options log (parseUpdates updates) 0
loop :: Options -> (Text -> Sh ()) -> [(Text, Version, Version)] -> Int -> Sh ()
loop _ log [] _ = log "ups.sh finished"
loop options log ((package, oldVersion, newVersion) : moreUpdates) okToPrAt = do
log package
updated <- catch_sh
(updatePackage options package oldVersion newVersion okToPrAt)
(\ e ->
case e of
ExitCode 0 -> return True
ExitCode _ -> return False)
okToPrAt <-
if updated then do
log "SUCCESS"
tRead <$> cmd "date" "+%s" "-d" "+15 minutes"
else do
log "FAIL"
return okToPrAt
loop options log moreUpdates okToPrAt

View File

@ -2,15 +2,16 @@
{-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-}
module Update (updatePackage) where module Update (updateAll) where
import Control.Exception (throw) import Control.Exception (throw)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Text (Text) import Data.Text (Text)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Shelly import Shelly
import Clean (fixSrcUrl)
import Check (checkResult) import Check (checkResult)
import Utils (Version, Options(..), ExitCode(..), canFail, orElse, setupNixpkgs, tRead, checkAttrPathVersion) import Utils (Version, Options(..), ExitCode(..), canFail, orElse, parseUpdates, setupNixpkgs, tRead, checkAttrPathVersion)
import Data.Semigroup ((<>)) import Data.Semigroup ((<>))
default (T.Text) default (T.Text)
@ -53,8 +54,6 @@ isOnBlackList _ _ = return ""
rawEval :: Text -> Sh Text rawEval :: Text -> Sh Text
rawEval expr = T.strip <$> cmd "nix" "eval" "-f" "." "--raw" expr rawEval expr = T.strip <$> cmd "nix" "eval" "-f" "." "--raw" expr
fixSrcUrl :: Text -> Version -> Version -> Text -> Text -> Text -> Sh Text
fixSrcUrl packageName oldVersion newVersion derivationFile attrPath oldSrcUrl = cmd "./fix-src-url.sh" packageName oldVersion newVersion derivationFile attrPath oldSrcUrl
push :: Text -> Options -> Sh () push :: Text -> Options -> Sh ()
push branchName options = push branchName options =
@ -63,6 +62,53 @@ push branchName options =
else else
cmd "git" "push" "--set-upstream" "origin" branchName "--force" cmd "git" "push" "--set-upstream" "origin" branchName "--force"
log' logFile msg = do
runDate <- cmd "date" "-Iseconds"
appendfile logFile (runDate <> msg)
updateAll :: Options -> Sh ()
updateAll options = do
let logFile = workingDir options </> "ups.log"
mkdir_p (workingDir options)
touchfile logFile
updates <- cmd "cat" "packages-to-update.txt"
let log = log' logFile
appendfile logFile "\n\n"
log "New run of ups.sh"
updateLoop options log (parseUpdates updates) 0
updateLoop :: Options -> (Text -> Sh ()) -> [(Text, Version, Version)] -> Int -> Sh ()
updateLoop _ log [] _ = log "ups.sh finished"
updateLoop options log ((package, oldVersion, newVersion) : moreUpdates) okToPrAt = do
log package
updated <- catch_sh
(updatePackage options package oldVersion newVersion okToPrAt)
(\ e ->
case e of
ExitCode 0 -> return True
ExitCode _ -> return False)
okToPrAt <-
if updated then do
log "SUCCESS"
tRead <$> cmd "date" "+%s" "-d" "+15 minutes"
else do
log "FAIL"
return okToPrAt
updateLoop options log moreUpdates okToPrAt
updatePackage :: Options -> Text -> Version -> Version -> Int -> Sh Bool updatePackage :: Options -> Text -> Version -> Version -> Int -> Sh Bool
updatePackage options packageName oldVersion newVersion okToPrAt = do updatePackage options packageName oldVersion newVersion okToPrAt = do
nixpkgsPath <- setupNixpkgs nixpkgsPath <- setupNixpkgs