@@ -14,13 +14,14 @@ import Control.Applicative
1414import Control.Exception (displayException, try)
1515import Control.Lens (ifor, ifor_, (.~))
1616import Control.Monad
17−import Control.Monad.Extra (findM, unlessM, whenM)
17+import Control.Monad.Extra (findM)
1818import Control.Monad.Catch (MonadCatch, handle)
1919import Control.Monad.Except
2020import Data.Aeson ((.=))
2121import qualified Data.Aeson as Aeson
2222import Data.Aeson.Encode.Pretty
2323import qualified Data.Aeson.Types as Aeson
24+import Data.Bifunctor (first)
2425import qualified Data.ByteString.Lazy as LBS
2526import Data.Containers.ListUtils (nubOrd)
2627import Data.Default
@@ -208,7 +209,7 @@ data ReadThunkError
208209 deriving (Show)
209210
210211unpackedDirName :: FilePath
211−unpackedDirName = "local"
212+unpackedDirName = "."
212213
213214attrCacheFileName :: FilePath
214215attrCacheFileName = ".attr-cache"
@@ -356,7 +357,7 @@ overwriteThunk target thunk = do
356357 Right _ -> pure ()
357358
358359 --TODO: Is there a safer way to do this overwriting?
359− callProcessAndLogOutput (Debug, Error) $ proc rmPath ["-r", target] -- target may be a symlink
360+ liftIO $ removePathForcibly target
360361 createThunk target $ Right thunk
361362
362363thunkPtrToSpec :: ThunkPtr -> ThunkSpec
@@ -409,21 +410,6 @@ encodeThunkPtrData (ThunkPtr rev src) = case src of
409410 , confTrailingNewline = True
410411 }
411412
412−-- | Initialize a git repository to an unpacked thunk.
413−initThunk :: MonadObelisk m => FilePath -> m ()
414−initThunk target = withSpinner [i|Initializing thunk at ${target}|] $ do
415− checkThunkDirectory target
416− unlessM (liftIO $ doesDirectoryExist $ target </> ".git") $ failWith [i|${target} is not a git checkout.|]
417− ptr <- getThunkPtr CheckClean_NoCheck target Nothing
418− let tempThunkDir = target <.> "thunk-init"
419− whenM (liftIO $ doesPathExist tempThunkDir) $
420− failWith [i|A previous 'thunk init' left unfinished state at ${tempThunkDir}. You will need to rename or remove that path before trying again.|]
421− createThunk tempThunkDir $ Left (thunkPtrToSpec ptr) -- Only write the skeleton, but skip the ptr itself since it's unpacked
422− liftIO $ do
423− renameDirectory target (tempThunkDir </> unpackedDirName)
424− removePathForcibly target
425− renameDirectory tempThunkDir target
426−
427413createThunk :: MonadObelisk m => FilePath -> Either ThunkSpec ThunkPtr -> m ()
428414createThunk target ptrInfo =
429415 ifor_ (_thunkSpec_files spec) $ \path -> \case
@@ -555,7 +541,7 @@ let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256
555541 inherit owner repo rev sha256 fetchSubmodules private;
556542 };
557543 json = builtins.fromJSON (builtins.readFile ./github.json);
558−in if builtins.pathExists ./local then ./local else fetch json
544+in fetch json
559545|]
560546
561547parseGitHubJsonBytes :: LBS.ByteString -> Either String ThunkPtr
@@ -647,7 +633,7 @@ let fetch = {url, rev, branch ? null, sha256 ? null, fetchSubmodules ? false, pr
647633 url = realUrl; inherit rev sha256;
648634 };
649635 json = builtins.fromJSON (builtins.readFile ./git.json);
650−in if builtins.pathExists ./local then ./local else fetch json
636+in fetch json
651637|]
652638
653639parseGitJsonBytes :: LBS.ByteString -> Either String ThunkPtr
@@ -659,7 +645,7 @@ mkThunkSpec name jsonFileName parser srcNix = ThunkSpec name $ Map.fromList
659645 , ("thunk.nix", ThunkFileSpec_FileMatches srcNix)
660646 , (jsonFileName, ThunkFileSpec_Ptr parser)
661647 , (attrCacheFileName, ThunkFileSpec_AttrCache)
662− , (unpackedDirName, ThunkFileSpec_CheckoutIndicator)
648+ , (normalise $ unpackedDirName </> ".git", ThunkFileSpec_CheckoutIndicator)
663649 ]
664650 where
665651 defaultNixViaSrc = [here|
@@ -773,9 +759,6 @@ updateThunk p f = withSystemTempDirectory "obelisk-thunkptr-" $ \tmpDir -> do
773759finalMsg :: Bool -> (a -> Text) -> Maybe (a -> Text)
774760finalMsg noTrail s = if noTrail then Nothing else Just s
775761
776−unpackThunk :: MonadObelisk m => FilePath -> m ()
777−unpackThunk = unpackThunk' False
778−
779762-- | Check that we are not somewhere inside the thunk directory
780763checkThunkDirectory :: MonadObelisk m => FilePath -> m ()
781764checkThunkDirectory thunkDir = do
@@ -790,6 +773,9 @@ checkThunkDirectory thunkDir = do
790773 Right _ -> failWith [i|Refusing to perform thunk operation on ${thunkDir} because it is a thunk's unpacked source|]
791774 Left _ -> pure ()
792775
776+unpackThunk :: MonadObelisk m => FilePath -> m ()
777+unpackThunk = unpackThunk' False
778+
793779unpackThunk' :: MonadObelisk m => Bool -> FilePath -> m ()
794780unpackThunk' noTrail thunkDir = checkThunkDirectory thunkDir *> readThunk thunkDir >>= \case
795781 Left err -> failWith [i|Invalid thunk at ${thunkDir}: ${err}|]
@@ -805,9 +791,12 @@ unpackThunk' noTrail thunkDir = checkThunkDirectory thunkDir *> readThunk thunkD
805791 ThunkSource_Git _ -> NonEmpty.head gitThunkSpecs
806792 withSpinner' ("Fetching thunk " <> T.pack thunkName)
807793 (finalMsg noTrail $ const $ "Fetched thunk " <> T.pack thunkName) $ do
808− gitCloneForThunkUnpack gitSrc (_thunkRev_commit $ _thunkPtr_rev tptr) (tmpThunk </> unpackedDirName)
794+ let unpackedPath = tmpThunk </> unpackedDirName
795+ gitCloneForThunkUnpack gitSrc (_thunkRev_commit $ _thunkPtr_rev tptr) unpackedPath
809796
810− createThunk tmpThunk $ Left newSpec
797+ let normalizeMore = dropTrailingPathSeparator . normalise
798+ when (normalizeMore unpackedPath /= normalizeMore tmpThunk) $ -- Only write meta data if the checkout is not inplace
799+ createThunk tmpThunk $ Left newSpec
811800
812801 liftIO $ do
813802 removePathForcibly thunkDir
@@ -843,7 +832,7 @@ packThunk' noTrail (ThunkPackConfig force thunkConfig) thunkDir = checkThunkDire
843832 do
844833 let checkClean = if force then CheckClean_NoCheck else CheckClean_FullCheck
845834 thunkPtr <- modifyThunkPtrByConfig thunkConfig <$> getThunkPtr checkClean thunkDir (_thunkConfig_private thunkConfig)
846− callProcessAndLogOutput (Debug, Error) $ proc rmPath ["-rf", thunkDir] -- thunkDir may be a symlink
835+ liftIO $ removePathForcibly thunkDir
847836 createThunk thunkDir $ Right thunkPtr
848837 pure thunkPtr
849838
@@ -865,7 +854,8 @@ data CheckClean
865854
866855getThunkPtr :: forall m. MonadObelisk m => CheckClean -> FilePath -> Maybe Bool -> m ThunkPtr
867856getThunkPtr gitCheckClean dir mPrivate = do
868− let repoLocations = [(".git", "."), (unpackedDirName, unpackedDirName)]
857+ let repoLocations = nubOrd $ map (first normalise)
858+ [(".git", "."), (unpackedDirName </> ".git", unpackedDirName)]
869859 repoLocation' <- liftIO $ flip findM repoLocations $ doesDirectoryExist . (dir </>) . fst
870860 thunkDir <- case repoLocation' of
871861 Nothing -> failWith [i|Can't find an unpacked thunk in ${dir}|]