%  Copyright (C) 2002-2004 David Roundy
%
%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2, or (at your option)
%  any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; see the file COPYING.  If not, write to
%  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
%  Boston, MA 02110-1301, USA.

\subsection{darcs remove}
\begin{code}
module Remove ( remove ) where

import Monad ( liftM )

import DarcsCommands ( DarcsCommand(..), nodefaults )
import DarcsArguments ( DarcsFlag, fix_filepaths_wrt, verbose,
                        list_registered_files,
                        working_repo_dir, umask_option
                      )
import Repository ( identifyRepository, withRepoLock, amInRepository,
                    slurp_pending, add_to_pending,
                  )
import Patch ( Patch, rmdir, join_patches )
import SlurpDirectory ( slurp_removedir, slurp_removefile )
import RepoPrefs ( filetype_function )
import Diff ( smart_diff )
import FileName ( fp2fn )
#include "impossible.h"
\end{code}

\begin{code}
remove_description :: String
remove_description =
 "Remove one or more files or directories from the repository."
\end{code}

\options{remove}

\haskell{remove_help}

\begin{code}
remove_help :: String
remove_help =
 "Remove should be called when you want to remove a file from your project,\n"++
 "but don't actually want to delete the file.  Otherwise just delete the\n"++
 "file or directory, and darcs will notice that it has been removed.\n" ++
 "Be aware that the file WILL be deleted from any other copy of the\n" ++
 "repository to which you later apply the patch.\n"
\end{code}

\begin{code}
remove :: DarcsCommand
remove = DarcsCommand {command_name = "remove",
                       command_help = remove_help,
                       command_description = remove_description,
                       command_extra_args = -1,
                       command_extra_arg_help = ["<FILE or DIRECTORY> ..."],
                       command_command = remove_cmd,
                       command_prereq = amInRepository,
                       command_get_arg_possibilities = list_registered_files,
                       command_argdefaults = nodefaults,
                       command_darcsoptions =
                           [verbose, working_repo_dir, umask_option]}
\end{code}

\begin{code}
remove_cmd :: [DarcsFlag] -> [String] -> IO ()
remove_cmd opts relargs =
    withRepoLock opts $ \repository -> do
    args <- fix_filepaths_wrt "." opts relargs
    p <- make_remove_patch args
    add_to_pending repository p

make_remove_patch :: [FilePath] -> IO Patch
make_remove_patch files = do repository <- identifyRepository "."
                             s <- slurp_pending repository
                             wt <- filetype_function
                             join_patches `liftM` mrp wt s files
    where mrp wt s (f:fs) =
              case slurp_removedir (fp2fn f) s of
              Just s' -> do rest <- mrp wt s' fs
                            return $ rmdir f : rest
              Nothing ->
                  case slurp_removefile (fp2fn f) s of
                  Nothing -> fail $ "Can't remove "++f
                  Just s' ->
                      do rest <- mrp wt s' fs
                         return $ fromJust (smart_diff [] wt s s') : rest
          mrp _ _ [] = return []
\end{code}

