Skip to content

Commit e0fdd84

Browse files
fix(linker): handle empty pr issue regexp
Signed-off-by: Matan Ryngler <matan.r@wonderful.ai>
1 parent 9e659ab commit e0fdd84

5 files changed

Lines changed: 135 additions & 7 deletions

File tree

backend/plugins/linker/impl/impl.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package impl
2020
import (
2121
"encoding/json"
2222
"regexp"
23+
"strings"
2324

2425
"github.com/apache/incubator-devlake/core/dal"
2526
"github.com/apache/incubator-devlake/core/errors"
@@ -84,13 +85,11 @@ func (p Linker) PrepareTaskData(taskCtx plugin.TaskContext, options map[string]i
8485
taskData := &tasks.LinkerTaskData{
8586
Options: op,
8687
}
87-
if op.PrToIssueRegexp != "" {
88-
re, err := regexp.Compile(op.PrToIssueRegexp)
89-
if err != nil {
90-
return taskData, errors.Convert(err)
91-
}
92-
taskData.PrToIssueRegexp = re
88+
re, compileErr := regexp.Compile(op.PrToIssueRegexp)
89+
if compileErr != nil {
90+
return taskData, errors.Convert(compileErr)
9391
}
92+
taskData.PrToIssueRegexp = re
9493
return taskData, nil
9594
}
9695

@@ -109,6 +108,10 @@ func (p Linker) MakeMetricPluginPipelinePlanV200(projectName string, options jso
109108
if err != nil {
110109
return nil, errors.Default.WrapRaw(err)
111110
}
111+
op.PrToIssueRegexp = strings.TrimSpace(op.PrToIssueRegexp)
112+
if op.PrToIssueRegexp == "" {
113+
return nil, nil
114+
}
112115
plan := coreModels.PipelinePlan{
113116
{
114117
{
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package impl
19+
20+
import (
21+
"encoding/json"
22+
"testing"
23+
24+
coreModels "github.com/apache/incubator-devlake/core/models"
25+
"github.com/stretchr/testify/assert"
26+
)
27+
28+
func TestMakeMetricPluginPipelinePlanV200SkipsEmptyRegexp(t *testing.T) {
29+
var linker Linker
30+
31+
plan, err := linker.MakeMetricPluginPipelinePlanV200("project", json.RawMessage(`{}`))
32+
33+
assert.Nil(t, err)
34+
assert.Nil(t, plan)
35+
}
36+
37+
func TestMakeMetricPluginPipelinePlanV200BuildsPlan(t *testing.T) {
38+
var linker Linker
39+
options, err := json.Marshal(map[string]string{
40+
"prToIssueRegexp": `#(\d+)`,
41+
})
42+
assert.Nil(t, err)
43+
44+
plan, err := linker.MakeMetricPluginPipelinePlanV200("project", options)
45+
46+
assert.Nil(t, err)
47+
assert.Equal(t, coreModels.PipelinePlan{
48+
{
49+
{
50+
Plugin: "linker",
51+
Options: map[string]interface{}{
52+
"projectName": "project",
53+
"prToIssueRegexp": `#(\d+)`,
54+
},
55+
Subtasks: []string{
56+
"LinkPrToIssue",
57+
},
58+
},
59+
},
60+
}, plan)
61+
}
62+
63+
func TestPrepareTaskDataRejectsEmptyRegexp(t *testing.T) {
64+
var linker Linker
65+
66+
taskData, err := linker.PrepareTaskData(nil, map[string]interface{}{
67+
"projectName": "project",
68+
"prToIssueRegexp": "",
69+
})
70+
71+
assert.NotNil(t, err)
72+
assert.Nil(t, taskData)
73+
}

backend/plugins/linker/tasks/link_pr_and_issue.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ func clearHistoryData(db dal.Dal, data *LinkerTaskData) errors.Error {
7474
func LinkPrToIssue(taskCtx plugin.SubTaskContext) errors.Error {
7575
db := taskCtx.GetDal()
7676
data := taskCtx.GetData().(*LinkerTaskData)
77+
if data.PrToIssueRegexp == nil {
78+
return errors.BadInput.New("prToIssueRegexp is required")
79+
}
7780

7881
if err := clearHistoryData(db, data); err != nil {
7982
return err

backend/plugins/linker/tasks/task_data.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ limitations under the License.
1818
package tasks
1919

2020
import (
21+
"regexp"
22+
"strings"
23+
2124
"github.com/apache/incubator-devlake/core/errors"
2225
helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
23-
"regexp"
2426
)
2527

2628
type LinkerOptions struct {
@@ -39,5 +41,9 @@ func DecodeAndValidateTaskOptions(options map[string]interface{}) (*LinkerOption
3941
if err != nil {
4042
return nil, errors.Default.Wrap(err, "error decoding linker task options")
4143
}
44+
op.PrToIssueRegexp = strings.TrimSpace(op.PrToIssueRegexp)
45+
if op.PrToIssueRegexp == "" {
46+
return nil, errors.BadInput.New("prToIssueRegexp is required")
47+
}
4248
return &op, nil
4349
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package tasks
19+
20+
import (
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
func TestDecodeAndValidateTaskOptionsRequiresPrToIssueRegexp(t *testing.T) {
27+
options, err := DecodeAndValidateTaskOptions(map[string]interface{}{
28+
"projectName": "project",
29+
})
30+
31+
assert.NotNil(t, err)
32+
assert.Nil(t, options)
33+
}
34+
35+
func TestDecodeAndValidateTaskOptionsTrimsPrToIssueRegexp(t *testing.T) {
36+
options, err := DecodeAndValidateTaskOptions(map[string]interface{}{
37+
"projectName": "project",
38+
"prToIssueRegexp": " #(\\d+) ",
39+
})
40+
41+
assert.Nil(t, err)
42+
assert.Equal(t, "#(\\d+)", options.PrToIssueRegexp)
43+
}

0 commit comments

Comments
 (0)