|
88 | 88 | % Call codetools.requiredFilesAndProducts on the file list
|
89 | 89 | [requiredFiles, requiredProducts] = processFileList(targetFiles);
|
90 | 90 |
|
| 91 | + % Remove required files which are listed twice - once because they already |
| 92 | + % exist in the reference list, and again because they are |
| 93 | + [requiredFiles, installedFiles] = detectInstalledFiles( ... |
| 94 | + requiredFiles, referenceFiles); |
| 95 | + |
91 | 96 | % Find missing files (required files not included in the project)
|
92 | 97 | missingFiles = setdiff(requiredFiles, referenceFiles);
|
| 98 | + missingFiles = setdiff(missingFiles, installedFiles); |
93 | 99 | missingFiles = string(missingFiles);
|
94 | 100 | requiredFiles = string(requiredFiles);
|
95 | 101 |
|
|
103 | 109 | Requirements.requiredProducts = requiredProducts;
|
104 | 110 | end
|
105 | 111 |
|
| 112 | +function [requiredFiles, installedFiles] = detectInstalledFiles( ... |
| 113 | + requiredFiles, referenceFiles) |
| 114 | + |
| 115 | + % If the required files exist both within the project (e.g. b/c they were |
| 116 | + % already installed with this function) and elsewhere on the path (e.g. in |
| 117 | + % the localSourcePath used by installRequiredFiles), they may be listed twice |
| 118 | + % in requiredFiles, but only once in referenceFiles (the installed ones). |
| 119 | + % This may occur b/c matlab.codetools.requiredFilesAndProducts finds them in |
| 120 | + % localSourcePath first (b/c it is higher on the path), and then finds them |
| 121 | + % in their installed location within the project. Then the setdiff above only |
| 122 | + % removes the ones which are installed locally. The next step prunes the ones |
| 123 | + % which exist locally but are listed as missing. Note, the desired behavior |
| 124 | + % is unclear here - they could be reinstalled by default. |
| 125 | + |
| 126 | + % installedFiles are the ones in localSourcePath, not the ones already in the |
| 127 | + % toolbox b/c those are in referenceList. |
| 128 | + |
| 129 | + % Extract file names without paths |
| 130 | + [~, requiredFilenames] = fileparts(requiredFiles); |
| 131 | + [~, referenceFilenames] = fileparts(referenceFiles); |
| 132 | + |
| 133 | + % Find duplicates in requiredFilenames |
| 134 | + [uniqueFilenames, ia, ic] = unique(requiredFilenames, 'stable'); |
| 135 | + duplicateIndices = setdiff(1:numel(requiredFilenames), ia); |
| 136 | + |
| 137 | + % Filter to get filenames that appear more than once in requiredFiles |
| 138 | + isDuplicate = accumarray(ic, 1) > 1; |
| 139 | + duplicateFilenames = uniqueFilenames(isDuplicate); |
| 140 | + |
| 141 | + % Find which of these duplicate filenames are also in the referenceFiles |
| 142 | + installedFileIndices = ismember(requiredFilenames, duplicateFilenames) & ... |
| 143 | + ismember(requiredFilenames, referenceFilenames); |
| 144 | + |
| 145 | + % Extract the actual paths of these installed files from requiredFiles |
| 146 | + installedDuplicateFiles = requiredFiles(installedFileIndices); |
| 147 | + |
| 148 | + % Get the list of installed files (files identified as required but which |
| 149 | + % already exist in the toolbox). |
| 150 | + installedFiles = installedDuplicateFiles(~ismember(installedDuplicateFiles, ... |
| 151 | + referenceFiles)); |
| 152 | +end |
| 153 | + |
| 154 | + |
106 | 155 | %% Local Functions
|
107 | 156 | function [requiredFiles, requiredProducts] = processFileList(fileList)
|
108 | 157 |
|
|
234 | 283 | end
|
235 | 284 | end
|
236 | 285 | end
|
| 286 | + |
0 commit comments