foreman-tasks 13.1.0 → 13.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/foreman_tasks/version.rb +1 -1
- data/webpack/ForemanTasks/Components/Chart/Chart.js +3 -1
- data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.js +8 -1
- data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +1 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.scss +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskHelper.js +4 -1
- data/webpack/ForemanTasks/Components/TaskDetails/ExecutionDetails.js +13 -7
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +1 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +6 -2
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +2 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/ExecutionDetails.test.js +53 -6
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +0 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +1 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.scss +1 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +9 -4
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +2 -1
- data/webpack/ForemanTasks/Components/common/taskResultIcon.js +39 -29
- data/webpack/ForemanTasks/Routes/ShowTaskDetails/TaskDetailsHeader.js +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a192677704918d5f7e81554fb38e70f389a795c021c4889f6f910fa992a1bed7
|
|
4
|
+
data.tar.gz: 000732f9d423e0bc8ba6293f7150a631de785535a94d6b5004d40922768897d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d6e131b3624a79ef45aca8c87674938bcc7b2b8c1c0be6652251b6818f0bb1a4ad3843b976d2394901ffe861d7e153fdaeb764c1b44c0cdcbddb46d73d06c6f9
|
|
7
|
+
data.tar.gz: 95888cc143cb58b40d0485d6c67f71c95e9e8e88d08f086b31982f9cfc3693aee68cecd885984581e7fb704feee3978d6e601551b6b200413036f6cbfd0c3336
|
|
@@ -17,6 +17,8 @@ import React from 'react';
|
|
|
17
17
|
import PropTypes from 'prop-types';
|
|
18
18
|
import { findDOMNode } from 'react-dom';
|
|
19
19
|
|
|
20
|
+
const DESTROY_DELAY_MS = 1000;
|
|
21
|
+
|
|
20
22
|
let c3;
|
|
21
23
|
|
|
22
24
|
class C3Chart extends React.Component {
|
|
@@ -44,7 +46,7 @@ class C3Chart extends React.Component {
|
|
|
44
46
|
// Delaying the destroy a bit seems to resolve the issue.
|
|
45
47
|
// The chart API methods are already bind explicitly, therefore we don't need
|
|
46
48
|
// any special handling when passing the function.
|
|
47
|
-
setTimeout(this.chart.destroy,
|
|
49
|
+
setTimeout(this.chart.destroy, DESTROY_DELAY_MS);
|
|
48
50
|
this.chart = null;
|
|
49
51
|
} catch (err) {
|
|
50
52
|
throw new Error('Internal C3 error', err);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { translate as __, sprintf } from 'foremanReact/common/I18n';
|
|
2
2
|
import { addToast } from 'foremanReact/components/ToastsList';
|
|
3
3
|
import { getURIQuery } from 'foremanReact/common/helpers';
|
|
4
|
+
import {
|
|
5
|
+
MINUTES_PER_HOUR,
|
|
6
|
+
SECONDS_PER_MINUTE,
|
|
7
|
+
MS_PER_SECOND,
|
|
8
|
+
} from 'foremanReact/constants';
|
|
4
9
|
import { TASKS_DASHBOARD_JS_QUERY_MODES } from '../TasksDashboard/TasksDashboardConstants';
|
|
5
10
|
import { timeToHoursNumber } from '../TasksDashboard/TasksDashboardHelper';
|
|
6
11
|
import {
|
|
@@ -25,7 +30,9 @@ export const convertDashboardQuery = () => {
|
|
|
25
30
|
} = getTasksQuery();
|
|
26
31
|
|
|
27
32
|
const hours = timeToHoursNumber(timeHorizon);
|
|
28
|
-
const timestamp = new Date(
|
|
33
|
+
const timestamp = new Date(
|
|
34
|
+
new Date() - hours * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND
|
|
35
|
+
);
|
|
29
36
|
let dashboardTime = '';
|
|
30
37
|
const stateQuery = state ? `state=${state}` : '';
|
|
31
38
|
let resultQuery = '';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
-ms-transform-origin: 50% 50%; /* IE 9 */
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
@keyframes spin {
|
|
13
13
|
from {
|
|
14
14
|
-moz-transform: rotate(0deg);
|
|
15
15
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
@keyframes spin {
|
|
23
23
|
from {
|
|
24
24
|
-webkit-transform: rotate(0deg);
|
|
25
25
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { translate as __, documentLocale } from 'foremanReact/common/I18n';
|
|
2
2
|
import { isoCompatibleDate } from 'foremanReact/common/helpers';
|
|
3
3
|
import humanizeDuration from 'humanize-duration';
|
|
4
|
+
import { MS_PER_SECOND } from 'foremanReact/constants';
|
|
4
5
|
|
|
5
6
|
export const durationInWords = (
|
|
6
7
|
start,
|
|
@@ -16,7 +17,9 @@ export const durationInWords = (
|
|
|
16
17
|
language: selectedLocale,
|
|
17
18
|
fallbacks: ['en'],
|
|
18
19
|
}),
|
|
19
|
-
tooltip: `${numberWithDelimiter((finish - start) /
|
|
20
|
+
tooltip: `${numberWithDelimiter((finish - start) / MS_PER_SECOND)} ${__(
|
|
21
|
+
'seconds'
|
|
22
|
+
)}`,
|
|
20
23
|
};
|
|
21
24
|
};
|
|
22
25
|
|
|
@@ -14,18 +14,23 @@ const ExecutionDetails = ({
|
|
|
14
14
|
failedSteps,
|
|
15
15
|
result,
|
|
16
16
|
}) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
state === '
|
|
21
|
-
|
|
17
|
+
const hasFailedSteps = failedSteps.length > 0;
|
|
18
|
+
const hasRunningSteps = runningSteps.length > 0;
|
|
19
|
+
const isActiveExecutionState =
|
|
20
|
+
state === 'running' || state === 'pending' || state === 'paused';
|
|
21
|
+
|
|
22
|
+
// Prefer Errors when failed steps exist (e.g. paused-after-error). Only fall
|
|
23
|
+
// back to the RunningSteps empty state for active tasks with no failures.
|
|
24
|
+
const showRunningSteps =
|
|
25
|
+
hasRunningSteps || (isActiveExecutionState && !hasFailedSteps);
|
|
26
|
+
const showErrors = hasFailedSteps || !showRunningSteps;
|
|
22
27
|
|
|
23
28
|
return (
|
|
24
29
|
<div
|
|
25
30
|
id="execution-details-panel"
|
|
26
31
|
data-ouia-component-id="execution-details-panel"
|
|
27
32
|
>
|
|
28
|
-
{
|
|
33
|
+
{showRunningSteps && (
|
|
29
34
|
<RunningSteps
|
|
30
35
|
executionPlan={executionPlan}
|
|
31
36
|
result={result}
|
|
@@ -35,7 +40,8 @@ const ExecutionDetails = ({
|
|
|
35
40
|
taskReload={taskReload}
|
|
36
41
|
taskReloadStart={taskReloadStart}
|
|
37
42
|
/>
|
|
38
|
-
)
|
|
43
|
+
)}
|
|
44
|
+
{showErrors && (
|
|
39
45
|
<Errors executionPlan={executionPlan} failedSteps={failedSteps} />
|
|
40
46
|
)}
|
|
41
47
|
</div>
|
|
@@ -6,7 +6,11 @@ import {
|
|
|
6
6
|
stopInterval,
|
|
7
7
|
} from 'foremanReact/redux/middlewares/IntervalMiddleware';
|
|
8
8
|
import { foremanTasksApiPath, foremanTasksPath } from '../common/urlHelpers';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
TASK_STEP_CANCEL,
|
|
11
|
+
FOREMAN_TASK_DETAILS,
|
|
12
|
+
TASK_RELOAD_INTERVAL_MS,
|
|
13
|
+
} from './TaskDetailsConstants';
|
|
10
14
|
import {
|
|
11
15
|
errorToastData,
|
|
12
16
|
infoToastData,
|
|
@@ -30,7 +34,7 @@ export const taskReloadStart = id => dispatch => {
|
|
|
30
34
|
dispatch(stopInterval(FOREMAN_TASK_DETAILS));
|
|
31
35
|
},
|
|
32
36
|
}),
|
|
33
|
-
|
|
37
|
+
TASK_RELOAD_INTERVAL_MS
|
|
34
38
|
)
|
|
35
39
|
);
|
|
36
40
|
};
|
|
@@ -3,3 +3,5 @@ export const FOREMAN_TASK_DETAILS_SUCCESS = 'FOREMAN_TASK_DETAILS_SUCCESS';
|
|
|
3
3
|
export const TASKS_PATH = '/foreman_tasks/tasks';
|
|
4
4
|
export const TASK_STEP_CANCEL = 'TASK_STEP_CANCEL';
|
|
5
5
|
export const VIEW_FOREMAN_TASKS = 'view_foreman_tasks';
|
|
6
|
+
|
|
7
|
+
export const TASK_RELOAD_INTERVAL_MS = 5000;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
selectAPIError as selectAPIErrorByKey,
|
|
6
6
|
} from 'foremanReact/redux/API/APISelectors';
|
|
7
7
|
import { selectDoesIntervalExist } from 'foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors';
|
|
8
|
-
import { STATUS } from 'foremanReact/constants';
|
|
8
|
+
import { STATUS, PERCENT_MULTIPLIER } from 'foremanReact/constants';
|
|
9
9
|
import { selectForemanTasks } from '../../ForemanTasksSelectors';
|
|
10
10
|
import { FOREMAN_TASK_DETAILS } from './TaskDetailsConstants';
|
|
11
11
|
|
|
@@ -41,7 +41,7 @@ export const selectCancellable = state =>
|
|
|
41
41
|
|
|
42
42
|
export const selectProgress = state =>
|
|
43
43
|
selectTaskDetailsResponse(state).progress
|
|
44
|
-
? Math.trunc(selectTaskDetailsResponse(state).progress *
|
|
44
|
+
? Math.trunc(selectTaskDetailsResponse(state).progress * PERCENT_MULTIPLIER)
|
|
45
45
|
: 0;
|
|
46
46
|
|
|
47
47
|
export const selectUsername = state =>
|
|
@@ -28,9 +28,13 @@ describe('ExecutionDetails', () => {
|
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
expect(
|
|
31
|
-
document.querySelector(
|
|
31
|
+
document.querySelector(
|
|
32
|
+
'[data-ouia-component-id="execution-details-panel"]'
|
|
33
|
+
)
|
|
34
|
+
).toBeInTheDocument();
|
|
35
|
+
expect(
|
|
36
|
+
document.getElementById('execution-details-panel')
|
|
32
37
|
).toBeInTheDocument();
|
|
33
|
-
expect(document.getElementById('execution-details-panel')).toBeInTheDocument();
|
|
34
38
|
});
|
|
35
39
|
|
|
36
40
|
it('shows Errors pane when stopped with no running steps', () => {
|
|
@@ -44,7 +48,9 @@ describe('ExecutionDetails', () => {
|
|
|
44
48
|
/>
|
|
45
49
|
);
|
|
46
50
|
|
|
47
|
-
expect(
|
|
51
|
+
expect(
|
|
52
|
+
screen.getByRole('heading', { name: /^no errors found$/i })
|
|
53
|
+
).toBeInTheDocument();
|
|
48
54
|
expect(
|
|
49
55
|
screen.getByText(/the task finished with no errors or warnings/i)
|
|
50
56
|
).toBeInTheDocument();
|
|
@@ -127,9 +133,7 @@ describe('ExecutionDetails', () => {
|
|
|
127
133
|
name: /action actions::katello::eventqueue::monitor is already active/i,
|
|
128
134
|
})
|
|
129
135
|
).toBeInTheDocument();
|
|
130
|
-
expect(
|
|
131
|
-
screen.getByLabelText(/failed task errors/i)
|
|
132
|
-
).toBeInTheDocument();
|
|
136
|
+
expect(screen.getByLabelText(/failed task errors/i)).toBeInTheDocument();
|
|
133
137
|
expect(screen.getByText('Exception:')).toBeInTheDocument();
|
|
134
138
|
});
|
|
135
139
|
|
|
@@ -191,4 +195,47 @@ describe('ExecutionDetails', () => {
|
|
|
191
195
|
).toBeInTheDocument();
|
|
192
196
|
expect(screen.getByText('paused')).toBeInTheDocument();
|
|
193
197
|
});
|
|
198
|
+
|
|
199
|
+
it('shows Errors when state is paused with failed steps', () => {
|
|
200
|
+
render(
|
|
201
|
+
<ExecutionDetails
|
|
202
|
+
{...rtlBaseProps}
|
|
203
|
+
{...fixtureFailedExecutionDetail}
|
|
204
|
+
state="paused"
|
|
205
|
+
executionPlan={{ state: 'paused', cancellable: false }}
|
|
206
|
+
runningSteps={[]}
|
|
207
|
+
/>
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
expect(
|
|
211
|
+
screen.getByRole('tab', {
|
|
212
|
+
name: /action actions::katello::eventqueue::monitor is already active/i,
|
|
213
|
+
})
|
|
214
|
+
).toBeInTheDocument();
|
|
215
|
+
expect(screen.getByLabelText(/failed task errors/i)).toBeInTheDocument();
|
|
216
|
+
expect(screen.getByText('Exception:')).toBeInTheDocument();
|
|
217
|
+
expect(screen.queryByText(/no running steps/i)).not.toBeInTheDocument();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('shows Errors and RunningSteps when paused with both failed and running steps', () => {
|
|
221
|
+
render(
|
|
222
|
+
<ExecutionDetails
|
|
223
|
+
{...rtlBaseProps}
|
|
224
|
+
{...fixtureFailedExecutionDetail}
|
|
225
|
+
state="paused"
|
|
226
|
+
executionPlan={{ state: 'paused', cancellable: false }}
|
|
227
|
+
runningSteps={[
|
|
228
|
+
{
|
|
229
|
+
...fixtureRunningExecutionDetail.runningSteps[0],
|
|
230
|
+
state: 'suspended',
|
|
231
|
+
},
|
|
232
|
+
]}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expect(
|
|
237
|
+
screen.getByRole('heading', { name: 'Warning alert: Running step 1' })
|
|
238
|
+
).toBeInTheDocument();
|
|
239
|
+
expect(screen.getByLabelText(/failed task errors/i)).toBeInTheDocument();
|
|
240
|
+
});
|
|
194
241
|
});
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { getURIQuery } from 'foremanReact/common/helpers';
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
HOURS_PER_HALF_DAY,
|
|
5
|
+
HOURS_PER_DAY,
|
|
6
|
+
DAYS_PER_WEEK,
|
|
7
|
+
} from 'foremanReact/constants';
|
|
3
8
|
import {
|
|
4
9
|
TASKS_DASHBOARD_AVAILABLE_TIMES,
|
|
5
10
|
TASKS_DASHBOARD_QUERY_KEYS_TEXT,
|
|
@@ -16,13 +21,13 @@ export const getQueryValueText = value =>
|
|
|
16
21
|
export const timeToHoursNumber = time => {
|
|
17
22
|
switch (time) {
|
|
18
23
|
case TASKS_DASHBOARD_AVAILABLE_TIMES.H12:
|
|
19
|
-
return
|
|
24
|
+
return HOURS_PER_HALF_DAY;
|
|
20
25
|
case TASKS_DASHBOARD_AVAILABLE_TIMES.H24:
|
|
21
|
-
return
|
|
26
|
+
return HOURS_PER_DAY;
|
|
22
27
|
case TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK:
|
|
23
|
-
return
|
|
28
|
+
return HOURS_PER_DAY * DAYS_PER_WEEK;
|
|
24
29
|
default:
|
|
25
|
-
return
|
|
30
|
+
return HOURS_PER_DAY;
|
|
26
31
|
}
|
|
27
32
|
};
|
|
28
33
|
|
|
@@ -2,6 +2,7 @@ import URI from 'urijs';
|
|
|
2
2
|
import { translate as __, documentLocale } from 'foremanReact/common/I18n';
|
|
3
3
|
import humanizeDuration from 'humanize-duration';
|
|
4
4
|
import { isoCompatibleDate } from 'foremanReact/common/helpers';
|
|
5
|
+
import { MS_PER_SECOND } from 'foremanReact/constants';
|
|
5
6
|
import { convertDashboardQuery } from '../TaskActions/TaskActionHelpers';
|
|
6
7
|
|
|
7
8
|
export const updateURlQuery = (query, history) => {
|
|
@@ -51,7 +52,7 @@ export const getDuration = (start, finish) => {
|
|
|
51
52
|
const duration = finishDate - startDate;
|
|
52
53
|
return {
|
|
53
54
|
text:
|
|
54
|
-
duration > 0 && duration <
|
|
55
|
+
duration > 0 && duration < MS_PER_SECOND
|
|
55
56
|
? __('Less than a second')
|
|
56
57
|
: humanizeDuration(duration, dateOptions),
|
|
57
58
|
};
|
|
@@ -5,49 +5,59 @@ import {
|
|
|
5
5
|
ExclamationCircleIcon,
|
|
6
6
|
ExclamationTriangleIcon,
|
|
7
7
|
QuestionCircleIcon,
|
|
8
|
+
InProgressIcon,
|
|
8
9
|
} from '@patternfly/react-icons';
|
|
9
10
|
import { translate as __ } from 'foremanReact/common/I18n';
|
|
10
11
|
|
|
12
|
+
const RESULT_ICONS = {
|
|
13
|
+
success: {
|
|
14
|
+
status: 'success',
|
|
15
|
+
title: () => __('Success'),
|
|
16
|
+
IconComponent: CheckCircleIcon,
|
|
17
|
+
},
|
|
18
|
+
error: {
|
|
19
|
+
status: 'danger',
|
|
20
|
+
title: () => __('Error'),
|
|
21
|
+
IconComponent: ExclamationCircleIcon,
|
|
22
|
+
},
|
|
23
|
+
warning: {
|
|
24
|
+
status: 'warning',
|
|
25
|
+
title: () => __('Warning'),
|
|
26
|
+
IconComponent: ExclamationTriangleIcon,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const UNKNOWN_RESULT_ICON = {
|
|
31
|
+
status: undefined,
|
|
32
|
+
title: () => __('Unknown'),
|
|
33
|
+
IconComponent: QuestionCircleIcon,
|
|
34
|
+
};
|
|
35
|
+
|
|
11
36
|
/**
|
|
12
37
|
* Icon reflecting task state/result (aligned with TaskInfo / tasks table).
|
|
13
38
|
*
|
|
14
39
|
* @param {string} state Dynflow task state (e.g. stopped, running).
|
|
15
40
|
* @param {string} [result] Result when stopped (success, error, warning, …).
|
|
41
|
+
* @param {boolean} isTitleIcon Whether the icon should be used as a title icon.
|
|
16
42
|
* @returns {React.ReactElement}
|
|
17
43
|
*/
|
|
18
|
-
export const taskResultIconEl = (state, result) => {
|
|
44
|
+
export const taskResultIconEl = (state, result, isTitleIcon = false) => {
|
|
45
|
+
const size = isTitleIcon ? 'lg' : 'md';
|
|
46
|
+
|
|
19
47
|
if (state && state !== 'stopped') {
|
|
20
48
|
return (
|
|
21
|
-
<Icon title={__('Running')}>
|
|
22
|
-
<
|
|
49
|
+
<Icon title={__('Running')} status="info" isInline size={size}>
|
|
50
|
+
<InProgressIcon />
|
|
23
51
|
</Icon>
|
|
24
52
|
);
|
|
25
53
|
}
|
|
26
54
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<Icon status="danger" title={__('Error')}>
|
|
37
|
-
<ExclamationCircleIcon />
|
|
38
|
-
</Icon>
|
|
39
|
-
);
|
|
40
|
-
case 'warning':
|
|
41
|
-
return (
|
|
42
|
-
<Icon status="warning" title={__('Warning')}>
|
|
43
|
-
<ExclamationTriangleIcon />
|
|
44
|
-
</Icon>
|
|
45
|
-
);
|
|
46
|
-
default:
|
|
47
|
-
return (
|
|
48
|
-
<Icon title={__('Unknown')}>
|
|
49
|
-
<QuestionCircleIcon />
|
|
50
|
-
</Icon>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
55
|
+
const { status, title, IconComponent } =
|
|
56
|
+
RESULT_ICONS[result] || UNKNOWN_RESULT_ICON;
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<Icon title={title()} status={status} isInline size={size}>
|
|
60
|
+
<IconComponent />
|
|
61
|
+
</Icon>
|
|
62
|
+
);
|
|
53
63
|
};
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman-tasks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 13.
|
|
4
|
+
version: 13.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ivan Nečas
|
|
@@ -511,7 +511,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
511
511
|
- !ruby/object:Gem::Version
|
|
512
512
|
version: '0'
|
|
513
513
|
requirements: []
|
|
514
|
-
rubygems_version: 4.0.
|
|
514
|
+
rubygems_version: 4.0.16
|
|
515
515
|
specification_version: 4
|
|
516
516
|
summary: Foreman plugin for showing tasks information for resources and users
|
|
517
517
|
test_files:
|