mirror of
https://github.com/ryantm/nixpkgs-update.git
synced 2024-12-15 22:01:58 +03:00
Merge branch 'green-to-purple' of https://github.com/jtojnar/nix-update into green-to-purple
This commit is contained in:
commit
e3b149b2c6
@ -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
|
|
@ -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
|
|
@ -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
53
src/Clean.hs
Normal 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
37
src/DeleteMerged.hs
Normal 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
|
||||||
|
|
70
src/Main.hs
70
src/Main.hs
@ -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
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user