Skip to content

Commit 96895d3

Browse files
committed
refactor(install): Detect requirements already installed.
1 parent 8eb5ba8 commit 96895d3

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

icemodel/+icemodel/+internal/installRequiredFiles.m

+9-4
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140
end
141141

142142
function [requirementsList, urlList] = remoteDependencyList( ...
143-
requiredFiles, projectPath, localsource, remotesource)
143+
requiredFiles, projectPath, localSourcePath, remoteSourcePath)
144144
%REMOTEDEPENDENCYLIST Get a list of remote url's to function dependencies.
145145

146146
% This operates on one file at a time
@@ -161,20 +161,25 @@
161161

162162
% If the required file exists in the local source repo, add it to the
163163
% requirementsList and build a full path to the remote file.
164-
if contains(requiredFilePath, localsource)
164+
165+
% Note - this is problematic if the requiredFiles contain files which are
166+
% not in localSourcePath e.g. if one project depends on another. So this
167+
% needs to be refactored to work with localSourcePaths (plural).
168+
169+
if contains(requiredFilePath, localSourcePath)
165170

166171
% Add file names to list of external depencies
167172
requirementsList(ifile) = requiredFileName;
168173

169174
% Get the subfolder path relative to the top-level source repo
170-
relativePath = erase(requiredFilePath, localsource);
175+
relativePath = erase(requiredFilePath, localSourcePath);
171176
relativePath = strrep(relativePath, filesep , '/');
172177
if relativePath(1) == filesep
173178
relativePath = relativePath(2:end);
174179
end
175180

176181
% Use '/' not fullfile b/c fullfile is platform specific
177-
urlList(ifile) = remotesource + '/' + relativePath + '/' ...
182+
urlList(ifile) = remoteSourcePath + '/' + relativePath + '/' ...
178183
+ requirementsList(ifile);
179184
end
180185
end

icemodel/+icemodel/+internal/private/getRequiredFiles.m

+50
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,14 @@
8888
% Call codetools.requiredFilesAndProducts on the file list
8989
[requiredFiles, requiredProducts] = processFileList(targetFiles);
9090

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+
9196
% Find missing files (required files not included in the project)
9297
missingFiles = setdiff(requiredFiles, referenceFiles);
98+
missingFiles = setdiff(missingFiles, installedFiles);
9399
missingFiles = string(missingFiles);
94100
requiredFiles = string(requiredFiles);
95101

@@ -103,6 +109,49 @@
103109
Requirements.requiredProducts = requiredProducts;
104110
end
105111

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+
106155
%% Local Functions
107156
function [requiredFiles, requiredProducts] = processFileList(fileList)
108157

@@ -234,3 +283,4 @@
234283
end
235284
end
236285
end
286+

0 commit comments

Comments
 (0)