|
1 | | -function update(scheduled) |
2 | | -% GIT.UPDATE Pull latest Rigbox code |
3 | | -% Pulls the latest code from the remote Github repository. If 'scheduled' |
4 | | -% is a value in the range [1 7] - corresponding to the days of the week, |
5 | | -% with Sunday=1 - code will be pulled only on the 'scheduled' day, |
6 | | -% provided the last fetch was over a day ago. Code will also be pulled if |
7 | | -% it is not the scheduled day, but the last fetch was over a week ago. If |
8 | | -% scheduled is 0, the function will pull changes provided the last fetch |
9 | | -% was over an hour ago. |
| 1 | +function exitCode = update(scheduled) |
| 2 | +% GIT.UPDATE Pulls latest Rigbox code |
| 3 | +% `git.update` pulls the latest code from the remote Rigbox Github |
| 4 | +% repository if it is run on a specific day of the week (provided the |
| 5 | +% remote code was last fetched over a day ago), or immediately (provided |
| 6 | +% the remote code was last fetched over an hour ago), according to |
| 7 | +% `scheduled`. If run without an input arg, code is pulled according to |
| 8 | +% the `updateSchedule` field in the struct returned by `dat.paths`, or |
| 9 | +% immediately if the `updateSchedule` field is not found in `dat.paths` |
| 10 | +% (provided the remote code was last fetched over an hour ago). |
| 11 | +% |
| 12 | +% Inputs: |
| 13 | +% `scheduled`: an optional input as an integer in the interval [0,7]. |
| 14 | +% When 0, the remote code will be pulled provided the last fetch was |
| 15 | +% over an hour ago. When in the interval [1,7], code will be pulled on |
| 16 | +% a corresponding day according to `weekday` (Sunday=1, Monday=2, ... |
| 17 | +% Saturday = 7), provided the last fetch was over a day ago. Code will |
| 18 | +% also be pulled if it is not the scheduled day, but the last fetch was |
| 19 | +% over a week ago. If scheduled is 0, the function will pull changes |
| 20 | +% provided the last fetch was over an hour ago. |
10 | 21 | % |
11 | | -% TODO Find quicker way to check for changes |
| 22 | +% Outputs: |
| 23 | +% `exitCode`: An integer in the interval [0,2]. 0 indicates a |
| 24 | +% successful update of the code. 1 indicates an error running git |
| 25 | +% commands. 2 indicates successfully returning from the function |
| 26 | +% without updating the code if the last fetch was within an hour and |
| 27 | +% `scheduled` == 0, or if the last fetch was within 24 hours and |
| 28 | +% `scheduled` is an integer in the interval [1,7]). |
| 29 | +% |
| 30 | +% Example: Pull remote code immediately, provided last code fetch was |
| 31 | +% over an hour ago: |
| 32 | +% git.update(0); |
| 33 | +% |
| 34 | +% Example: Pull remote code if today is Monday, provided last code fetch |
| 35 | +% was over a day ago: |
| 36 | +% git.update(2); |
| 37 | +% |
12 | 38 | % See also DAT.PATHS |
| 39 | +% |
| 40 | +% TODO Find quicker way to check for changes |
13 | 41 |
|
14 | 42 | % Check that paths are set up |
15 | 43 | assert(~isempty(which('dat.paths')), ... |
16 | 44 | 'rigbox:git:update:copyPaths',... |
17 | 45 | ['Error: ''dat.paths'' file not found. Please ensure that a '... |
18 | 46 | '''dat.paths'' file exists for your setup. A template can be found at '... |
19 | 47 | '''docs/setup/paths_template''.']) |
| 48 | + |
| 49 | +% If no input arg, or input arg is not an acceptable value, use |
| 50 | +% `updateSchedule` in `dat.paths`. If `updateSchedule` is not found, set |
| 51 | +% `scheduled` to 0. |
| 52 | +if nargin < 1 |
| 53 | + scheduled = getOr(dat.paths, 'updateSchedule', 0); |
| 54 | +elseif ~isnumeric(scheduled) || ~any(0:7 == scheduled) |
| 55 | + error('Rigbox:git:update:valueError', ... |
| 56 | + 'Input must be integer between 0 and 7') |
| 57 | +end |
| 58 | +root = getOr(dat.paths, 'rigbox'); % Rigbox root directory |
20 | 59 |
|
21 | | -% If not given as input argument, use 'updateSchedule' in 'dat.paths'. If |
22 | | -% not found, set 'scheduled' to 0. |
23 | | -if nargin < 1; scheduled = getOr(dat.paths, 'updateSchedule', 0); end |
24 | | -root = fileparts(which('addRigboxPaths')); % Rigbox root directory |
25 | 60 | % Attempt to find date of last fetch |
26 | 61 | fetch_head = fullfile(root, '.git', 'FETCH_HEAD'); |
27 | | -lastFetch = iff(exist(fetch_head,'file')==2, ... % If FETCH_HEAD file exists |
28 | | - @()getOr(dir(fetch_head), 'datenum'), 0); % Retrieve date modified |
| 62 | +% If `FETCH_HEAD` file exists, retrieve datenum for when last modified, |
| 63 | +% else return 0 (i.e. there was never a fetch) |
| 64 | +lastFetch = iff(exist(fetch_head,'file')==2, ... |
| 65 | + file.modDate(fetch_head), 0); |
29 | 66 |
|
30 | | -% Don't pull changes if the following conditions are met: |
31 | | -% 1. The updates are scheduled for a different day and the last fetch was |
32 | | -% less than a week ago. |
33 | | -% 2. The updates are scheduled for today and the last fetch was today. |
34 | | -% 3. The updates are scheduled for every day and the last fetch was less |
35 | | -% than an hour ago. |
36 | | -if (scheduled && (weekday(now) ~= scheduled) && now - lastFetch < 7) || ... |
37 | | - (scheduled && (weekday(now) == scheduled) && now - lastFetch < 1) || ... |
38 | | - (~scheduled && now - lastFetch < 1/24) |
| 67 | +% Pull changes if the following conditions are met: |
| 68 | +% 1. The last fetch was over a week ago. |
| 69 | +% 2. The updates are scheduled for today and not yet fetched today. |
| 70 | +% 3. The updates are daily and the last fetch was over an hour ago. |
| 71 | +fetchDay = scheduled == weekday(now) || scheduled == false; |
| 72 | +minTime = iff(scheduled, iff(fetchDay, 1, 7), 1/24); |
| 73 | +fetched = now-lastFetch < minTime; |
| 74 | +if fetched || ~fetchDay |
| 75 | + exitCode = 2; |
39 | 76 | return |
40 | 77 | end |
41 | 78 | disp('Updating code...') |
42 | 79 |
|
43 | | -% Get the path to the Git exe |
44 | | -gitexepath = getOr(dat.paths, 'gitExe'); |
45 | | -if isempty(gitexepath) |
46 | | - [~,gitexepath] = system('where git'); % todo: this doesn't always work |
47 | | -end |
48 | | -gitexepath = ['"', strtrim(gitexepath), '"']; |
49 | | - |
50 | | -% Temporarily change directory into Rigbox to git pull |
51 | | -origDir = pwd; |
52 | | -cd(root) |
53 | | - |
54 | 80 | % Create Windows system commands for git stashing, initializing submodules, |
55 | 81 | % and pulling |
56 | | -cmdstrStash = [gitexepath, ' stash push -m "stash Rigbox working changes before scheduled git update"']; |
57 | | -cmdstrStashSubs = [gitexepath, ' submodule foreach "git stash push"']; |
58 | | -cmdstrInit = [gitexepath, ' submodule update --init']; |
59 | | -cmdstrPull = [gitexepath, ' pull --recurse-submodules --strategy-option=theirs']; |
60 | | - |
61 | | -% Stash any WIP, check submodules are initialized, pull |
62 | | -try |
63 | | - [~, cmdout] = system(cmdstrStash, '-echo'); |
64 | | - [~, cmdout] = system(cmdstrStashSubs, '-echo'); |
65 | | - [~, cmdout] = system(cmdstrInit, '-echo'); |
66 | | - [~, cmdout] = system(cmdstrPull, '-echo'); %#ok<ASGLU> |
67 | | -catch ex |
68 | | - cd(origDir) |
69 | | - error('gitUpdate:pull:pullFailed', 'Failed to pull latest changes:, %s', cmdout) |
70 | | -end |
71 | | - |
72 | | -% Run any new tasks |
73 | | -changesPath = fullfile(root, 'cortexlab', '+git', 'changes.m'); |
74 | | -if exist(changesPath, 'file') |
75 | | - git.changes; |
76 | | - delete(changesPath); |
77 | | -end |
78 | | -cd(origDir) |
79 | | -end |
| 82 | +stash = ['stash push -m "stash Rigbox working changes before '... |
| 83 | + 'scheduled git update"']; |
| 84 | +stashSubs = 'submodule foreach "git stash push"'; |
| 85 | +init = 'submodule update --init'; |
| 86 | +pull = 'pull --recurse-submodules --strategy-option=theirs'; |
| 87 | +cmds = {stash, stashSubs, init, pull}; |
| 88 | +% run commands in Rigbox root folder |
| 89 | +exitCode = any(git.runCmd(cmds, 'dir', root, 'echo', true)); |
0 commit comments