grim/youtrack-import
Clone
Summary
Browse
Changes
Graph
use `unset` as the value when a state is moving to/from an unknown states. Fixes YI-27
2020-01-17, Gary Kramlich
741af4ca4d62
use `unset` as the value when a state is moving to/from an unknown states. Fixes YI-27
package
youtrack
import
(
"bytes"
"encoding/xml"
"fmt"
"net/http"
"time"
)
type
Issue
struct
{
Number
int
Summary
string
Description
string
Created
time
.
Time
Updated
time
.
Time
UpdatedBy
string
Resolved
time
.
Time
Reporter
string
Assignee
string
Voters
[]
string
Watchers
[]
string
PermittedGroup
string
Markdown
bool
Version
string
Subsystem
string
Priority
string
Type
string
State
string
Comments
[]
*
Comment
Attachments
[]
*
Attachment
}
func
(
i
*
Issue
)
extractAttachments
()
error
{
if
i
.
Markdown
{
modified
,
attachments
,
err
:=
extractAttachments
(
i
.
Number
,
i
.
Reporter
,
i
.
Description
,
i
.
Created
,
)
if
err
!=
nil
{
return
err
}
if
len
(
attachments
)
>
0
{
i
.
Description
=
modified
i
.
Attachments
=
append
(
i
.
Attachments
,
attachments
...
)
}
}
for
_
,
comment
:=
range
i
.
Comments
{
if
err
:=
comment
.
extractAttachments
(
i
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
(
i
*
Issue
)
encode
()
xmlIssue
{
x
:=
xmlIssue
{}
// required fields
x
.
AddField
(
"numberInProject"
,
fmt
.
Sprintf
(
"%d"
,
i
.
Number
))
x
.
AddField
(
"summary"
,
i
.
Summary
)
x
.
AddField
(
"reporterName"
,
i
.
Reporter
)
x
.
AddField
(
"Assignee"
,
i
.
Assignee
)
x
.
AddField
(
"Type"
,
i
.
Type
)
x
.
AddField
(
"Priority"
,
i
.
Priority
)
x
.
AddField
(
"State"
,
i
.
State
)
// optional fields
if
i
.
Markdown
{
x
.
AddField
(
"markdown"
,
"true"
)
}
if
!
i
.
Created
.
IsZero
()
{
x
.
AddField
(
"created"
,
formatTimeString
(
i
.
Created
))
}
if
i
.
Description
!=
""
{
x
.
AddField
(
"description"
,
i
.
Description
)
}
if
!
i
.
Updated
.
IsZero
()
{
x
.
AddField
(
"updated"
,
formatTimeString
(
i
.
Updated
))
}
if
i
.
UpdatedBy
!=
""
{
x
.
AddField
(
"updaterName"
,
i
.
UpdatedBy
)
}
if
!
i
.
Resolved
.
IsZero
()
{
x
.
AddField
(
"resolved"
,
fmt
.
Sprintf
(
"%d"
,
i
.
Resolved
.
Unix
()))
}
if
len
(
i
.
Voters
)
>
0
{
x
.
AddFieldSlice
(
"voterName"
,
i
.
Voters
)
}
if
len
(
i
.
Watchers
)
>
0
{
x
.
AddFieldSlice
(
"watcherName"
,
i
.
Watchers
)
}
if
i
.
PermittedGroup
!=
""
{
x
.
AddField
(
"permittedGroup"
,
i
.
PermittedGroup
)
}
if
i
.
Version
!=
""
{
x
.
AddField
(
"Fix Versions"
,
i
.
Version
)
}
if
i
.
Subsystem
!=
""
{
x
.
AddField
(
"Subsystem"
,
i
.
Subsystem
)
}
sortComments
(
i
.
Comments
)
for
_
,
c
:=
range
i
.
Comments
{
x
.
AddComment
(
c
.
Author
,
c
.
Text
,
c
.
Created
,
c
.
Updated
,
c
.
Markdown
)
}
return
x
}
func
(
c
*
Client
)
importIssuesRange
(
p
*
Project
,
s
,
e
int
)
error
{
issues
:=
&
xmlIssues
{}
issues
.
Issues
=
make
([]
xmlIssue
,
e
-
s
)
for
i
:=
s
;
i
<
e
;
i
++
{
if
err
:=
p
.
Issues
[
i
].
extractAttachments
();
err
!=
nil
{
return
err
}
issues
.
Issues
[
i
-
s
]
=
p
.
Issues
[
i
].
encode
()
}
// convert the datastructure to an xml string
data
,
err
:=
xml
.
Marshal
(
issues
)
if
err
!=
nil
{
return
err
}
// create the reader for the put request
putBody
:=
bytes
.
NewReader
(
data
)
resp
,
err
:=
c
.
xmlRequest
(
http
.
MethodPut
,
c
.
uri
+
"/import/"
+
p
.
ID
+
"/issues"
,
putBody
,
)
if
err
!=
nil
{
return
err
}
defer
resp
.
Body
.
Close
()
return
c
.
validateXmlImportReport
(
[]
int
{
http
.
StatusOK
,
http
.
StatusBadRequest
},
resp
,
)
}
func
(
c
*
Client
)
ImportIssues
(
p
*
Project
)
error
{
r
:=
10
for
s
:=
0
;
s
<
len
(
p
.
Issues
);
s
+=
r
{
e
:=
s
+
r
if
e
>
len
(
p
.
Issues
)
{
e
=
len
(
p
.
Issues
)
}
fmt
.
Printf
(
"importing issues %d-%d ... "
,
s
,
e
-
1
)
if
err
:=
c
.
importIssuesRange
(
p
,
s
,
e
);
err
!=
nil
{
fmt
.
Printf
(
"failed.\n"
)
return
err
}
fmt
.
Printf
(
"done.\n"
)
}
return
nil
}