% 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 whatsnew} \label{whatsnew} \begin{code} module WhatsNew ( whatsnew ) where import System ( ExitCode(..), exitWith ) import List ( sort ) import Monad ( liftM, when, unless ) import DarcsCommands ( DarcsCommand(..), nodefaults ) import DarcsArguments ( DarcsFlag(..), working_repo_dir, lookforadds, ignoretimes, verbose, noskip_boring, #ifdef HAVEWX gui_interactive, #endif summary, unified, fix_filepaths_wrt, list_registered_files, ) import TouchesFiles ( choose_touching ) import Repository ( identifyRepository, slurp_recorded, get_unrecorded, amInRepository ) import RepoPrefs ( filetype_function ) import Diff ( smart_diff ) import Patch ( patch_summary, join_patches, apply_to_slurpy, is_hunk, flatten, is_null_patch, ) import PrintPatch ( printPatch, contextualPrintPatch ) import Patch ( invert, apply_to_filepaths, null_patch ) import Printer ( putDocLn, renderString, vcat, text ) #ifdef HAVEWX import GuiUtils ( patchViewer, updatePatchViewer ) import Patch ( Patch ) import Graphics.UI.WX hiding ( when, text ) import qualified Graphics.UI.WX ( text ) import Graphics.UI.WXCore hiding ( when ) #endif \end{code} \options{whatsnew} \haskell{whatsnew_description} \begin{code} whatsnew_description :: String whatsnew_description = "Display unrecorded changes in the working copy." \end{code} \haskell{whatsnew_help} \verb!darcs whatsnew! will return a non-zero value if there are no changes, which can be useful if you just want to see in a script if anything has been modified. If you want to see some context around your changes, you can use the \verb!-u! option, to get output similar to the unidiff format. \begin{code} whatsnew_help :: String whatsnew_help = "whatsnew gives you a view of what changes you've made in your working\n"++ "copy that haven't yet been recorded. The changes are displayed in\n"++ "darcs patch format. Note that --look-for-adds implies --summary usage.\n" \end{code} \begin{code} whatsnew :: DarcsCommand whatsnew = DarcsCommand {command_name = "whatsnew", command_help = whatsnew_help, command_description = whatsnew_description, command_extra_args = -1, command_extra_arg_help = ["[FILE or DIRECTORY]..."], command_command = whatsnew_cmd, command_prereq = amInRepository, command_get_arg_possibilities = list_registered_files, command_argdefaults = nodefaults, command_darcsoptions = [verbose, #ifdef HAVEWX gui_interactive, #endif summary, unified, ignoretimes, lookforadds, noskip_boring, working_repo_dir]} \end{code} \begin{code} whatsnew_cmd :: [DarcsFlag] -> [String] -> IO () whatsnew_cmd opts' args | LookForAdds `elem` opts' && NoSummary `notElem` opts' = do -- add Summary to the opts since 'darcs whatsnew --look-for-adds' -- implies summary let opts = Summary : opts' repository <- identifyRepository "." files <- fix_filepaths_wrt "." opts args when (concat files /= "") $ putStrLn $ "What's new in "++unwords (map show files)++":\n" maybe_all_changes <- get_unrecorded repository opts maybe_old_changes <- get_unrecorded repository $ filter (/= LookForAdds) opts s <- slurp_recorded repository ftf <- filetype_function let chold = case maybe_old_changes of Nothing -> null_patch Just p -> p pre_changed_files = apply_to_filepaths (invert chold) files select_adds = join_patches . filter (not . is_hunk) . flatten select_files = choose_touching pre_changed_files cho = select_files chold all_changes = case maybe_all_changes of Nothing -> join_patches [] Just p -> p cha = select_adds $ select_files all_changes maybe_new_changes = do so <- apply_to_slurpy (select_adds cho) s sn <- apply_to_slurpy cha s smart_diff [LookForAdds,Summary] ftf so sn chn = case maybe_new_changes of Nothing -> join_patches [] Just nc -> nc if is_null_patch chn && is_null_patch cho then do putStrLn "No changes!" exitWith $ ExitFailure 1 else do putDocLn $ patch_summary cho unless (is_null_patch chn) $ putDocLn $ lower_as $ renderString $ patch_summary chn where lower_as s = vcat $ map (text . l_as) $ lines s l_as ('A':s) = 'a':s l_as s = s whatsnew_cmd opts args = do files <- sort `liftM` fix_filepaths_wrt "." opts args when (concat files /= "") $ putStrLn $ "What's new in "++unwords (map show files)++":\n" repository <- identifyRepository "." maybe_changes <- get_unrecorded repository opts case maybe_changes of Nothing -> do putStrLn "No changes!" exitWith $ ExitFailure 1 Just changes -> let pre_changed_files = apply_to_filepaths (invert changes) files ch = choose_touching pre_changed_files changes in if is_null_patch ch then do putStrLn "No changes!" exitWith $ ExitFailure 1 else #ifdef HAVEWX if Gui `elem` opts then do s <- slurp_recorded repository guiShowPatch ch s else #endif if Summary `elem` opts then putDocLn $ patch_summary ch else if Unified `elem` opts then do s <- slurp_recorded repository contextualPrintPatch s ch else printPatch ch #ifdef HAVEWX guiShowPatch :: Patch -> a -> IO () guiShowPatch p _ = start $ hello p hello :: Patch -> IO () hello p = do f <- frame [Graphics.UI.WX.text := "Whats New!"] t <- patchViewer f updatePatchViewer t (flatten p) (ms,mclose) <- default_menubar quit <- button f [Graphics.UI.WX.text := "Quit", on command := close f] set f [layout := column 0 [fill $ widget t, centre $ hstretch $ margin 5 $ widget quit], menuBar := ms, on (menu mclose) := close f, clientSize := sz 600 400 -- this is window actual size ] default_menubar :: IO ([Menu ()], MenuItem ()) default_menubar = do file <- menuPane [Graphics.UI.WX.text := "&File"] mclose <- menuItem file [Graphics.UI.WX.text := "&Quit\tCtrl+Q", help := "Quit darcs"] return ([file],mclose) #endif \end{code} If you give one or more file or directory names as an argument to \verb!whatsnew!, darcs will output only changes to those files or to files in those directories.