Skip to content

Commit 82b2810

Browse files
authored
Merge branch 'main' into xormigrate
2 parents 3bad064 + 3269b04 commit 82b2810

File tree

4 files changed

+94
-27
lines changed

4 files changed

+94
-27
lines changed

modules/actions/task_state.go

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,32 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
1818
return fullStepsOfEmptySteps(task)
1919
}
2020

21-
firstStep := task.Steps[0]
21+
// firstStep is the first step that has run or running, not include preStep.
22+
// For example,
23+
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): firstStep is step1.
24+
// 2. preStep(Success) -> step1(Skipped) -> step2(Success) -> postStep(Success): firstStep is step2.
25+
// 3. preStep(Success) -> step1(Running) -> step2(Waiting) -> postStep(Waiting): firstStep is step1.
26+
// 4. preStep(Success) -> step1(Skipped) -> step2(Skipped) -> postStep(Skipped): firstStep is nil.
27+
// 5. preStep(Success) -> step1(Cancelled) -> step2(Cancelled) -> postStep(Cancelled): firstStep is nil.
28+
var firstStep *actions_model.ActionTaskStep
29+
// lastHasRunStep is the last step that has run.
30+
// For example,
31+
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
32+
// 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
33+
// 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
34+
// So its Stopped is the Started of postStep when there are no more steps to run.
35+
var lastHasRunStep *actions_model.ActionTaskStep
36+
2237
var logIndex int64
38+
for _, step := range task.Steps {
39+
if firstStep == nil && (step.Status.HasRun() || step.Status.IsRunning()) {
40+
firstStep = step
41+
}
42+
if step.Status.HasRun() {
43+
lastHasRunStep = step
44+
}
45+
logIndex += step.LogLength
46+
}
2347

2448
preStep := &actions_model.ActionTaskStep{
2549
Name: preStepName,
@@ -28,32 +52,17 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
2852
Status: actions_model.StatusRunning,
2953
}
3054

31-
if firstStep.Status.HasRun() || firstStep.Status.IsRunning() {
55+
// No step has run or is running, so preStep is equal to the task
56+
if firstStep == nil {
57+
preStep.Stopped = task.Stopped
58+
preStep.Status = task.Status
59+
} else {
3260
preStep.LogLength = firstStep.LogIndex
3361
preStep.Stopped = firstStep.Started
3462
preStep.Status = actions_model.StatusSuccess
35-
} else if task.Status.IsDone() {
36-
preStep.Stopped = task.Stopped
37-
preStep.Status = actions_model.StatusFailure
38-
if task.Status.IsSkipped() {
39-
preStep.Status = actions_model.StatusSkipped
40-
}
4163
}
4264
logIndex += preStep.LogLength
4365

44-
// lastHasRunStep is the last step that has run.
45-
// For example,
46-
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
47-
// 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
48-
// 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
49-
// So its Stopped is the Started of postStep when there are no more steps to run.
50-
var lastHasRunStep *actions_model.ActionTaskStep
51-
for _, step := range task.Steps {
52-
if step.Status.HasRun() {
53-
lastHasRunStep = step
54-
}
55-
logIndex += step.LogLength
56-
}
5766
if lastHasRunStep == nil {
5867
lastHasRunStep = preStep
5968
}

modules/actions/task_state_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,25 @@ func TestFullSteps(t *testing.T) {
137137
{Name: postStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
138138
},
139139
},
140+
{
141+
name: "first step is skipped",
142+
task: &actions_model.ActionTask{
143+
Steps: []*actions_model.ActionTaskStep{
144+
{Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
145+
{Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
146+
},
147+
Status: actions_model.StatusSuccess,
148+
Started: 10000,
149+
Stopped: 10100,
150+
LogLength: 100,
151+
},
152+
want: []*actions_model.ActionTaskStep{
153+
{Name: preStepName, Status: actions_model.StatusSuccess, LogIndex: 0, LogLength: 10, Started: 10000, Stopped: 10010},
154+
{Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
155+
{Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
156+
{Name: postStepName, Status: actions_model.StatusSuccess, LogIndex: 90, LogLength: 10, Started: 10090, Stopped: 10100},
157+
},
158+
},
140159
}
141160
for _, tt := range tests {
142161
t.Run(tt.name, func(t *testing.T) {

routers/web/repo/editor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
317317
case git.EntryModeBlob:
318318
ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path), tplEditFile, &form)
319319
default:
320-
ctx.Error(http.StatusInternalServerError, err.Error())
320+
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_invalid", fileErr.Path), tplEditFile, &form)
321321
}
322322
} else {
323323
ctx.Error(http.StatusInternalServerError, err.Error())

web_src/js/features/repo-editor.ts

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,62 @@ export function initRepoEditor() {
7575
}
7676
filenameInput.addEventListener('input', function () {
7777
const parts = filenameInput.value.split('/');
78+
const links = Array.from(document.querySelectorAll('.breadcrumb span.section'));
79+
const dividers = Array.from(document.querySelectorAll('.breadcrumb .breadcrumb-divider'));
80+
let warningDiv = document.querySelector('.ui.warning.message.flash-message.flash-warning.space-related');
81+
let containSpace = false;
7882
if (parts.length > 1) {
7983
for (let i = 0; i < parts.length; ++i) {
8084
const value = parts[i];
85+
const trimValue = value.trim();
86+
if (trimValue === '..') {
87+
// remove previous tree path
88+
if (links.length > 0) {
89+
const link = links.pop();
90+
const divider = dividers.pop();
91+
link.remove();
92+
divider.remove();
93+
}
94+
continue;
95+
}
8196
if (i < parts.length - 1) {
82-
if (value.length) {
83-
filenameInput.before(createElementFromHTML(
97+
if (trimValue.length) {
98+
const linkElement = createElementFromHTML(
8499
`<span class="section"><a href="#">${htmlEscape(value)}</a></span>`,
85-
));
86-
filenameInput.before(createElementFromHTML(
100+
);
101+
const dividerElement = createElementFromHTML(
87102
`<div class="breadcrumb-divider">/</div>`,
88-
));
103+
);
104+
links.push(linkElement);
105+
dividers.push(dividerElement);
106+
filenameInput.before(linkElement);
107+
filenameInput.before(dividerElement);
89108
}
90109
} else {
91110
filenameInput.value = value;
92111
}
93112
this.setSelectionRange(0, 0);
113+
containSpace |= (trimValue !== value && trimValue !== '');
114+
}
115+
}
116+
containSpace |= Array.from(links).some((link) => {
117+
const value = link.querySelector('a').textContent;
118+
return value.trim() !== value;
119+
});
120+
containSpace |= parts[parts.length - 1].trim() !== parts[parts.length - 1];
121+
if (containSpace) {
122+
if (!warningDiv) {
123+
warningDiv = document.createElement('div');
124+
warningDiv.classList.add('ui', 'warning', 'message', 'flash-message', 'flash-warning', 'space-related');
125+
warningDiv.innerHTML = '<p>File path contains leading or trailing whitespace.</p>';
126+
// Add display 'block' because display is set to 'none' in formantic\build\semantic.css
127+
warningDiv.style.display = 'block';
128+
const inputContainer = document.querySelector('.repo-editor-header');
129+
inputContainer.insertAdjacentElement('beforebegin', warningDiv);
94130
}
131+
showElem(warningDiv);
132+
} else if (warningDiv) {
133+
hideElem(warningDiv);
95134
}
96135
joinTreePath();
97136
});

0 commit comments

Comments
 (0)