Skip to content
Snippets Groups Projects
Upgrade.hs 3.14 KiB
Newer Older
Joey Hess's avatar
Joey Hess committed
{- git-annex upgrade support
 -
 - Copyright 2010-2020 Joey Hess <id@joeyh.name>
Joey Hess's avatar
Joey Hess committed
 -
 - Licensed under the GNU AGPL version 3 or higher.
Joey Hess's avatar
Joey Hess committed
 -}

{-# LANGUAGE CPP #-}

Joey Hess's avatar
Joey Hess committed
module Upgrade where

import qualified Annex
import qualified Git
import Config
import Config.Files
Joey Hess's avatar
Joey Hess committed
import Annex.Version
Joey Hess's avatar
v7  
Joey Hess committed
import Types.RepoVersion
#ifndef mingw32_HOST_OS
Joey Hess's avatar
Joey Hess committed
import qualified Upgrade.V0
import qualified Upgrade.V1
Joey Hess's avatar
Joey Hess committed
import qualified Upgrade.V2
import qualified Upgrade.V4
import qualified Upgrade.V5
Joey Hess's avatar
v7  
Joey Hess committed
import qualified Upgrade.V6
Joey Hess's avatar
Joey Hess committed
import qualified Upgrade.V7
Joey Hess's avatar
Joey Hess committed

import qualified Data.Map as M

Joey Hess's avatar
v7  
Joey Hess committed
checkUpgrade :: RepoVersion -> Annex ()
checkUpgrade = maybe noop giveup <=< needsUpgrade
Joey Hess's avatar
v7  
Joey Hess committed
needsUpgrade :: RepoVersion -> Annex (Maybe String)
Joey Hess's avatar
Joey Hess committed
needsUpgrade v
	| v `elem` supportedVersions = ok
	| otherwise = case M.lookup v autoUpgradeableVersions of
		Nothing
			| v `elem` upgradableVersions ->
				err "Upgrade this repository: git-annex upgrade"
			| otherwise ->
				err "Upgrade git-annex."
		Just newv -> ifM (annexAutoUpgradeRepository <$> Annex.getGitConfig)
			( tryNonAsync (upgrade True newv) >>= \case
				Right True -> ok
Joey Hess's avatar
Joey Hess committed
				Right False -> err "Automatic upgrade failed!"
				Left ex -> err $ "Automatic upgrade exception! " ++ show ex
			, err "Automatic upgrade is disabled by annex.autoupgraderepository configuration. To upgrade this repository: git-annex upgrade"
	err msg = do
		g <- Annex.gitRepo
		p <- liftIO $ absPath $ fromRawFilePath $ Git.repoPath g
		return $ Just $ unwords
			[ "Repository", p
			, "is at unsupported version"
			, show (fromRepoVersion v) ++ "."
			, msg
			]
Joey Hess's avatar
Joey Hess committed
	ok = return Nothing
Joey Hess's avatar
v7  
Joey Hess committed
upgrade :: Bool -> RepoVersion -> Annex Bool
	when upgraded
		postupgrade
Joey Hess's avatar
Joey Hess committed
  where
	go (Just v)
		| v >= destversion = return True
		| otherwise = ifM upgradingRemote
			( upgraderemote
			, ifM (up v)
				( go (Just (RepoVersion (fromRepoVersion v + 1)))
				, return False
				)
	postupgrade = ifM upgradingRemote
		( reloadConfig
		, setVersion destversion
		)

#ifndef mingw32_HOST_OS
	up (RepoVersion 0) = Upgrade.V0.upgrade
	up (RepoVersion 1) = Upgrade.V1.upgrade
	up (RepoVersion 0) = giveup "upgrade from v0 on Windows not supported"
	up (RepoVersion 1) = giveup "upgrade from v1 on Windows not supported"
	up (RepoVersion 2) = Upgrade.V2.upgrade
	up (RepoVersion 3) = Upgrade.V3.upgrade automatic
	up (RepoVersion 4) = Upgrade.V4.upgrade automatic
	up (RepoVersion 5) = Upgrade.V5.upgrade automatic
	up (RepoVersion 6) = Upgrade.V6.upgrade automatic
Joey Hess's avatar
Joey Hess committed
	up (RepoVersion 7) = Upgrade.V7.upgrade automatic
	up _ = return True

	-- Upgrade local remotes by running git-annex upgrade in them.
	-- This avoids complicating the upgrade code by needing to handle
	-- upgrading a git repo other than the current repo.
	upgraderemote = do
		rp <- fromRawFilePath <$> fromRepo Git.repoPath
		cmd <- liftIO readProgramFile
		liftIO $ boolSystem' cmd
			[ Param "upgrade"
			, Param "--quiet"
			, Param "--autoonly"
			]
			(\p -> p { cwd = Just rp })

upgradingRemote :: Annex Bool
upgradingRemote = isJust <$> fromRepo Git.remoteName