diff --git a/code/+matbox/+codespell/+internal/addToIgnore.m b/code/+matbox/+codespell/+internal/addToIgnore.m index a8babb3..b63de74 100644 --- a/code/+matbox/+codespell/+internal/addToIgnore.m +++ b/code/+matbox/+codespell/+internal/addToIgnore.m @@ -1,5 +1,5 @@ function addToIgnore(word, ignoreFilePath) - + [~, ~, fileExt] = fileparts(ignoreFilePath); if strcmp(fileExt, '.codespell_ignore') @@ -9,7 +9,7 @@ function addToIgnore(word, ignoreFilePath) else fileContent = ''; end - + elseif strcmp(fileExt, '.codespellrc') if isfile(ignoreFilePath) fileContent = fileread(ignoreFilePath); diff --git a/code/+matbox/+py/getPackageInfo.m b/code/+matbox/+py/getPackageInfo.m index bb88e0a..ae8bfce 100644 --- a/code/+matbox/+py/getPackageInfo.m +++ b/code/+matbox/+py/getPackageInfo.m @@ -94,7 +94,7 @@ % Postprocess Requires, Required_by packageInfo.Requires = split(packageInfo.Requires, ', '); packageInfo.Required_by = split(packageInfo.Required_by, ', '); - + if ~ismissing( options.Field ) packageInfo = packageInfo.(options.Field); end diff --git a/code/+matbox/+py/getPythonExecutable.m b/code/+matbox/+py/getPythonExecutable.m index a2e0f60..61ccaf5 100644 --- a/code/+matbox/+py/getPythonExecutable.m +++ b/code/+matbox/+py/getPythonExecutable.m @@ -33,9 +33,9 @@ % Todo: What if MATLAB release is older than R2019b when pyenv was % introduced? - + pythonInfo = pyenv; - + if pythonInfo.Version == "" error("MatBox:PythonNotInstalled", "Python not installed.") end diff --git a/code/+matbox/+py/pipInstall.m b/code/+matbox/+py/pipInstall.m index a8c38ce..2b612b3 100644 --- a/code/+matbox/+py/pipInstall.m +++ b/code/+matbox/+py/pipInstall.m @@ -30,7 +30,7 @@ function pipInstall(packageName, options) arguments packageName (1,1) string - options.Update (1,1) logical = false + options.Update (1,1) logical = false end pythonExecutable = matbox.py.getPythonExecutable(); diff --git a/code/+matbox/+setup/+internal/+fex/getToolboxRequiredAddonStruct.m b/code/+matbox/+setup/+internal/+fex/getToolboxRequiredAddonStruct.m index 90bee81..2fcbb44 100644 --- a/code/+matbox/+setup/+internal/+fex/getToolboxRequiredAddonStruct.m +++ b/code/+matbox/+setup/+internal/+fex/getToolboxRequiredAddonStruct.m @@ -19,13 +19,13 @@ numAddons = numel(fexURI); fieldNames = ["Name", "Identifier", "EarliestVersion", "LatestVersion", "DownloadURL"]; - + S = cell2struct( repmat({""}, 1, numel(fieldNames)), cellstr(fieldNames), 2 ); S = repmat(S, 1, numAddons); for iAddon = 1:numAddons [addonUuid, version] = matbox.setup.internal.fex.parseFileExchangeURI(fexURI(iAddon)); - + addonMetadata = matbox.setup.internal.fex.getAddonMetadata(addonUuid); S(iAddon).Name = addonMetadata.name; diff --git a/code/+matbox/+setup/+internal/+fex/isToolboxInstalled.m b/code/+matbox/+setup/+internal/+fex/isToolboxInstalled.m index c7d2a42..63f19f0 100644 --- a/code/+matbox/+setup/+internal/+fex/isToolboxInstalled.m +++ b/code/+matbox/+setup/+internal/+fex/isToolboxInstalled.m @@ -1,10 +1,10 @@ function [tf, versionString, toolboxFolder] = isToolboxInstalled(toolboxIdentifier, versionString) - + arguments toolboxIdentifier (1,1) string versionString (1,1) string = missing end - + import matlab.internal.addons.util.retrieveInstallationFolderForAddOn tf = false; diff --git a/code/+matbox/+setup/+internal/+fex/parseFileExchangeURI.m b/code/+matbox/+setup/+internal/+fex/parseFileExchangeURI.m index 4e87e60..5262f7e 100644 --- a/code/+matbox/+setup/+internal/+fex/parseFileExchangeURI.m +++ b/code/+matbox/+setup/+internal/+fex/parseFileExchangeURI.m @@ -3,20 +3,20 @@ % % NB: This function relies on an undocumented api, and might break in the % future. - + arguments uri (1,:) string end - + FEX_API_URL = "https://addons.mathworks.com/registry/v1/"; - + packageUuid = repmat("", 1, numel(uri)); version = repmat("latest", 1, numel(uri)); % Initialize default value for i = 1:numel(uri) - + splitUri = strsplit(uri(i), '/'); - + packageNumber = regexp(splitUri{2}, '\d*(?=-)', 'match', 'once'); try packageInfo = webread(FEX_API_URL + num2str(packageNumber)); @@ -29,7 +29,7 @@ rethrow(ME) end end - + if numel(splitUri) == 3 version = string( splitUri{3} ); assert( any(strcmp(packageInfo.versions, version) ), ... diff --git a/code/+matbox/+setup/+internal/+github/+api/getCurrentCommitID.m b/code/+matbox/+setup/+internal/+github/+api/getCurrentCommitID.m index 0ff5a50..7997403 100644 --- a/code/+matbox/+setup/+internal/+github/+api/getCurrentCommitID.m +++ b/code/+matbox/+setup/+internal/+github/+api/getCurrentCommitID.m @@ -15,7 +15,7 @@ API_BASE_URL = sprintf("https://api.github.com/repos/%s/%s", ... options.Owner, repositoryName); - + apiURL = strjoin( [API_BASE_URL, "commits", options.BranchName], '/'); % Get info about latest commit: diff --git a/code/+matbox/+setup/+internal/+github/+api/getDefaultBranch.m b/code/+matbox/+setup/+internal/+github/+api/getDefaultBranch.m index 26c95b4..f3e4e12 100644 --- a/code/+matbox/+setup/+internal/+github/+api/getDefaultBranch.m +++ b/code/+matbox/+setup/+internal/+github/+api/getDefaultBranch.m @@ -8,7 +8,7 @@ % Build the API URL apiUrl = sprintf('https://api.github.com/repos/%s/%s', owner, repoName); - + requestOpts = matbox.setup.internal.github.api.getGithubWebOptions(); requestOpts.Timeout = 10; requestOpts.ContentType = 'json'; diff --git a/code/+matbox/+setup/+internal/+github/+api/getGithubWebOptions.m b/code/+matbox/+setup/+internal/+github/+api/getGithubWebOptions.m index aff07e1..a88cd85 100644 --- a/code/+matbox/+setup/+internal/+github/+api/getGithubWebOptions.m +++ b/code/+matbox/+setup/+internal/+github/+api/getGithubWebOptions.m @@ -6,22 +6,22 @@ % % Outputs: % options - weboptions object with authentication headers if token is available - + arguments customHeaders = {} end - + % Get GITHUB_TOKEN from environment variables token = getenv('GITHUB_TOKEN'); - + % Initialize options options = weboptions('UserAgent', 'MATLAB WebClient'); - + % Add custom headers if provided if ~isempty(customHeaders) options.HeaderFields = customHeaders; end - + % Add authentication header if token is available if ~isempty(token) if isempty(options.HeaderFields) diff --git a/code/+matbox/+setup/+internal/+github/+api/getLicenseHtmlUrl.m b/code/+matbox/+setup/+internal/+github/+api/getLicenseHtmlUrl.m index 209eff6..ea4219b 100644 --- a/code/+matbox/+setup/+internal/+github/+api/getLicenseHtmlUrl.m +++ b/code/+matbox/+setup/+internal/+github/+api/getLicenseHtmlUrl.m @@ -4,10 +4,10 @@ repositoryOwner (1,1) string end apiUrl = sprintf("https://api.github.com/repos/%s/%s/license", repositoryOwner, repositoryName); - + % Get web options with GitHub authentication if available options = matbox.setup.internal.github.api.getGithubWebOptions(); - + try data = webread(apiUrl, options); htmlUrl = data.download_url; diff --git a/code/+matbox/+setup/+internal/+github/+api/getOrganizationRepositories.m b/code/+matbox/+setup/+internal/+github/+api/getOrganizationRepositories.m index 6293bc3..109f33e 100644 --- a/code/+matbox/+setup/+internal/+github/+api/getOrganizationRepositories.m +++ b/code/+matbox/+setup/+internal/+github/+api/getOrganizationRepositories.m @@ -6,34 +6,34 @@ % % Outputs: % reposStruct - A struct array with fields 'name' and 'visibility'. - + arguments organizationName (1,1) string end % Get GITHUB_TOKEN from environment variables token = getenv('GITHUB_TOKEN'); - + if isempty(token) warning('GITHUB_TOKEN environment variable is not set. Retrieving public repositories'); end - + organizationName = char(organizationName); % GitHub API endpoint for organization repositories url = ['https://api.github.com/orgs/' organizationName '/repos']; - + % Get web options with GitHub authentication if available options = matbox.setup.internal.github.api.getGithubWebOptions(); options.Timeout = 15; options.ContentType = 'json'; - + % Fetch repositories information from GitHub data = webread(url, options); - + % Initialize an empty struct reposStruct = struct('name', {}, 'visibility', {}); - + % Parse the data for i = 1:numel(data) reposStruct(i).name = data(i).name; % Repository name diff --git a/code/+matbox/+setup/+internal/+github/getRequiredAdditionalSoftwareStructForToolboxOptions.m b/code/+matbox/+setup/+internal/+github/getRequiredAdditionalSoftwareStructForToolboxOptions.m index 4c82ae4..abbc887 100644 --- a/code/+matbox/+setup/+internal/+github/getRequiredAdditionalSoftwareStructForToolboxOptions.m +++ b/code/+matbox/+setup/+internal/+github/getRequiredAdditionalSoftwareStructForToolboxOptions.m @@ -10,7 +10,7 @@ % - Platform Platform to download the additional software package for, specified as "win64", "maci64", or "glnxa64" % - DownloadURL URL to download the additional software package, specified as a string scalar or character vector % - LicenseURL URL for the software package license file, specified as a string scalar or character vector - + arguments githubRepo (1,:) string end diff --git a/code/+matbox/+setup/+internal/+github/parseRepositoryURL.m b/code/+matbox/+setup/+internal/+github/parseRepositoryURL.m index 290ebe8..b09b8c0 100644 --- a/code/+matbox/+setup/+internal/+github/parseRepositoryURL.m +++ b/code/+matbox/+setup/+internal/+github/parseRepositoryURL.m @@ -1,15 +1,15 @@ function [owner, repositoryName, branchName] = parseRepositoryURL(repoUrl) % parseRepositoryURL - Extract owner, repository name and branch name from URL - + arguments repoUrl (1,1) matlab.net.URI end - + if repoUrl.Host ~= "github.com" error("MATBOX:GitHub:InvalidRepositoryURL", ... "Please make sure the repository URL's host name is 'github.com'") end - + pathNames = repoUrl.Path; pathNames( cellfun('isempty', pathNames) ) = []; diff --git a/code/+matbox/+setup/+internal/+github/readCommitHash.m b/code/+matbox/+setup/+internal/+github/readCommitHash.m index d43495d..717701a 100644 --- a/code/+matbox/+setup/+internal/+github/readCommitHash.m +++ b/code/+matbox/+setup/+internal/+github/readCommitHash.m @@ -2,12 +2,12 @@ % readCommitHash - Reads the commit hash from a specified repository folder % % Syntax: -% commitHash = readCommitHash(repositoryFolderPath) -% This function reads the commit hash from a file named '.commit_hash' +% commitHash = readCommitHash(repositoryFolderPath) +% This function reads the commit hash from a file named '.commit_hash' % located in the specified repository folder. % % Input Arguments: -% repositoryFolderPath - A string specifying the path to the repository +% repositoryFolderPath - A string specifying the path to the repository % folder from which the commit hash will be read. % % Output Arguments: diff --git a/code/+matbox/+setup/+internal/+github/writeCommitHash.m b/code/+matbox/+setup/+internal/+github/writeCommitHash.m index cd75575..f9d312d 100644 --- a/code/+matbox/+setup/+internal/+github/writeCommitHash.m +++ b/code/+matbox/+setup/+internal/+github/writeCommitHash.m @@ -1,5 +1,5 @@ function writeCommitHash(repositoryFolderPath, repositoryName, owner, branchName) -% writeCommitHash - Writes the current commit hash of a repository to file. +% writeCommitHash - Writes the current commit hash of a repository to file. % % Syntax: % writeCommitHash(repositoryFolderPath, repositoryName, owner, branchName) @@ -12,7 +12,7 @@ function writeCommitHash(repositoryFolderPath, repositoryName, owner, branchName % % See also: % matbox.setup.internal.github.api.getCurrentCommitID -% matbox.setup.internal.github.readCommitHash +% matbox.setup.internal.github.readCommitHash arguments repositoryFolderPath (1,1) string diff --git a/code/+matbox/+setup/+internal/+pathtool/lookForRepository.m b/code/+matbox/+setup/+internal/+pathtool/lookForRepository.m index 36b353c..9ab9c95 100644 --- a/code/+matbox/+setup/+internal/+pathtool/lookForRepository.m +++ b/code/+matbox/+setup/+internal/+pathtool/lookForRepository.m @@ -1,8 +1,8 @@ function [exists, repositoryPath] = lookForRepository(repositoryName, branchName) - + exists = false; repositoryPath = ""; - + % Get the full MATLAB search path: pathList = strsplit(path, pathsep); @@ -48,7 +48,7 @@ end end repositoryPath = string(repositoryPath); - + % Make sure folder exists if ~isempty(char(repositoryPath)) && ~isfolder(repositoryPath) warning("Repository was found on MATLAB's search path, but folder does not exist") @@ -57,7 +57,7 @@ end if repositoryPath == ""; return; end - + % Check if folder contains expected files... L = dir( repositoryPath ); assert(contains('README.md', {L.name}, 'IgnoreCase', true) && ... diff --git a/code/+matbox/+setup/+internal/+utility/filewrite.m b/code/+matbox/+setup/+internal/+utility/filewrite.m index 1b34b05..025a2a5 100644 --- a/code/+matbox/+setup/+internal/+utility/filewrite.m +++ b/code/+matbox/+setup/+internal/+utility/filewrite.m @@ -1,11 +1,11 @@ function filewrite(filePath, textStr) - + folderPath = fileparts(filePath); - + if ~exist(folderPath, 'dir') mkdir(folderPath) end - + fid = fopen(filePath, 'w'); fwrite(fid, textStr); fclose(fid); diff --git a/code/+matbox/+setup/+internal/addDependenciesToPath.m b/code/+matbox/+setup/+internal/addDependenciesToPath.m index 6f89927..bfb5ed0 100644 --- a/code/+matbox/+setup/+internal/addDependenciesToPath.m +++ b/code/+matbox/+setup/+internal/addDependenciesToPath.m @@ -4,7 +4,7 @@ function addDependenciesToPath(toolboxFolder, options) toolboxFolder (1,1) string {mustBeFolder} options.InstallationLocation (1,1) string = matbox.setup.internal.getDefaultAddonFolder() end - + reqs = matbox.setup.internal.getRequirements(toolboxFolder); for i = 1:numel(reqs) @@ -13,7 +13,7 @@ function addDependenciesToPath(toolboxFolder, options) % Todo. % [repoUrl, branchName] = parseGitHubUrl(reqs(i).URI); % matbox.setup.internal.installGithubRepository( repoUrl, branchName ) - + case 'FileExchange' [packageUuid, version] = matbox.setup.internal.fex.parseFileExchangeURI( reqs(i).URI ); [isInstalled, version] = matbox.setup.internal.fex.isToolboxInstalled(packageUuid, version); @@ -24,7 +24,7 @@ function addDependenciesToPath(toolboxFolder, options) continue end end - + % Add all addons in the package's addon folder to path addonLocation = options.InstallationLocation; addonListing = dir(addonLocation); @@ -39,7 +39,7 @@ function addDependenciesToPath(toolboxFolder, options) folderPath = fullfile(addonListing(i).folder, addonListing(i).name); startupFile = matbox.setup.internal.findStartupFile(folderPath); - + if ~isempty(startupFile) run( startupFile ) else diff --git a/code/+matbox/+setup/+internal/downloadZippedGithubRepo.m b/code/+matbox/+setup/+internal/downloadZippedGithubRepo.m index 1655d69..4655367 100644 --- a/code/+matbox/+setup/+internal/downloadZippedGithubRepo.m +++ b/code/+matbox/+setup/+internal/downloadZippedGithubRepo.m @@ -7,14 +7,14 @@ if isa(updateFlag, 'char') && strcmp(updateFlag, 'update') updateFlag = true; end - + % Create a temporary path for storing the downloaded file. [~, ~, fileType] = fileparts(githubUrl); tempFilepath = [tempname, fileType]; - + % Get web options with GitHub authentication if available options = matbox.setup.internal.github.api.getGithubWebOptions(); - + % Download the file containing the addon toolbox try tempFilepath = websave(tempFilepath, githubUrl, options); @@ -32,12 +32,12 @@ if endsWith(unzippedFolder, filesep) unzippedFolder = unzippedFolder(1:end-1); end - + [~, repoFolderName] = fileparts(unzippedFolder); targetFolder = fullfile(targetFolder, repoFolderName); if updateFlag && isfolder(targetFolder) - + % Delete current version if isfolder(targetFolder) if contains(path, fullfile(targetFolder, filesep)) @@ -56,7 +56,7 @@ end movefile(unzippedFolder, targetFolder); - + % Delete the temp zip file clear fileCleanupObj diff --git a/code/+matbox/+setup/+internal/findSetupFile.m b/code/+matbox/+setup/+internal/findSetupFile.m index 2d3d72e..07fc9c9 100644 --- a/code/+matbox/+setup/+internal/findSetupFile.m +++ b/code/+matbox/+setup/+internal/findSetupFile.m @@ -8,7 +8,7 @@ if ~isfolder(folderPath) error('Provided folder does not exist') end - + L = [ dir(fullfile(folderPath, 'setup.m')), ... dir(fullfile(folderPath, '*', 'setup.m')) ]; diff --git a/code/+matbox/+setup/+internal/findStartupFile.m b/code/+matbox/+setup/+internal/findStartupFile.m index 556e1e2..8a08f76 100644 --- a/code/+matbox/+setup/+internal/findStartupFile.m +++ b/code/+matbox/+setup/+internal/findStartupFile.m @@ -8,7 +8,7 @@ if ~isfolder(folderPath) error('Provided folder does not exist') end - + L = [ dir(fullfile(folderPath, 'startup.m')), ... dir(fullfile(folderPath, '*', 'startup.m')) ]; diff --git a/code/+matbox/+setup/+internal/getRequirements.m b/code/+matbox/+setup/+internal/getRequirements.m index 853459c..8c716f6 100644 --- a/code/+matbox/+setup/+internal/getRequirements.m +++ b/code/+matbox/+setup/+internal/getRequirements.m @@ -5,13 +5,13 @@ % returns a struct array where each element represents a % requirement/dependency. This function assumes a requirements.txt % file is present in the provided packageRootDirectorys - + arguments packageRootDirectory (1,1) string end requirementsFilePath = fullfile(packageRootDirectory, 'requirements.txt'); - + if ~isfile(requirementsFilePath) error("MatBox:Setup:RequirementsFileNotFound", ... 'No requirements file was found in the given toolbox folder') @@ -22,7 +22,7 @@ isEmpty = cellfun('isempty', requirements); requirements(isEmpty) = []; - + isComment = cellfun(@(str) startsWith(str, "#"), requirements); requirements(isComment) = []; @@ -34,7 +34,7 @@ parsedRequirements = struct; for i = 1:numel(requirements) - + if startsWith(requirements{i}, "fex://") type = 'FileExchange'; elseif startsWith(requirements{i}, "https://github.com") @@ -43,7 +43,7 @@ type = 'Unknown'; warning('Unsupported requirement specification: %s', requirements{i}) end - + parsedRequirements(i).Type = type; parsedRequirements(i).URI = string(requirements{i}); end diff --git a/code/+matbox/+setup/+internal/installFexPackage.m b/code/+matbox/+setup/+internal/installFexPackage.m index 356f643..cf16696 100644 --- a/code/+matbox/+setup/+internal/installFexPackage.m +++ b/code/+matbox/+setup/+internal/installFexPackage.m @@ -46,10 +46,10 @@ else versionStr = options.Version; end - + % Get download url for addon / package addonUrl = fex.getAddonURL(toolboxIdentifier, versionStr); - + if endsWith(addonUrl, '.xml') % Todo: Install in MATLAB's Addon folder @@ -75,7 +75,7 @@ toolboxName = options.Name; end end - + if options.Verbose if ismissing(toolboxName) fprintf('Please wait, installing ""...') @@ -125,7 +125,7 @@ function toolboxName = retrieveToolboxName(toolboxIdentifier) fex = matlab.addons.repositories.FileExchangeRepository(); - + try additionalInfoUrl = fex.getAddonDetailsURL(toolboxIdentifier); addonHtmlInfo = webread(additionalInfoUrl); diff --git a/code/+matbox/+setup/+internal/installGithubRepository.m b/code/+matbox/+setup/+internal/installGithubRepository.m index 7a1a6da..2ab763e 100644 --- a/code/+matbox/+setup/+internal/installGithubRepository.m +++ b/code/+matbox/+setup/+internal/installGithubRepository.m @@ -26,19 +26,19 @@ [ownerName, repositoryName] = ... matbox.setup.internal.github.parseRepositoryURL(repositoryUrl); - + if ismissing(branchName) % - Get default branchname branchName = matbox.setup.internal.github.api.getDefaultBranch(... ownerName, repositoryName); end - + [repoExists, repoFolderLocation] = ... matbox.setup.internal.pathtool.lookForRepository(repositoryName, branchName); if repoExists isUpdateNeeded = options.Update; repoTargetFolder = repoFolderLocation; - + if options.Update % Handle repository update if isGitRepository(repoFolderLocation) wasSuccess = gitPull(repoFolderLocation); @@ -125,7 +125,7 @@ function wasSuccess = gitPull(folderPath) % gitPull - Try to do a repository pull using git wasSuccess = false; - + % Try to use git commands to update the repository try if exist("gitrepo", "file") @@ -136,13 +136,13 @@ currentDir = pwd; cd(folderPath); workDirCleanup = onCleanup(@() cd(currentDir)); - + % Try to use git pull to update the repository [status, cmdout] = system('git pull'); - + % Return to original directory clear workDirCleanup - + if status == 0 wasSuccess = true; else @@ -152,7 +152,7 @@ catch ME warning(ME.identifier, 'Git pull failed with message: %s.', ME.message); end - + if wasSuccess % Run setup if present after update setupFile = matbox.setup.internal.findSetupFile(folderPath); @@ -165,7 +165,7 @@ function needsUpdate = checkCommitHash(repoFolderLocation, repoName, ... ownerName, branchName, repositoryUrl, options) % checkCommitHash - Check if the local commit hash matches remote commit hash - + arguments repoFolderLocation (1,1) string repoName (1,1) string @@ -174,21 +174,21 @@ repositoryUrl (1,1) string options.Verbose (1,1) logical = true end - + needsUpdate = false; % Check if commit hash has changed before updating try % Read the stored commit hash storedCommitHash = matbox.setup.internal.github.readCommitHash(repoFolderLocation); - + % Get the current commit hash from GitHub API currentCommitHash = ... matbox.setup.internal.github.api.getCurrentCommitID(... repoName, ... 'Owner', ownerName, ... 'BranchName', branchName); - + % Only update if commit hashes are different if strcmp(storedCommitHash, currentCommitHash) if options.Verbose diff --git a/code/+matbox/+tasks/codecheckToolbox.m b/code/+matbox/+tasks/codecheckToolbox.m index 0b37b30..4432490 100644 --- a/code/+matbox/+tasks/codecheckToolbox.m +++ b/code/+matbox/+tasks/codecheckToolbox.m @@ -13,13 +13,13 @@ filesToCheck = matbox.tasks.internal.resolveFiles(projectRootDir, ... options.FoldersToCheck, options.FilesToCheck); - + if isempty(filesToCheck) error("MatBox:CodeIssues", "No files to check.") end issueCount = struct; - + if verLessThan('matlab','9.13') %#ok % Use the old check code before R2022b issues = checkcode(filesToCheck); @@ -86,7 +86,7 @@ function createCodeIssuesBadge(issueCount, projectRootDir) if issueCount.Error > 0 color = "red"; end - + matbox.utility.createBadgeSvg("code issues", ... string(issueCount.Total), color, projectRootDir) end diff --git a/code/+matbox/+tasks/codespellToolbox.m b/code/+matbox/+tasks/codespellToolbox.m index fa6be55..537ab4d 100644 --- a/code/+matbox/+tasks/codespellToolbox.m +++ b/code/+matbox/+tasks/codespellToolbox.m @@ -14,7 +14,7 @@ function codespellToolbox(codeFolder, options) options.RequireCodespellPassing (1,1) logical = false options.SaveResults (1,1) logical = false; end - + if ~strcmp(codeFolder, pwd) currentDir = pwd(); cleanupObj = onCleanup( @(pathName) cd(currentDir)); @@ -22,9 +22,9 @@ function codespellToolbox(codeFolder, options) end options.Skip = [options.Skip, "*words.txt"]; - + commandStr = options.CodeSpellExecutable; - + if options.DoAutomaticFix commandStr = sprintf("%s --write-changes", commandStr); end @@ -50,7 +50,7 @@ function codespellToolbox(codeFolder, options) [s, m] = system(commandStr); codespellPassing = ~s; - + if options.DoAutomaticFix return end @@ -81,11 +81,11 @@ function codespellToolbox(codeFolder, options) for i = 1:numel(lines) splitLine = split(lines{i}, ':'); - + % Clean filepath: relativeFilePath = splitLine{1}(2:end); filePath = fullfile(codeFolder, relativeFilePath); - + fullName = omni.matlab.meta.abspath2funcname(strtrim(filePath)); lineNumber = str2double(splitLine{2}); @@ -104,7 +104,7 @@ function codespellToolbox(codeFolder, options) S(i).Ignore = createIgnoreLink(S(i).Word, options.ConfigFilePath); end end - + if options.SaveResults fid = fopen('words.txt', 'w'); fwrite(fid, strjoin(typos, newline)); @@ -114,7 +114,7 @@ function codespellToolbox(codeFolder, options) T = sortrows(T, "Auto"); disp( T ) end - + if options.RequireCodespellPassing message = sprintf( "Codespell identified the following potential spelling mistakes:\n%s", ... strjoin( " " + typos, newline)); diff --git a/code/+matbox/+tasks/createTestedWithBadgeforToolbox.m b/code/+matbox/+tasks/createTestedWithBadgeforToolbox.m index 0b8c88d..d812a9c 100644 --- a/code/+matbox/+tasks/createTestedWithBadgeforToolbox.m +++ b/code/+matbox/+tasks/createTestedWithBadgeforToolbox.m @@ -3,12 +3,12 @@ function createTestedWithBadgeforToolbox(versionNumber, projectRootDirectory) % multiple MATLAB releases, and generate the "Tested with" badge % % Adapted from: https://github.com/mathworks/climatedatastore/tree/main/buildUtilities - + arguments versionNumber (1,1) string projectRootDirectory (1,1) string {mustBeFolder} end - + releasesTestedWith = ""; releasesFailed = 0; @@ -19,7 +19,7 @@ function createTestedWithBadgeforToolbox(versionNumber, projectRootDirectory) assert( ~isempty(testResultsListing), ... 'MATBOX:BadgeCreation:NoTestResultsFound', ... 'No test results were found\n' ) - + testResultFolders = string({testResultsListing.folder}); releaseNames = getReleaseNamesFromFolderPaths(testResultFolders); @@ -35,15 +35,15 @@ function createTestedWithBadgeforToolbox(versionNumber, projectRootDirectory) testResultFiles = string(... fullfile({testResultsListing.folder}, {testResultsListing.name}) ... ); - + % Go through the directories and check if tests passed for i = 1:numel(testResultFiles) releaseName = releaseNames(i); currentFile = testResultFiles(i); - + % Read the test results file testResults = readstruct(currentFile); - + % If no tests failed, errors, or were skipped, then add it to the list if sum([testResults.testsuite.errorsAttribute]) == 0 ... && sum([testResults.testsuite.failuresAttribute]) == 0 ... diff --git a/code/+matbox/+tasks/installSetupTools.m b/code/+matbox/+tasks/installSetupTools.m index f5182d7..9009773 100644 --- a/code/+matbox/+tasks/installSetupTools.m +++ b/code/+matbox/+tasks/installSetupTools.m @@ -4,16 +4,16 @@ function installSetupTools() if exist('+setuptools/installRequirements.m', 'file') == 2 return end - + % Download setuptools url = "https://github.com/ehennestad/setuptools-matlab/archive/refs/heads/main.zip"; tempZipPath = websave(tempname, url); cleanupObj = onCleanup(@(fp) delete(tempZipPath)); - + % Add setuptools to MATLAB's search path installDirectory = fullfile(userpath, 'MATLAB-AddOns'); if ~isfolder(installDirectory);mkdir(installDirectory); end - + unzippedFiles = unzip(tempZipPath, installDirectory); addpath(genpath(unzippedFiles{1})) end diff --git a/code/+matbox/+tasks/testToolbox.m b/code/+matbox/+tasks/testToolbox.m index 45e54d3..9862e08 100644 --- a/code/+matbox/+tasks/testToolbox.m +++ b/code/+matbox/+tasks/testToolbox.m @@ -15,7 +15,7 @@ function testToolbox(projectRootDirectory, options) options.HasTag (1,1) string = "" options.ExcludeTags (1,:) string = string.empty end - + import matlab.unittest.TestSuite; import matlab.unittest.TestRunner; import matlab.unittest.plugins.CodeCoveragePlugin; @@ -23,13 +23,12 @@ function testToolbox(projectRootDirectory, options) import matlab.unittest.plugins.codecoverage.CoverageReport; import matlab.unittest.plugins.codecoverage.CoberturaFormat; import matlab.unittest.selectors.HasTag; - - - testFolder = fullfile(projectRootDirectory, options.TestsFolderName); + + testFolder = fullfile(projectRootDirectory, options.TestsFolderName); codeFolder = fullfile(projectRootDirectory, options.SourceFolderName); oldpath = addpath(genpath(testFolder), genpath(codeFolder)); finalize = onCleanup(@()(path(oldpath))); - + % Run startup function if it exists if isfile( fullfile(codeFolder, 'startup.m') ) run( fullfile(codeFolder, 'startup.m') ) @@ -41,7 +40,7 @@ function testToolbox(projectRootDirectory, options) end suite = TestSuite.fromFolder( testFolder, "IncludingSubfolders", true ); - + if isMATLABReleaseOlderThan('R2022a') % fromFolder did not include packages % List packages and add suites by package names packageListing = dir(fullfile(testFolder, '+*')); @@ -74,7 +73,7 @@ function testToolbox(projectRootDirectory, options) runner = TestRunner.withTextOutput('Verbosity', options.Verbosity); codecoverageFileName = fullfile(outputDirectory, "codecoverage.xml"); - + if ~isempty(options.CoverageFileList) codecoverageFileList = options.CoverageFileList; if ~ismissing(options.CoverageRootFolder) @@ -89,8 +88,7 @@ function testToolbox(projectRootDirectory, options) end codecoverageFileList = fullfile({mfileListing.folder}, {mfileListing.name}); end - - + codeCoverageFormats = [CoberturaFormat(codecoverageFileName)]; if options.HtmlReports htmlReport = CoverageReport(outputDirectory, 'MainFile', "codecoverage.html"); @@ -98,8 +96,7 @@ function testToolbox(projectRootDirectory, options) end runner.addPlugin(XMLPlugin.producingJUnitFormat(fullfile(outputDirectory,'test-results.xml'))); runner.addPlugin(CodeCoveragePlugin.forFile(codecoverageFileList, 'Producing', codeCoverageFormats)); - - + results = runner.run(suite); if ~verLessThan('matlab','9.9') && ~isMATLABReleaseOlderThan("R2022a") %#ok @@ -110,7 +107,7 @@ function testToolbox(projectRootDirectory, options) if options.CreateBadge createTestResultBadge(results, projectRootDirectory) % local function end - + displayTestResultSummary(results) results.assertSuccess(); @@ -120,7 +117,7 @@ function createTestResultBadge(results, projectRootDirectory) numTests = numel(results); numPassedTests = sum([results.Passed]); numFailedTests = sum([results.Failed]); - + % Generate the JSON files for the shields in the readme.md if numFailedTests == 0 color = "green"; diff --git a/code/+matbox/+tasks/verifyToolboxInstallation.m b/code/+matbox/+tasks/verifyToolboxInstallation.m index 5d8f950..6073057 100644 --- a/code/+matbox/+tasks/verifyToolboxInstallation.m +++ b/code/+matbox/+tasks/verifyToolboxInstallation.m @@ -8,7 +8,7 @@ function verifyToolboxInstallation(mltbxFile) fprintf('Installing toolbox: %s\n', mltbxFile); agreeToLicense = true; installedToolbox = matlab.addons.install(mltbxFile, agreeToLicense); - + % Verify installation fprintf('Toolbox installed successfully:\n'); fprintf(' Name: %s\n', installedToolbox.Name); diff --git a/code/+matbox/+toolbox/+internal/fixRequiredAdditionalSoftware.m b/code/+matbox/+toolbox/+internal/fixRequiredAdditionalSoftware.m index 08fbe04..d7bf0be 100644 --- a/code/+matbox/+toolbox/+internal/fixRequiredAdditionalSoftware.m +++ b/code/+matbox/+toolbox/+internal/fixRequiredAdditionalSoftware.m @@ -34,7 +34,7 @@ function fixRequiredAdditionalSoftware(initialToolboxFilePath, finalToolboxFileP filePath = fullfile(L(i).folder, L(i).name); targetFilename = strrep(L(i).name, 'maci64', 'common'); copyfile(filePath, targetFilename); - + mlAddonAddInstructionSet(char(finalToolboxFilePath), targetFilename) end end diff --git a/code/+matbox/+toolbox/+internal/resolvePathFolders.m b/code/+matbox/+toolbox/+internal/resolvePathFolders.m index 8143b19..60a71d1 100644 --- a/code/+matbox/+toolbox/+internal/resolvePathFolders.m +++ b/code/+matbox/+toolbox/+internal/resolvePathFolders.m @@ -39,7 +39,7 @@ options.SourceFolderName (1,1) string = "src" options.PathFolders (1,:) string = string.empty end - + if isempty(options.PathFolders) toolboxCodeFolder = fullfile(projectRootDirectory, options.SourceFolderName); toolboxPathFolders = string( strsplit(genpath(toolboxCodeFolder), pathsep)); diff --git a/code/+matbox/+toolbox/createToolboxOptions.m b/code/+matbox/+toolbox/createToolboxOptions.m index d95e013..204ae84 100644 --- a/code/+matbox/+toolbox/createToolboxOptions.m +++ b/code/+matbox/+toolbox/createToolboxOptions.m @@ -15,7 +15,7 @@ % Read the toolbox info from MLToolboxInfo.json [toolboxInfo, identifier] = matbox.toolbox.readToolboxInfo(projectRootDirectory); - + % Resolve folders to add to path for toolbox. This needs to be done % before creating the ToolboxOptions object due to a bug in that class % (See matbox.toolbox.internal.resolvePathFolders for more info) @@ -33,7 +33,7 @@ % Initialize the ToolboxOptions from the code folder and initial metadata toolboxFolder = fullfile(projectRootDirectory, options.SourceFolderName); opts = matlab.addons.toolbox.ToolboxOptions(toolboxFolder, identifier, toolboxInfo); - + % Set the toolbox version opts.ToolboxVersion = versionNumber; @@ -52,7 +52,7 @@ opts.SupportedPlatforms.Maci64 = true; opts.SupportedPlatforms.Glnxa64 = true; opts.SupportedPlatforms.MatlabOnline = true; - + % Populate required addons from requirements file try requirements = matbox.setup.internal.getRequirements(projectRootDirectory); @@ -76,7 +76,7 @@ end function opts = addRequirementsToToolboxOptions(opts, requirements) - % Add GitHub repository requirements as Additional Software + % Add GitHub repository requirements as Additional Software isGithubRequirement = strcmp({requirements.Type}, 'GitHub'); opts.RequiredAdditionalSoftware = ... matbox.setup.internal.github.getRequiredAdditionalSoftwareStructForToolboxOptions( {requirements(isGithubRequirement).URI} ); diff --git a/code/+matbox/+toolbox/readToolboxInfo.m b/code/+matbox/+toolbox/readToolboxInfo.m index e708f4c..0c93961 100644 --- a/code/+matbox/+toolbox/readToolboxInfo.m +++ b/code/+matbox/+toolbox/readToolboxInfo.m @@ -12,7 +12,7 @@ if isempty(fileListing) error('MatBox:ToolboxInfoFileNotFound', ... 'The file "MLToolboxInfo.json" could not be found in the specified project root directory.'); - + elseif numel(fileListing) > 1 error('MatBox:MultipleToolboxInfoFilesFound', ... 'Multiple instances of "MLToolboxInfo.json" were found in the project root directory. Please ensure there is only one file.'); @@ -22,7 +22,7 @@ toolboxInfoFilePath = fullfile(fileListing.folder, fileListing.name); toolboxInfo = jsondecode(fileread(toolboxInfoFilePath)); toolboxOptions = toolboxInfo.ToolboxOptions; - + % Expand path names by prepending project root directory pathOptions = ["ToolboxImageFile", "ToolboxGettingStartedGuide"]; for iPathOption = 1:numel(pathOptions) diff --git a/code/+matbox/+utility/createBadgeSvg.m b/code/+matbox/+utility/createBadgeSvg.m index 2f5efa0..82e0aa5 100644 --- a/code/+matbox/+utility/createBadgeSvg.m +++ b/code/+matbox/+utility/createBadgeSvg.m @@ -1,5 +1,5 @@ function createBadgeSvg(label, message, color, projectRootDirectory, options) - + arguments label (1,1) string message (1,1) string @@ -37,7 +37,7 @@ function createBadgeSvg(label, message, color, projectRootDirectory, options) filePath = fullfile(options.OutputFolder, name + ".svg"); fid = fopen(filePath, "wt"); fileCleanup = onCleanup(@() fclose(fid)); - + fwrite(fid, char(badgeSvg)); fprintf('Saved badge to %s\n', filePath) end diff --git a/code/+matbox/+utility/filewrite.m b/code/+matbox/+utility/filewrite.m index 04c9776..62a08b5 100644 --- a/code/+matbox/+utility/filewrite.m +++ b/code/+matbox/+utility/filewrite.m @@ -1,7 +1,7 @@ function filewrite(fileName, textStr) folderPath = fileparts(fileName); - + if ~isempty(folderPath) && ~exist(folderPath, 'dir') mkdir(folderPath) end diff --git a/code/+matbox/+utility/getLatestMatlabReleaseForGitHubActions.m b/code/+matbox/+utility/getLatestMatlabReleaseForGitHubActions.m index 2b52548..09c7cb8 100644 --- a/code/+matbox/+utility/getLatestMatlabReleaseForGitHubActions.m +++ b/code/+matbox/+utility/getLatestMatlabReleaseForGitHubActions.m @@ -5,7 +5,7 @@ % versionStr = matbox.utility.getLatestMatlabReleaseForGitHubActions() % % Input Arguments: -% includePrerelease - A boolean flag indicating whether to include +% includePrerelease - A boolean flag indicating whether to include % pre-release versions in the result. % % Output Arguments: @@ -14,9 +14,9 @@ arguments includePrerelease (1,1) logical = false end - + apiUrl = "https://ssd.mathworks.com/supportfiles/ci/matlab-release/v0/latest"; - + if includePrerelease apiUrl = apiUrl + "-including-prerelease"; end diff --git a/code/+matbox/+utility/getVersionFromContents.m b/code/+matbox/+utility/getVersionFromContents.m index baf4d63..ca5e7dd 100644 --- a/code/+matbox/+utility/getVersionFromContents.m +++ b/code/+matbox/+utility/getVersionFromContents.m @@ -8,7 +8,7 @@ % Update Contents.m contentsFilePath = fullfile(toolboxFolder, 'Contents.m'); contentsStr = fileread(contentsFilePath); - + % First try to get a version with a sub-patch version number versionStr = regexp(contentsStr, '(?<=Version )\d+\.\d+\.\d+.\d+(?= )', 'match', 'once'); @@ -16,7 +16,7 @@ if isempty(versionStr) versionStr = regexp(contentsStr, '(?<=Version )\d+\.\d+\.\d+(?= )', 'match', 'once'); end - + if isempty(versionStr) error('BUILDTOOLS:Version:VersionNotFound', ... 'No version was detected in the Contents file for this toolbox.') diff --git a/code/+matbox/+utility/updateContentsHeader.m b/code/+matbox/+utility/updateContentsHeader.m index 2fe28b7..fd99316 100644 --- a/code/+matbox/+utility/updateContentsHeader.m +++ b/code/+matbox/+utility/updateContentsHeader.m @@ -8,7 +8,7 @@ function updateContentsHeader(toolboxFolder, contentsHeader) contentsFilePath = fullfile(toolboxFolder, 'Contents.m'); if isfile(contentsFilePath) contentsStr = fileread(contentsFilePath); - + % Assume header is 5 lines contentsStrLines = strsplit(contentsStr, newline); contentsStrLines(1:5) = cellstr(strsplit(contentsHeader, newline)); diff --git a/code/+matbox/+utility/updateVersionNumber.m b/code/+matbox/+utility/updateVersionNumber.m index b97988b..3c5dc34 100644 --- a/code/+matbox/+utility/updateVersionNumber.m +++ b/code/+matbox/+utility/updateVersionNumber.m @@ -2,7 +2,7 @@ % updateVersionNumber - Utility function to update a version number % % Adapted from: https://github.com/mathworks/climatedatastore/blob/main/buildUtilities/packageToolbox.m - + arguments previousVersion string {mustBeTextScalar} = ""; releaseType {mustBeTextScalar,mustBeMember(releaseType,["build","major","minor","patch","specific"])} = "build" @@ -21,7 +21,7 @@ if numel(versionParts) == 3 versionParts(4) = "0"; end - + switch lower(releaseType) case "major" versionParts(1) = string(str2double(versionParts(1)) + 1); diff --git a/code/+matbox/+utility/writeBadgeJSONFile.m b/code/+matbox/+utility/writeBadgeJSONFile.m index 76e552e..772106c 100644 --- a/code/+matbox/+utility/writeBadgeJSONFile.m +++ b/code/+matbox/+utility/writeBadgeJSONFile.m @@ -62,7 +62,7 @@ function writeBadgeJSONFile(label, message, color, projectRootDirectory, options badgeInfo.message = message; badgeInfo.color = color; badgeJSON = jsonencode(badgeInfo); - + if ismissing(options.FileName) name = strrep(label, " ", "_"); else diff --git a/code/+matbox/VersionNumber.m b/code/+matbox/VersionNumber.m index 80a278c..330531d 100644 --- a/code/+matbox/VersionNumber.m +++ b/code/+matbox/VersionNumber.m @@ -18,7 +18,7 @@ methods % Constructor function obj = VersionNumber(versionSpecification, options) - + arguments (Repeating) versionSpecification end @@ -34,7 +34,7 @@ if isscalar(versionSpecification) && iscell(versionSpecification{1}) versionSpecification = versionSpecification{1}; end - + if numel(versionSpecification) > 1 obj(numel(versionSpecification)) = 1; end @@ -64,7 +64,7 @@ [obj.IsLatest] = options.IsLatest; end end - + % Set version function setVersion(obj, versionAsArray) @@ -96,7 +96,7 @@ function fromString(obj, versionStr) assert( isequal(versionStr, strjoin(string(num2str(parts)), '.')), ... 'Not a valid version specification %s', versionStr) - + if length(parts) >= 1 obj.Major = parts(1); end @@ -112,7 +112,7 @@ function fromString(obj, versionStr) obj.Build = parts(4); end end - + % toString method for custom string format function str = string(obj) str = repmat("", size(obj)); @@ -130,7 +130,7 @@ function fromString(obj, versionStr) function result = isEqualTo(obj, other) result = (obj.Major == other.Major) && (obj.Minor == other.Minor) && (obj.Patch == other.Patch) && (obj.Build == other.Build); end - + % Bumping version methods function bumpMajor(obj) obj.Major = obj.Major + 1; @@ -138,25 +138,25 @@ function bumpMajor(obj) obj.Patch = 0; obj.Build = 0; end - + function bumpMinor(obj) obj.Minor = obj.Minor + 1; obj.Patch = 0; obj.Build = 0; end - + function bumpPatch(obj) obj.Patch = obj.Patch + 1; obj.Build = 0; end - + function bumpBuild(obj) obj.Build = obj.Build + 1; end end methods - + % Greater than or equal (>=) function result = ge(obj, other) arguments @@ -169,7 +169,7 @@ function bumpBuild(obj) (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch > other.Patch) || ... (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch == other.Patch && obj.Build >= other.Build); end - + % Greater than (>) function result = gt(obj, other) arguments @@ -181,7 +181,7 @@ function bumpBuild(obj) (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch > other.Patch) || ... (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch == other.Patch && obj.Build > other.Build); end - + % Less than or equal (<=) function result = le(obj, other) arguments @@ -193,7 +193,7 @@ function bumpBuild(obj) (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch < other.Patch) || ... (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch == other.Patch && obj.Build <= other.Build); end - + % Less than (<) function result = lt(obj, other) arguments @@ -206,7 +206,7 @@ function bumpBuild(obj) (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch < other.Patch) || ... (obj.Major == other.Major && obj.Minor == other.Minor && obj.Patch == other.Patch && obj.Build < other.Build); end - + % Equal (==) function result = eq(obj, other) arguments @@ -217,13 +217,13 @@ function bumpBuild(obj) if obj.IsLatest && other.IsLatest result = true; return end - + result = (obj.Major == other.Major) && ... (obj.Minor == other.Minor) && ... (obj.Patch == other.Patch) && ... (obj.Build == other.Build); end - + % Not equal (~=) function result = ne(obj, other) arguments @@ -300,7 +300,7 @@ function validateVersion(versionRef, validVersions) end validVersions = [validVersions{:}]; - + isValid = arrayfun(@(v) versionRef == v, validVersions); if ~any(isValid) [validVersions(:).Format] = deal( versionRef.Format ); diff --git a/code/+matbox/addStartupToMainStartup.m b/code/+matbox/addStartupToMainStartup.m index 5de1782..f076ef1 100644 --- a/code/+matbox/addStartupToMainStartup.m +++ b/code/+matbox/addStartupToMainStartup.m @@ -2,25 +2,25 @@ function addStartupToMainStartup(toolboxFolder) % addStartupToMainStartup - Add startup from toolbox folder to main startup file % % Syntax: -% matbox.addStartupToMainStartup(toolboxFolder) adds a toolbox' startup.m in +% matbox.addStartupToMainStartup(toolboxFolder) adds a toolbox' startup.m in % a run statement to the user's main startup file. % % Details: -% This function locates the toolbox’s startup file and then adds a run -% statement to the user's main startup file. For a startup file that is a -% function, the run statement is inserted into the function body (before the -% final end). For a script file (which may include local functions), the run +% This function locates the toolbox’s startup file and then adds a run +% statement to the user's main startup file. For a startup file that is a +% function, the run statement is inserted into the function body (before the +% final end). For a script file (which may include local functions), the run % statement is inserted before the first local function definition. % % Caveats: -% Cases not explicitly handled include files that do not follow the -% conventional structure (for example, files that are empty or contain +% Cases not explicitly handled include files that do not follow the +% conventional structure (for example, files that are empty or contain % misleading comments) or if the run statement appears in a commented‐out form. - + arguments toolboxFolder (1,1) string {mustBeFolder} end - + startupFilePath = matbox.setup.internal.findStartupFile(toolboxFolder); if isempty(startupFilePath) warning('No startup file was found in the given directory:\n%s', toolboxFolder) @@ -38,7 +38,7 @@ function addStartupToMainStartup(toolboxFolder) % Only update if the startupFilePath is not already mentioned. if ~contains(fileContent, startupFilePath) - + lines = splitlines(fileContent); % Determine insertion point for the run statement. % Find the first non-empty, non-comment line. @@ -84,7 +84,7 @@ function addStartupToMainStartup(toolboxFolder) indentStr = ""; end runStatement = indentStr + sprintf("run('%s')", startupFilePath); - + % Adjust newlines if statement is added at the end of the file. if insertIdx == numel(lines) if ~endsWith(fileContent, newline) diff --git a/code/+matbox/installRequirements.m b/code/+matbox/installRequirements.m index 51181a2..603b5e7 100644 --- a/code/+matbox/installRequirements.m +++ b/code/+matbox/installRequirements.m @@ -6,27 +6,27 @@ function installRequirements(toolboxFolder, mode, options) arguments (Repeating) mode string {mustBeMember(mode, ["force", "f", "update", "u"])} end - + arguments - %options.UseDefaultInstallationLocation (1,1) logical = true % Tentative, not implemented yet! + % options.UseDefaultInstallationLocation (1,1) logical = true % Tentative, not implemented yet! options.UpdateSearchPath (1,1) logical = true options.SaveSearchPath (1,1) logical = true options.InstallationLocation (1,1) string = matbox.setup.internal.getDefaultAddonFolder() options.Verbose (1,1) logical = true options.AgreeToLicenses (1,1) logical = false end - + % Parse mode/flags mode = string(mode); doUpdate = any(strcmp(mode, 'update')) || any( strcmp(mode, 'u') ); - + installationLocation = options.InstallationLocation; if ~isfolder(installationLocation); mkdir(installationLocation); end - + reqs = matbox.setup.internal.getRequirements(toolboxFolder); for i = 1:numel(reqs) switch reqs(i).Type - + case 'GitHub' [repoUrl, branchName] = parseGitHubUrl(reqs(i).URI); matbox.setup.internal.installGithubRepository( ... @@ -66,7 +66,7 @@ function installRequirements(toolboxFolder, mode, options) version = "latest"; % Initialize default value FEX_API_URL = "https://addons.mathworks.com/registry/v1/"; - + splitUri = strsplit(uri, '/'); packageNumber = regexp(splitUri{2}, '\d*(?=-)', 'match', 'once'); diff --git a/code/+matbox/runStartup.m b/code/+matbox/runStartup.m index 0bb6b3d..ace67d3 100644 --- a/code/+matbox/runStartup.m +++ b/code/+matbox/runStartup.m @@ -3,7 +3,7 @@ function runStartup(toolboxFolder) arguments toolboxFolder (1,1) string {mustBeFolder} end - + startupFilePath = matbox.setup.internal.findStartupFile(toolboxFolder); if ~isempty(startupFilePath) run(startupFilePath) diff --git a/code/+matbox/toolboxversion.m b/code/+matbox/toolboxversion.m index 93712f5..459f549 100644 --- a/code/+matbox/toolboxversion.m +++ b/code/+matbox/toolboxversion.m @@ -7,9 +7,9 @@ if ~isfile(contentsFile) error("Toolbox does not have a Contents.m file") end - + fileStr = fileread(contentsFile); - + % First try to get a version with a sub-patch version number matchedStr = regexp(fileStr, 'Version \d*\.\d*\.\d*.\d*(?= )', 'match'); diff --git a/code/templates/setup.m b/code/templates/setup.m index da5c44d..71478bf 100644 --- a/code/templates/setup.m +++ b/code/templates/setup.m @@ -2,7 +2,7 @@ function setup(mode, options) % setup - Setup/install a MATLAB package % Note: should be placed in the root level of the repository or adapted if located in another directory - + arguments (Repeating) mode (1,1) string {mustBeMember(mode, ["savepath", "s"])}; end @@ -26,7 +26,7 @@ function setup(mode, options) % Assumes setup.m is located in root repository folder rootPath = fileparts(mfilename('fullpath')); addpath(genpath(fullfile(rootPath, 'code'))) - + if options.SavePathDef savepath() end diff --git a/tools/tests/+matboxtools/+unittest/BasicTest.m b/tools/tests/+matboxtools/+unittest/BasicTest.m index 430b78c..f60f8b2 100644 --- a/tools/tests/+matboxtools/+unittest/BasicTest.m +++ b/tools/tests/+matboxtools/+unittest/BasicTest.m @@ -18,7 +18,7 @@ function setupMethod(testCase) % Pass. No method setup routines needed end end - + methods (Test) function testToolboxDir(testCase) pathStr = matbox.toolboxdir(); diff --git a/tools/tests/+matboxtools/+unittest/PyNamespaceTest.m b/tools/tests/+matboxtools/+unittest/PyNamespaceTest.m index 8044db7..711da33 100644 --- a/tools/tests/+matboxtools/+unittest/PyNamespaceTest.m +++ b/tools/tests/+matboxtools/+unittest/PyNamespaceTest.m @@ -15,7 +15,7 @@ function setupClass(testCase) %#ok<*MANU> function setupMethod(testCase) end end - + methods (Test) function testPipUninstall(testCase) diff --git a/tools/tests/+matboxtools/+unittest/SetupTest.m b/tools/tests/+matboxtools/+unittest/SetupTest.m index bb48dd4..36a5e97 100644 --- a/tools/tests/+matboxtools/+unittest/SetupTest.m +++ b/tools/tests/+matboxtools/+unittest/SetupTest.m @@ -13,7 +13,7 @@ function setupMethod(testCase) testCase.applyFixture(WorkingFolderFixture) end end - + methods (Test) function testInstallRequirements(testCase) testCase.installRequirements() @@ -28,7 +28,7 @@ function testUpdateGitRequirement(testCase) end function testUpdateGitRequirementWithGit(testCase) - + system('git clone "https://github.com/ehennestad/StructEditor"') addpath("StructEditor") @@ -44,7 +44,7 @@ function installRequirements(testCase, options) testCase options.Update (1,1) logical = false end - + pathStr = matboxtools.projectdir(); requirementsPath = fullfile(pathStr, "tools", "tests", "test_resources"); diff --git a/tools/tests/+matboxtools/+unittest/TasksTest.m b/tools/tests/+matboxtools/+unittest/TasksTest.m index 748813a..a6e02f8 100644 --- a/tools/tests/+matboxtools/+unittest/TasksTest.m +++ b/tools/tests/+matboxtools/+unittest/TasksTest.m @@ -19,13 +19,13 @@ function setupMethod(testCase) testCase.applyFixture(matlab.unittest.fixtures.WorkingFolderFixture); end end - + methods (Test) function testCodecheckToolbox(testCase) pathStr = matboxtools.projectdir(); copyfile(pathStr, pwd); - + matbox.tasks.codecheckToolbox(pwd, ... "CreateBadge", false, "SaveReport", false); diff --git a/tools/tests/+matboxtools/+unittest/VersionNumberTest.m b/tools/tests/+matboxtools/+unittest/VersionNumberTest.m index f7262a7..0d7a475 100644 --- a/tools/tests/+matboxtools/+unittest/VersionNumberTest.m +++ b/tools/tests/+matboxtools/+unittest/VersionNumberTest.m @@ -1,7 +1,7 @@ classdef VersionNumberTest < matlab.unittest.TestCase methods (Test) - + % Test case for the constructor with numeric input function testConstructorWithNumericInput(testCase) version = matbox.VersionNumber({[1, 2, 3]}); @@ -9,7 +9,7 @@ function testConstructorWithNumericInput(testCase) testCase.verifyEqual(version.Minor, uint8(2)); testCase.verifyEqual(version.Patch, uint8(3)); end - + % Test case for the constructor with string input function testConstructorWithStringInput(testCase) version = matbox.VersionNumber({'1.2.3'}); @@ -45,7 +45,7 @@ function testBumpMinor(testCase) testCase.verifyEqual(version.Patch, uint8(0)); testCase.verifyEqual(version.Build, uint8(0)); end - + % Test bumpPatch method function testBumpPatch(testCase) version = matbox.VersionNumber({[1, 2, 3]}); @@ -55,7 +55,7 @@ function testBumpPatch(testCase) testCase.verifyEqual(version.Patch, uint8(4)); testCase.verifyEqual(version.Build, uint8(0)); end - + % Test bumpBuild method function testBumpBuild(testCase) version = matbox.VersionNumber({[1, 2, 3, 4]}); @@ -68,24 +68,24 @@ function testComparisonOperators(testCase) v1 = matbox.VersionNumber({'1.2.3'}); v2 = matbox.VersionNumber({'2.0.0'}); v3 = matbox.VersionNumber({'1.2.3'}); - + % Test equality testCase.verifyTrue(v1 == v3); testCase.verifyFalse(v1 == v2); - + % Test inequality testCase.verifyTrue(v1 ~= v2); testCase.verifyFalse(v1 ~= v3); - + % Test greater than testCase.verifyTrue(v2 > v1); testCase.verifyFalse(v1 > v2); - + % Test less than testCase.verifyTrue(v1 < v2); testCase.verifyFalse(v2 < v1); end - + % Test IsLatest property function testIsLatestProperty(testCase) version = matbox.VersionNumber({'latest'}); @@ -98,10 +98,10 @@ function testValidateVersion(testCase) v1 = matbox.VersionNumber({'1.2.3'}); v2 = matbox.VersionNumber({'2.0.0'}); validVersions = {v1, v2}; - + % No error for valid version testCase.verifyWarningFree(@() matbox.VersionNumber.validateVersion(v1, validVersions{:})); - + % Error for invalid version invalidVersion = matbox.VersionNumber({'3.0.0'}); testCase.verifyError(@() matbox.VersionNumber.validateVersion(invalidVersion, validVersions{:}), ...