%  Copyright (C) 2003 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 setpref}
\begin{code}
{-# OPTIONS_GHC -cpp #-}
module Darcs.Commands.SetPref ( setpref ) where

import System.Exit ( exitWith, ExitCode(..) )
import Control.Monad (when)

import Darcs.Commands ( DarcsCommand(..), nodefaults )
import Darcs.Arguments ( DarcsFlag, working_repo_dir, umask_option )
import Darcs.Repository ( amInRepository, add_to_pending, withRepoLock, ($-) )
import Darcs.Patch ( changepref )
import Darcs.Ordered ( FL(..) )
import Darcs.Repository.Prefs ( get_prefval, change_prefval, )
#include "impossible.h"
\end{code}

\begin{code}
setpref_description :: String
setpref_description =
 "Set a value for a preference (test, predist, ...)."
\end{code}

\options{setpref}
Usage example:
\begin{verbatim}
% darcs setpref test "echo I am not really testing anything."
\end{verbatim}

\haskell{setpref_help} If you just want to set the pref value in your
repository only, you can just edit ``\verb!_darcs/prefs/prefs!''.  Changes
you make in that file will be preserved.

The ``\verb!_darcs/prefs/prefs!'' holds the only preferences information
that can propagate between repositories by pushes and pulls, and the only
way this happens is when the setprefs command is used.  Note that although
prefs settings are included in patches, they are \emph{not} fully version
controlled.  In particular, depending on the order in which a series of
merges is performed, you may end up with a different final prefs
configuration.  In practice I don't expect this to be a problem, as the
prefs usually won't be changed very often.

\begin{code}
valid_pref_data :: [String]
valid_pref_data = ["test", "predist", "boringfile", "binariesfile"]
\end{code}
The following values are valid preferences options which can be configured
using setpref:
\begin{itemize}
\item ``test'' --- the command to run as a test script.
\item ``predist'' --- a command to run prior to tarring up a distribution
  tarball.  Typically this would consist of autoconf and/or automake.
\item ``boringfile'' --- the name of a file to read instead of the
  ``boring'' prefs file.
\item ``binariesfile'' --- the name of a file to read instead of the
  ``binaries'' prefs file.
\end{itemize}

\begin{code}
setpref_help :: String
setpref_help =
 "Setpref allows you to set a preference value in a way that will\n"++
 "propagate to other repositories.\n\n"++
 "Valid preferences are: "++unwords valid_pref_data++".\n"
\end{code}

\begin{code}
setpref :: DarcsCommand
setpref = DarcsCommand {command_name = "setpref",
                        command_help = setpref_help,
                        command_description = setpref_description,
                        command_extra_args = 2,
                        command_extra_arg_help = ["<PREF>",
                                                  "<VALUE>"],
                        command_command = setpref_cmd,
                        command_prereq = amInRepository,
                        command_get_arg_possibilities = return valid_pref_data,
                        command_argdefaults = nodefaults,
                        command_advanced_options = [umask_option],
                        command_basic_options =
                            [working_repo_dir]}
\end{code}

\begin{code}
setpref_cmd :: [DarcsFlag] -> [String] -> IO ()
setpref_cmd opts [pref,val] = withRepoLock opts $- \repository -> do
  when (' ' `elem` pref) $ do
    putStrLn $ "'"++pref++
               "' is not a valid preference name:  no spaces allowed!"
    exitWith $ ExitFailure 1
  when (not $ pref `elem` valid_pref_data) $ do
    putStrLn $ "'"++pref++"' is not a valid preference name!"
    putStrLn $ "Try one of:  "++unwords valid_pref_data++""
    exitWith $ ExitFailure 1
  oval <- get_prefval pref
  old <- case oval of Just v -> return v
                      Nothing -> return ""
  change_prefval pref old val
  putStrLn $ "Changing value of "++pref++" from '"++old++"' to '"++val++"'"
  add_to_pending repository (changepref pref old val :>: NilFL)
setpref_cmd _ _ = impossible
\end{code}

