From b016561871d827cf867a2a39a0e200ef56183dbd Mon Sep 17 00:00:00 2001 From: guzman-raphael Date: Sat, 19 Sep 2020 04:38:13 -0500 Subject: [PATCH 1/3] Fix R2016b and add toolbox packaging. --- +dj/Connection.m | 5 +- +dj/version.m | 2 +- +tests/Main.m | 5 -- .gitignore | 4 +- .gitmodules | 0 .travis.yml | 4 ++ DataJoint.mltbx | Bin 0 -> 71149 bytes LNX-docker-compose.yml | 33 +++++++---- README.md | 8 +-- local-docker-compose.yml | 54 +++++++++++++----- setupDJ.m | 47 --------------- {+tests => tests}/+lib/compareVersions.m | 0 tests/Main.m | 5 ++ {+tests => tests}/Prep.m | 6 +- {+tests => tests}/TestConnection.m | 2 +- {+tests => tests}/TestRelationalOperand.m | 2 +- {+tests => tests}/TestTls.m | 11 ++-- .../test_schemas/+University/All.m | 0 18 files changed, 92 insertions(+), 96 deletions(-) delete mode 100644 +tests/Main.m delete mode 100644 .gitmodules create mode 100644 DataJoint.mltbx delete mode 100644 setupDJ.m rename {+tests => tests}/+lib/compareVersions.m (100%) create mode 100644 tests/Main.m rename {+tests => tests}/Prep.m (95%) rename {+tests => tests}/TestConnection.m (98%) rename {+tests => tests}/TestRelationalOperand.m (98%) rename {+tests => tests}/TestTls.m (89%) rename {+tests => tests}/test_schemas/+University/All.m (100%) diff --git a/+dj/Connection.m b/+dj/Connection.m index 650814ed..c46c1557 100644 --- a/+dj/Connection.m +++ b/+dj/Connection.m @@ -27,7 +27,10 @@ % specify the connection to the database. % initQuery is the SQL query to be executed at the start % of each new session. - setupDJ(true); + if ~any(arrayfun(@(x) strcmp(x.Name, 'mym'), ... + matlab.addons.toolbox.installedToolboxes, 'uni', true)) + ghtb.install('guzman-raphael/mym'); + end try mymVersion = mym('version'); assert(mymVersion.major > 2 || mymVersion.major==2 && mymVersion.minor>=6) diff --git a/+dj/version.m b/+dj/version.m index 2b79a3cb..3efacd05 100644 --- a/+dj/version.m +++ b/+dj/version.m @@ -1,7 +1,7 @@ function varargout = version % report DataJoint version -v = struct('major',3,'minor',3,'bugfix',1); +v = struct('major',3,'minor',3,'bugfix',2); if nargout varargout{1}=v; diff --git a/+tests/Main.m b/+tests/Main.m deleted file mode 100644 index 4f14f0a7..00000000 --- a/+tests/Main.m +++ /dev/null @@ -1,5 +0,0 @@ -classdef Main < ... - tests.TestConnection & ... - tests.TestRelationalOperand & ... - tests.TestTls -end \ No newline at end of file diff --git a/.gitignore b/.gitignore index c9a8c43f..1a9c3e38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ *.m~ mym/ -*.mltbx *.env notebook *getSchema.m @@ -8,4 +7,5 @@ docker-compose.yml .vscode matlab.prf win.* -macos.* \ No newline at end of file +macos.* +package.prj \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29b..00000000 diff --git a/.travis.yml b/.travis.yml index 8bb0c8ab..ed7c6d16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,4 +36,8 @@ jobs: - <<: *slim env: - MATLAB_VERSION: R2018b + - MYSQL_TAG: 5.7 + - <<: *slim + env: + - MATLAB_VERSION: R2016b - MYSQL_TAG: 5.7 \ No newline at end of file diff --git a/DataJoint.mltbx b/DataJoint.mltbx new file mode 100644 index 0000000000000000000000000000000000000000..5ad609ec695c901a764ffcc997950fda13908423 GIT binary patch literal 71149 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 VtIJw_4K&j4HqBn&AFbbn{{d@u_Iv;U literal 0 HcmV?d00001 diff --git a/LNX-docker-compose.yml b/LNX-docker-compose.yml index 062b80af..3216a4a6 100644 --- a/LNX-docker-compose.yml +++ b/LNX-docker-compose.yml @@ -21,7 +21,6 @@ services: app: <<: *net environment: - - DISPLAY - MATLAB_LICENSE - MATLAB_USER - DJ_HOST=fakeservices.datajoint.io @@ -35,17 +34,29 @@ services: fakeservices.datajoint.io: condition: service_healthy user: ${MATLAB_UID}:${MATLAB_GID} - working_dir: /src - command: > - /bin/bash -c " - matlab -nodisplay -r \"\ - res=run(tests.Main);\ - disp(res);\ - if all([res.Passed]) exit, else exit(1), end;\ - \"; - " + working_dir: /main + command: + - /bin/bash + - -c + - | + matlab -nodisplay -r " + websave([tempdir 'GHToolbox.mltbx'],\ + ['https://github.com/datajoint/GHToolbox' \ + '/releases/download/' subsref(webread(['https://api.github.com/repos' \ + '/datajoint/GHToolbox' \ + '/releases/latest']),\ + substruct('.', 'tag_name')) \ + '/GHToolbox.mltbx']);\ + matlab.addons.toolbox.installToolbox([tempdir 'GHToolbox.mltbx']);\ + ghtb.install('DataJoint.mltbx');\ + addpath('tests');\ + res=run(Main);\ + disp(res);\ + if all([res.Passed]) exit, else exit(1), end;\ + " mac_address: $MATLAB_HOSTID volumes: - - .:/src + - ./tests:/main/tests + - ./DataJoint.mltbx:/main/DataJoint.mltbx networks: main: \ No newline at end of file diff --git a/README.md b/README.md index b8da6eb4..9977b3fe 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ MYSQL_TAG=5.7 | Use Case | MATLAB Code | | ---------------------------- | ------------------------------------------------------------------------------ | -| Run all tests | `run(tests.Main)` | -| Run one class of tests | `run(tests.TestTls)` | -| Run one specific test | `runtests('tests.TestTls/testInsecureConn')` | -| Run tests based on test name | `import matlab.unittest.TestSuite;`
`import matlab.unittest.selectors.HasName;`
`import matlab.unittest.constraints.ContainsSubstring;`
`suite = TestSuite.fromClass(?tests.Main, ... `
    `HasName(ContainsSubstring('Conn')));`
`run(suite)`| +| Run all tests | `run(Main)` | +| Run one class of tests | `run(TestTls)` | +| Run one specific test | `runtests('TestTls/testInsecureConn')` | +| Run tests based on test name | `import matlab.unittest.TestSuite;`
`import matlab.unittest.selectors.HasName;`
`import matlab.unittest.constraints.ContainsSubstring;`
`suite = TestSuite.fromClass(?Main, ... `
    `HasName(ContainsSubstring('Conn')));`
`run(suite)`| Launch Jupyter Notebook diff --git a/local-docker-compose.yml b/local-docker-compose.yml index 288d65c1..7546595c 100644 --- a/local-docker-compose.yml +++ b/local-docker-compose.yml @@ -46,19 +46,46 @@ services: ports: - "8888:8888" user: ${MATLAB_UID}:${MATLAB_GID} - working_dir: /home/muser/notebooks - command: > - /bin/bash -c " - ## Remove mym - rm -R /src/mym; - ## Set dj path - matlab -nodisplay -r \"\ - addpath('/src');\ - savepath;\ - \"; - ## Interactive Jupyter Notebook environment - jupyter notebook; - " + # working_dir: /home/muser/notebooks + working_dir: /src + command: + - /bin/bash + - -c + - | + # package into toolbox, and install + matlab -nodisplay -r " + websave([tempdir 'GHToolbox.mltbx'],\ + ['https://github.com/datajoint/GHToolbox' \ + '/releases/download/' subsref(webread(['https://api.github.com/repos' \ + '/datajoint/GHToolbox' \ + '/releases/latest']),\ + substruct('.', 'tag_name')) \ + '/GHToolbox.mltbx']);\ + matlab.addons.toolbox.installToolbox([tempdir 'GHToolbox.mltbx']);\ + fid = fopen('README.md', 'r');\ + docs = fread(fid, '*char')';\ + fclose(fid);\ + ghtb.package('DataJoint',\ + 'Raphael Guzman',\ + 'raphael.h.guzman@gmail.com',\ + ['Scientific workflow management framework built on top of a ' \ + 'relational database.'],\ + docs,\ + {'.vscode', '.git', '*.env', '.gitignore', '.travis.yml', 'tests',\ + 'docs-parts', 'mym', 'erd.m', '*docker-compose.yml', 'LICENSE.txt',\ + 'matlab.prf', 'package.m', 'README.md'},\ + @() strjoin(arrayfun(@(x) num2str(x),\ + cell2mat(struct2cell(dj.version)),\ + 'uni', false),\ + '.'),\ + {'+dj'});\ + ghtb.install('DataJoint.mltbx');\ + dj.version;\ + " + # Copy preferences + cp /tmp/matlab.prf /home/muser/.matlab/${MATLAB_VERSION}/matlab.prf + # Interactive Jupyter Notebook environment + jupyter notebook mac_address: $MATLAB_HOSTID volumes: ## Dev mounts @@ -66,5 +93,6 @@ services: - /tmp/.X11-unix:/tmp/.X11-unix:rw ## Additional mounts may go here # - ./notebook:/home/muser/notebooks + - ./matlab.prf:/tmp/matlab.prf networks: main: \ No newline at end of file diff --git a/setupDJ.m b/setupDJ.m deleted file mode 100644 index 25bb9b07..00000000 --- a/setupDJ.m +++ /dev/null @@ -1,47 +0,0 @@ -function setupDJ(skipPathAddition, force) - - if nargin < 2 - force = false; - end - - persistent INVOKED; - - if ~isempty(INVOKED) && ~force - return - end - - base = fileparts(mfilename('fullpath')); - - if nargin < 1 - skipPathAddition = false; - end - - if ~skipPathAddition - fprintf('Adding DataJoint to the path...\n') - addpath(base) - end - - mymdir = fullfile(base, 'mym'); - % if mym directory missing, download and install - if ~isdir(mymdir) - fprintf('mym missing. Downloading...\n') - target = fullfile(base, 'mym.zip'); - mymURL = 'https://github.com/datajoint/mym/archive/master.zip'; - target = websave(target, mymURL); - if isunix && ~ismac - % on Linux Matlab unzip doesn't work properly so use system unzip - system(sprintf('unzip -o %s -d %s', target, base)) - else - unzip(target, base) - end - % rename extracted mym-master directory to mym - movefile(fullfile(base, 'mym-master'), mymdir) - delete(target) - end - - % run mymSetup.m - fprintf('Setting up mym...\n') - run(fullfile(mymdir, 'mymSetup.m')) - - INVOKED = 1; -end diff --git a/+tests/+lib/compareVersions.m b/tests/+lib/compareVersions.m similarity index 100% rename from +tests/+lib/compareVersions.m rename to tests/+lib/compareVersions.m diff --git a/tests/Main.m b/tests/Main.m new file mode 100644 index 00000000..e20b3bfa --- /dev/null +++ b/tests/Main.m @@ -0,0 +1,5 @@ +classdef Main < ... + TestConnection & ... + TestRelationalOperand & ... + TestTls +end \ No newline at end of file diff --git a/+tests/Prep.m b/tests/Prep.m similarity index 95% rename from +tests/Prep.m rename to tests/Prep.m index 47395249..27305cb3 100644 --- a/+tests/Prep.m +++ b/tests/Prep.m @@ -22,9 +22,7 @@ methods function obj = Prep() % Initialize test_root - test_pkg_details = what('tests'); - [test_root, ~, ~] = fileparts(test_pkg_details.path); - obj.test_root = [test_root '/+tests']; + obj.test_root = [pwd '/tests']; end end methods (TestClassSetup) @@ -37,7 +35,7 @@ function init(testCase) testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password,'',true); % create test users ver = curr_conn.query('select @@version as version').version; - if tests.lib.compareVersions(ver,'5.8') + if lib.compareVersions(ver,'5.8') cmd = {... 'CREATE USER IF NOT EXISTS ''datajoint''@''%%'' ' 'IDENTIFIED BY ''datajoint'';' diff --git a/+tests/TestConnection.m b/tests/TestConnection.m similarity index 98% rename from +tests/TestConnection.m rename to tests/TestConnection.m index 92b113a3..cd42ec3b 100644 --- a/+tests/TestConnection.m +++ b/tests/TestConnection.m @@ -1,4 +1,4 @@ -classdef TestConnection < tests.Prep +classdef TestConnection < Prep % TestConnection tests typical connection scenarios. methods (Test) function TestConnection_testConnection(testCase) diff --git a/+tests/TestRelationalOperand.m b/tests/TestRelationalOperand.m similarity index 98% rename from +tests/TestRelationalOperand.m rename to tests/TestRelationalOperand.m index b88147f0..6e09577f 100644 --- a/+tests/TestRelationalOperand.m +++ b/tests/TestRelationalOperand.m @@ -1,4 +1,4 @@ -classdef TestRelationalOperand < tests.Prep +classdef TestRelationalOperand < Prep % TestRelationalOperand tests relational operations. methods (Test) function TestRelationalOperand_testUpdateDate(testCase) diff --git a/+tests/TestTls.m b/tests/TestTls.m similarity index 89% rename from +tests/TestTls.m rename to tests/TestTls.m index a340afb6..4ed33df8 100644 --- a/+tests/TestTls.m +++ b/tests/TestTls.m @@ -1,4 +1,4 @@ -classdef TestTls < tests.Prep +classdef TestTls < Prep % TestTls tests TLS connection scenarios. methods (Test) function TestTls_testSecureConn(testCase) @@ -47,11 +47,10 @@ function TestTls_testRejectException(testCase) 'djssl', ... '',true,false); testCase.verifyTrue(false); - catch - e = lasterror; - testCase.verifyEqual(e.identifier, 'MySQL:Error'); - testCase.verifyTrue(contains(e.message,... - ["requires secure connection","Access denied"])); %MySQL8,MySQL5 + catch ME + testCase.verifyEqual(ME.identifier, 'MySQL:Error'); + testCase.verifyTrue(contains(ME.message,'requires secure connection') || ... + contains(ME.message,'Access denied')); %MySQL8 or MySQL5 end end function TestTls_testStructException(testCase) diff --git a/+tests/test_schemas/+University/All.m b/tests/test_schemas/+University/All.m similarity index 100% rename from +tests/test_schemas/+University/All.m rename to tests/test_schemas/+University/All.m From 058227cd985813a06fb8f10cd0fcd6670838e6e4 Mon Sep 17 00:00:00 2001 From: guzman-raphael Date: Tue, 22 Sep 2020 18:00:53 -0500 Subject: [PATCH 2/3] Move compareVersions to its maintained toolbox, rename setupDJ to +dj/setup, add GHToolbox/mym dependencies, add installation docs, and clean up tests. --- +dj/+lib/compareVersions.m | 100 ----------------------------------- +dj/Connection.m | 14 +---- +dj/conn.m | 1 - +dj/setup.m | 51 ++++++++++++++++++ DataJoint.mltbx | Bin 71149 -> 70597 bytes LNX-docker-compose.yml | 10 +--- README.md | 39 +++++++++++--- local-docker-compose.yml | 2 - tests/+lib/compareVersions.m | 100 ----------------------------------- tests/Prep.m | 2 +- 10 files changed, 85 insertions(+), 234 deletions(-) delete mode 100644 +dj/+lib/compareVersions.m create mode 100644 +dj/setup.m delete mode 100644 tests/+lib/compareVersions.m diff --git a/+dj/+lib/compareVersions.m b/+dj/+lib/compareVersions.m deleted file mode 100644 index 7380bb32..00000000 --- a/+dj/+lib/compareVersions.m +++ /dev/null @@ -1,100 +0,0 @@ -function res = compareVersions(verArray, verComp) - % compareVersions - Semantic version comparison (greater than or equal) - % - % This function evaluates if an array of semantic versions is greater than - % or equal to a reference version. - % - % DISTRIBUTION: - % GitHub: https://github.com/guzman-raphael/compareVersions - % FileExchange: https://www.mathworks.com/matlabcentral/fileexchange/71849-compareversions - % - % res = compareVersions(verArray, verComp) - % INPUT: - % verArray: Cell array with the following conditions: - % - be of length >= 1, - % - contain only string elements, and - % - each element must be of length >= 1. - % verComp: String or Char array that verArray will compare against for - % greater than evaluation. Must be: - % - be of length >= 1, and - % - a string. - % OUTPUT: - % res: Logical array that identifies if each cell element in verArray - % is greater than or equal to verComp. - % TESTS: - % Tests included for reference. From root package directory, - % use command: runtests - % - % EXAMPLES: - % output = compareVersions({'3.2.4beta','9.5.2.1','8.0'}, '8.0.0'); %logical([0 1 1]) - % - % NOTES: - % Tests included for reference. From root package directory, - % use command: runtests - % - % Tested: Matlab 9.5.0.944444 (R2018b) Linux - % Author: Raphael Guzman, DataJoint - % - % $License: MIT (use/copy/change/redistribute on own risk) $ - % $File: compareVersions.m $ - % History: - % 001: 2019-06-12 11:00, First version. - % - % OPEN BUGS: - % - None - res_n = length(verArray); - if ~res_n || max(cellfun(@(c) ~ischar(c) && ... - ~isstring(c),verArray)) > 0 || min(cellfun('length',verArray)) == 0 - msg = { - 'compareVersions:Error:CellArray' - 'Cell array to verify must:' - '- be of length >= 1,' - '- contain only string elements, and' - '- each element must be of length >= 1.' - }; - error('compareVersions:Error:CellArray', sprintf('%s\n',msg{:})); - end - if ~ischar(verComp) && ~isstring(verComp) || length(verComp) == 0 - msg = { - 'compareVersions:Error:VersionRef' - 'Version reference must:' - '- be of length >= 1, and' - '- a string.' - }; - error('compareVersions:Error:VersionRef', sprintf('%s\n',msg{:})); - end - res = false(1, res_n); - for i = 1:res_n - shortVer = strsplit(verArray{i}, '.'); - shortVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), shortVer(1,:)); - longVer = strsplit(verComp, '.'); - longVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), longVer(1,:)); - shortVer_p = true; - longVer_p = false; - shortVer_s = length(shortVer); - longVer_s = length(longVer); - - if shortVer_s > longVer_s - [longVer shortVer] = deal(shortVer,longVer); - [longVer_s shortVer_s] = deal(shortVer_s,longVer_s); - [longVer_p shortVer_p] = deal(shortVer_p,longVer_p); - end - - shortVer = [shortVer zeros(1,longVer_s - shortVer_s)]; - diff = shortVer - longVer; - match = diff ~= 0; - - if ~match - res(i) = true; - else - pos = 1:longVer_s; - pos = pos(match); - val = diff(pos(1)); - if val > 0 - res(i) = shortVer_p; - elseif val < 0 - res(i) = longVer_p; - end - end - end -end diff --git a/+dj/Connection.m b/+dj/Connection.m index c46c1557..ea5d23f9 100644 --- a/+dj/Connection.m +++ b/+dj/Connection.m @@ -27,19 +27,7 @@ % specify the connection to the database. % initQuery is the SQL query to be executed at the start % of each new session. - if ~any(arrayfun(@(x) strcmp(x.Name, 'mym'), ... - matlab.addons.toolbox.installedToolboxes, 'uni', true)) - ghtb.install('guzman-raphael/mym'); - end - try - mymVersion = mym('version'); - assert(mymVersion.major > 2 || mymVersion.major==2 && mymVersion.minor>=6) - catch - error 'Outdated version of mYm. Please upgrade to version 2.6 or later' - end - if verLessThan('matlab', '8.6') - error 'MATLAB version 8.6 (R2015b) or greater is required' - end + dj.setup('prompt', ~dj.set('suppressPrompt')); self.host = host; self.user = username; self.password = password; diff --git a/+dj/conn.m b/+dj/conn.m index b6c4cf10..b7899692 100644 --- a/+dj/conn.m +++ b/+dj/conn.m @@ -45,7 +45,6 @@ end end else - % invoke setupDJ % optional environment variables specifying the connection. env = struct(... 'host', 'DJ_HOST', ... diff --git a/+dj/setup.m b/+dj/setup.m new file mode 100644 index 00000000..fc5d9eb1 --- /dev/null +++ b/+dj/setup.m @@ -0,0 +1,51 @@ +function setup(varargin) + p = inputParser; + addOptional(p, 'force', false); + addOptional(p, 'prompt', true); + parse(p, varargin{:}); + force = p.Results.force; + prompt = p.Results.prompt; + persistent INVOKED + if ~isempty(INVOKED) && ~force + return + end + % check MATLAB + if verLessThan('matlab', '9.1') + error('DataJoint:System:UnsupportedMatlabVersion', ... + 'MATLAB version 9.1 (R2016b) or greater is required'); + end + % require certain toolboxes + requiredToolboxes = {... + struct(... + 'Name', 'GHToolbox', ... + 'ResolveTarget', 'datajoint/GHToolbox'... + ), ... + struct(... + 'Name', 'mym', ... + 'ResolveTarget', 'guzman-raphael/mym', ... + 'Version', '2.7.3'... + )... + }; + try + ghtb.require(requiredToolboxes, 'prompt', prompt); + catch ME + if strcmp(ME.identifier, 'MATLAB:undefinedVarOrClass') + GHToolboxMsg = { + 'Toolbox ''GHToolbox'' did not meet the minimum minimum requirements.' + 'Please install it via instructions in ' + '''https://github.com/datajoint/GHToolbox'''.' + }; + error('DataJoint:verifyGHToolbox:Failed', ... + sprintf('%s\n', GHToolboxMsg{:})); + else + rethrow(ME) + end + end + % check mym + mymVersion = mym('version'); + assert(mymVersion.major > 2 || mymVersion.major==2 && mymVersion.minor>=6, ... + 'DataJoint:System:mYmIncompatible', ... + 'Outdated version of mYm. Please upgrade to version 2.6 or later'); + % set cache + INVOKED = true; +end \ No newline at end of file diff --git a/DataJoint.mltbx b/DataJoint.mltbx index 5ad609ec695c901a764ffcc997950fda13908423..5a8528bd53794e760923ad025f51a49cfd98d79a 100644 GIT binary patch delta 9001 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 delta 9422 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 Add-Ons -> Get Add-Ons* +2. Search and Select `DataJoint` +3. Select *Add from GitHub* + +### Less than R2016b + +1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* +2. Search and Select `DataJoint` +3. Select *Download from GitHub* +4. Save `DataJoint.mltbx` locally +5. Navigate in MATLAB tree browser to saved toolbox file +6. Right-Click and Select *Install* +7. Select *Install* + +### From Source + +1. Download `DataJoint.mltbx` locally +2. Navigate in MATLAB tree browser to saved toolbox file +3. Right-Click and Select *Install* +4. Select *Install* + + +## Running Tests Locally * Create an `.env` with desired development environment values e.g. ``` sh @@ -30,20 +53,20 @@ MYSQL_TAG=5.7 | Run tests based on test name | `import matlab.unittest.TestSuite;`
`import matlab.unittest.selectors.HasName;`
`import matlab.unittest.constraints.ContainsSubstring;`
`suite = TestSuite.fromClass(?Main, ... `
    `HasName(ContainsSubstring('Conn')));`
`run(suite)`| -Launch Jupyter Notebook ------------------------ +### Launch Jupyter Notebook + * Navigate to `localhost:8888` * Input Jupyter password * Launch a notebook i.e. `New > MATLAB` -Launch MATLAB GUI (supports remote interactive debugger) --------------------------------------------------------- +### Launch MATLAB GUI (supports remote interactive debugger) + * Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` * Launch Matlab by runnning command `matlab` -Launch MATLAB Terminal ----------------------- +### Launch MATLAB Terminal + * Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` * Launch Matlab with no GUI by runnning command `matlab -nodisplay` \ No newline at end of file diff --git a/local-docker-compose.yml b/local-docker-compose.yml index 7546595c..95288efe 100644 --- a/local-docker-compose.yml +++ b/local-docker-compose.yml @@ -79,8 +79,6 @@ services: 'uni', false),\ '.'),\ {'+dj'});\ - ghtb.install('DataJoint.mltbx');\ - dj.version;\ " # Copy preferences cp /tmp/matlab.prf /home/muser/.matlab/${MATLAB_VERSION}/matlab.prf diff --git a/tests/+lib/compareVersions.m b/tests/+lib/compareVersions.m deleted file mode 100644 index 46d7b27d..00000000 --- a/tests/+lib/compareVersions.m +++ /dev/null @@ -1,100 +0,0 @@ -function res = compareVersions(verArray, verComp) - % compareVersions - Semantic version comparison (greater than or equal) - % - % This function evaluates if an array of semantic versions is greater than - % or equal to a reference version. - % - % DISTRIBUTION: - % GitHub: https://github.com/guzman-raphael/compareVersions - % FileExchange: https://www.mathworks.com/matlabcentral/fileexchange/71849-compareversions - % - % res = compareVersions(verArray, verComp) - % INPUT: - % verArray: Cell array with the following conditions: - % - be of length >= 1, - % - contain only string elements, and - % - each element must be of length >= 1. - % verComp: String or Char array that verArray will compare against for - % greater than evaluation. Must be: - % - be of length >= 1, and - % - a string. - % OUTPUT: - % res: Logical array that identifies if each cell element in verArray - % is greater than or equal to verComp. - % TESTS: - % Tests included for reference. From root package directory, - % use command: runtests - % - % EXAMPLES: - % output = compareVersions({'3.2.4beta','9.5.2.1','8.0'}, '8.0.0'); %logical([0 1 1]) - % - % NOTES: - % Tests included for reference. From root package directory, - % use command: runtests - % - % Tested: Matlab 9.5.0.944444 (R2018b) Linux - % Author: Raphael Guzman, DataJoint - % - % $License: MIT (use/copy/change/redistribute on own risk) $ - % $File: compareVersions.m $ - % History: - % 001: 2019-06-12 11:00, First version. - % - % OPEN BUGS: - % - None - res_n = length(verArray); - if ~res_n || max(cellfun(@(c) ~ischar(c) && ... - ~isstring(c),verArray)) > 0 || min(cellfun('length',verArray)) == 0 - msg = { - 'compareVersions:Error:CellArray' - 'Cell array to verify must:' - '- be of length >= 1,' - '- contain only string elements, and' - '- each element must be of length >= 1.' - }; - error('compareVersions:Error:CellArray', sprintf('%s\n',msg{:})); - end - if ~ischar(verComp) && ~isstring(verComp) || length(verComp) == 0 - msg = { - 'compareVersions:Error:VersionRef' - 'Version reference must:' - '- be of length >= 1, and' - '- a string.' - }; - error('compareVersions:Error:VersionRef', sprintf('%s\n',msg{:})); - end - res = false(1, res_n); - for i = 1:res_n - shortVer = strsplit(verArray{i}, '.'); - shortVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), shortVer(1,:)); - longVer = strsplit(verComp, '.'); - longVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), longVer(1,:)); - shortVer_p = true; - longVer_p = false; - shortVer_s = length(shortVer); - longVer_s = length(longVer); - - if shortVer_s > longVer_s - [longVer shortVer] = deal(shortVer,longVer); - [longVer_s shortVer_s] = deal(shortVer_s,longVer_s); - [longVer_p shortVer_p] = deal(shortVer_p,longVer_p); - end - - shortVer = [shortVer zeros(1,longVer_s - shortVer_s)]; - diff = shortVer - longVer; - match = diff ~= 0; - - if ~match - res(i) = true; - else - pos = 1:longVer_s; - pos = pos(match); - val = diff(pos(1)); - if val > 0 - res(i) = shortVer_p; - elseif val < 0 - res(i) = longVer_p; - end - end - end -end \ No newline at end of file diff --git a/tests/Prep.m b/tests/Prep.m index 27305cb3..e936afbe 100644 --- a/tests/Prep.m +++ b/tests/Prep.m @@ -35,7 +35,7 @@ function init(testCase) testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password,'',true); % create test users ver = curr_conn.query('select @@version as version').version; - if lib.compareVersions(ver,'5.8') + if compareVersions(ver,'5.8') cmd = {... 'CREATE USER IF NOT EXISTS ''datajoint''@''%%'' ' 'IDENTIFIED BY ''datajoint'';' From 089051f338859072aab625a64ee16e09047c3896 Mon Sep 17 00:00:00 2001 From: guzman-raphael Date: Tue, 22 Sep 2020 18:22:03 -0500 Subject: [PATCH 3/3] Update tests and add compiled toolbox. --- DataJoint.mltbx | Bin 70597 -> 70595 bytes LNX-docker-compose.yml | 10 +++++++++- local-docker-compose.yml | 9 +++++++-- tests/Prep.m | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/DataJoint.mltbx b/DataJoint.mltbx index 5a8528bd53794e760923ad025f51a49cfd98d79a..feb1a4996ac5e24495753848b2c3ec2aa34eb2a7 100644 GIT binary patch delta 3868 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 diff --git a/LNX-docker-compose.yml b/LNX-docker-compose.yml index 3ed651e9..3216a4a6 100644 --- a/LNX-docker-compose.yml +++ b/LNX-docker-compose.yml @@ -40,7 +40,15 @@ services: - -c - | matlab -nodisplay -r " - matlab.addons.toolbox.installToolbox('DataJoint.mltbx');\ + websave([tempdir 'GHToolbox.mltbx'],\ + ['https://github.com/datajoint/GHToolbox' \ + '/releases/download/' subsref(webread(['https://api.github.com/repos' \ + '/datajoint/GHToolbox' \ + '/releases/latest']),\ + substruct('.', 'tag_name')) \ + '/GHToolbox.mltbx']);\ + matlab.addons.toolbox.installToolbox([tempdir 'GHToolbox.mltbx']);\ + ghtb.install('DataJoint.mltbx');\ addpath('tests');\ res=run(Main);\ disp(res);\ diff --git a/local-docker-compose.yml b/local-docker-compose.yml index 95288efe..16a379aa 100644 --- a/local-docker-compose.yml +++ b/local-docker-compose.yml @@ -46,12 +46,13 @@ services: ports: - "8888:8888" user: ${MATLAB_UID}:${MATLAB_GID} - # working_dir: /home/muser/notebooks - working_dir: /src + working_dir: /home/muser/notebooks command: - /bin/bash - -c - | + ORIG_DIR=$$(pwd) + cd /src # package into toolbox, and install matlab -nodisplay -r " websave([tempdir 'GHToolbox.mltbx'],\ @@ -79,7 +80,11 @@ services: 'uni', false),\ '.'),\ {'+dj'});\ + matlab.addons.toolbox.installToolbox('DataJoint.mltbx');\ + cd(tempdir);\ + disp(dj.version);\ " + cd "$${ORIG_DIR}" # Copy preferences cp /tmp/matlab.prf /home/muser/.matlab/${MATLAB_VERSION}/matlab.prf # Interactive Jupyter Notebook environment diff --git a/tests/Prep.m b/tests/Prep.m index e936afbe..4cd26e5c 100644 --- a/tests/Prep.m +++ b/tests/Prep.m @@ -30,6 +30,7 @@ function init(testCase) disp('---------------INIT---------------'); clear functions; addpath([testCase.test_root '/test_schemas']); + dj.set('suppressPrompt', true); curr_conn = dj.conn(testCase.CONN_INFO_ROOT.host, ... testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password,'',true);