1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
function files_out = gipper (directory, include, exclude, exclude_hidden)
%GIPPER zip selected files and subdirectories (gipper = grep + zip)
%
% files = gipper (directory, include, exclude, exclude_hidden) ;
%
% Creates a zip file of all files and subdirectories in a directory. A file in
% the directory or any of its subdirectories whose name matches any expression
% in 'include' via regexp is added to the zip file. A file that matches any
% expression in 'exclude' is not added. A subdirectory whose name or full
% pathname matches any expression in 'exclude' is not searched. The name of
% the zip file is the name of the directory, with '.zip' appended.
%
% 'include' and 'exclude' are either cells of strings, or just single strings.
%
% With no outputs, a list of files is printed and the user is prompted before
% proceeding. Otherwise, the gipper proceeds without prompting and returns a
% list of files that were added to the zip file.
%
% By default, all files and subdirectories of the directory are included, except
% that hidden files and directories (those whose names start with a dot, '.')
% are excluded.
%
% If any parameter is empty or not present, the defaults are used:
% directory: defaults to the current directory
% include: defaults to include all files and directories
% exclude: defaults to exclude nothing, as modified by 'exclude_hidden'
% exclude_hidden: 1 (exclude hidden files and directories)
%
% Empty directories or subdirectories are never included.
%
% Example:
% % suppose 'X' is the name of the current directory.
%
% % include all files in X (except hidden files) in the zip file ../X.zip
% gipper
%
% % create mytoolbox.zip archive of the 'X/mytoolbox' directory
% gipper mytoolbox
%
% % only include *.m files in ../X.zip
% gipper '' '\.m$'
%
% % create ../X.zip, but exclude compiled object and MEX files
% gipper ('', '', { '\.o$' '\.obj$', ['\.' mexext '$'] })
%
% % include everything, including hidden files, in ../X.zip
% gipper ('', '', '', 0)
%
% % zip mytoolbox, except hidden files and the mytoolbox/old directory
% gipper mytoolbox '' old
%
% % these are the same, except gipper also traverses subdirectories
% gipper ('', { '\.m$', '\.*mat$' })
% zip ('../X', { '*.m', '*.mat' })
%
% See also zip, regexp, unzip.
% NOTE: if the directory name is empty or not present, and you hit control-C
% while the gipper is running, your current directory will now be the parent.
% You must install the gipper first, by placing it in your MATLAB path.
% gipper, Copyright (c) 2007, Timothy A Davis. All Rights Reserved.
% SPDX-License-Identifier: BSD-3-clause
% Created May 2007, using MATLAB 7.4 (R2007a). Requires MATLAB 6.5 or later.
% exclude hidden files and directories by default
if (nargin < 4)
exclude_hidden = 1 ;
end
% exclude nothing by default (as modified by exclude_hidden)
if (nargin < 3)
exclude = { } ;
end
exclude = cleanup (exclude) ;
% append the hidden file and directory rule, if requested
if (exclude_hidden)
exclude = union (exclude, { '^\.', [ '\' '/' '\.' ] }) ;
end
% always exclude '.' and '..' files
exclude = union (exclude, { '^\.$', '^\.\.$' }) ;
% include all files by default
if (nargin < 2 || isempty (include))
include = { '.' } ;
end
include = cleanup (include) ;
% operate on the current directory, if not specified
if (nargin < 1 || isempty (directory))
here = pwd ;
directory = here ((find (here == '/', 1, 'last') + 1) : end) ;
% use try-catch so that if a failure occurs, we go back to current
% directory. Unfortunately, this mechanism does not catch a control-C.
gipper_found = 0 ;
try
% run the gipper in the parent
cd ('..') ;
% if gipper.m is not in the path, it will no longer exist
gipper_found = ~isempty (which ('gipper')) ;
if (gipper_found)
if (nargout == 0)
fprintf ('Note that if you terminate gipper with control-C, ') ;
fprintf ('your\ndirectory be changed to the parent') ;
fprintf (' (as in "cd ..").\n') ;
gipper (directory, include, exclude, exclude_hidden) ;
else
files_out = gipper (directory, include, exclude,exclude_hidden);
end
end
catch
cd (here) ;
rethrow (lasterror) ;
end
% go back to where we started
cd (here) ;
if (~gipper_found)
fprintf ('To install the gipper, type "pathtool" and add\n') ;
fprintf ('the directory in which it resides:\n') ;
fprintf ('%s\n', which (mfilename)) ;
error ('You must install the gipper first.') ;
end
return
else
if (nargout == 0)
fprintf ('\ngipper: creating %s%s%s.zip\n', pwd, '/', directory) ;
end
end
% get the list of files to zip
n = 0 ;
files = { } ;
for file = dir (directory)'
[files, n] = finder (files, n, directory, file.name, include, exclude) ;
end
files = files (1:n)' ;
% cannot create an empty zip file
if (isempty (files))
warning ('gipper:nothing', 'nothing to zip; no zip file created') ;
if (nargout > 0)
files_out = files ;
end
return
end
% return the list of files, or confirm
if (nargout == 0)
% print the list of files and ask for confirmation first
fprintf ('Creating a zip archive containing these files:\n\n') ;
for k = 1:length(files)
fprintf (' %s\n', files {k}) ;
end
fprintf ('\nCreating the zip archive: %s', directory) ;
if (isempty (regexp (directory, '\.zip$', 'once')))
fprintf ('.zip') ;
end
fprintf ('\n') ;
reply = input ('Proceed? (yes or no, default is yes): ', 's') ;
if (~isempty (reply) && lower (reply (1)) == 'n')
fprintf ('zip file not created\n') ;
return
end
else
% zip the files without asking
files_out = files ;
end
% zip the files
zip (directory, files) ;
%-------------------------------------------------------------------------------
function [files, n] = finder (files, n, prefix, name, include, exclude)
% finder: return a list of files to zip
% fullname includes the entire path to the file or directory
fullname = [prefix '/' name] ;
if (isdir (fullname))
% always traverse a subdirectory to look for files to include, unless the
% directory name or fullname itself is explicitly excluded.
if (~(grep (name, exclude) || grep (fullname, exclude)))
% the directory is selected, recursively traverse it
for file = dir (fullname)'
[files, n] = finder (files, n, fullname, file.name, ...
include, exclude) ;
end
end
else
% this is a file, apply the include/exclude rules to just the file name
% itself not the fullname.
if (grep (name, include) && ~grep (name, exclude))
% the file is selected for the archive. Use a dynamic-table approach
% to speed up the dynamic growth of the table.
n = n + 1 ;
files {n} = fullname ;
if (n == length (files))
files {2*n} = [ ] ;
end
end
end
%-------------------------------------------------------------------------------
function match = grep (string, list)
% grep: determine if a string matches an expression in a list
match = 0 ;
for expression = list
if (~isempty (regexp (string, expression {1}, 'once')))
match = 1 ;
return ;
end
end
%-------------------------------------------------------------------------------
function s = cleanup (s)
% cleanup: ensure the input list is in the proper format
s = s (:)' ; % make sure it is a row vector
if (ischar (s))
s = { s } ; % if it is a string, convert it into a cell with one string
end
|