Merge branch 'master' into refactor_issues-subscription

This commit is contained in:
6543 2019-11-01 05:17:19 +01:00 committed by GitHub
commit 47ba722e19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
210 changed files with 7170 additions and 4719 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ _test
# MS VSCode # MS VSCode
.vscode .vscode
__debug_bin
# Architecture specific extensions/prefixes # Architecture specific extensions/prefixes
*.[568vq] *.[568vq]

View File

@ -4,6 +4,32 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.10.0-RC2](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc2) - 2019-10-30
* BREAKING
* Fix deadline on update issue or PR via API (#8698)
* Hide some user information via API if user doesn't have enough permission (#8655) (#8657)
* BUGFIXES
* Expose db.SetMaxOpenConns and allow non MySQL dbs to set conn pool params (#8528) (#8618)
* Fix milestone close timestamp (#8728) (#8730)
* Fix 500 when getting user as unauthenticated user (#8653) (#8663)
* Fix 'New Issue Missing Milestone Comment' (#8678) (#8681)
* Use AppSubUrl for more redirections (#8647) (#8651)
* Add SubURL to redirect path (#8632) (#8634)
* Fix template error on account page (#8562) (#8622)
* Allow externalID to be UUID (#8551) (#8624)
* Prevent removal of non-empty emoji panel following selection of duplicate (#8609) (#8623)
* Update heatmap fixtures to restore tests (#8615) (#8616)
* Ensure that diff stats can scroll independently of the diff (#8581) (#8621)
* Webhook: set Content-Type for application/x-www-form-urlencoded (#8600)
* Fix #8582 by handling empty repos (#8587) (#8594)
* Fix bug on pull requests when transfer head repository (#8564) (#8569)
* Add missed close in ServeBlobLFS (#8527) (#8542)
* Ensure that GitRepo is set on Empty repositories (#8539) (#8541)
* Fix migrate mirror 500 bug (#8526) (#8530)
* Fix password complexity regex for special characters (#8524)
* Prevent .code-view from overriding font on icon fonts (#8614) (#8627)
* Allow more than 255 characters for tokens in external_login_user table (#8554)
## [1.10.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc1) - 2019-10-14 ## [1.10.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc1) - 2019-10-14
* BREAKING * BREAKING
* Remove legacy handling of drone token (#8191) * Remove legacy handling of drone token (#8191)
@ -263,6 +289,30 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243) * wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243)
* Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141) * Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141)
## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30
* BREAKING
* Hide some user information via API if user doesn't have enough permission (#8655) (#8658)
* BUGFIXES
* Fix milestone close timestamp (#8728) (#8731)
* Fix deadline on update issue or PR via API (#8699)
* Fix 'New Issue Missing Milestone Comment' (#8678) (#8682)
* Fix 500 when getting user as unauthenticated user (#8653) (#8662)
* Use AppSubUrl for more redirections (#8647) (#8652)
* Add SubURL to redirect path (#8632) (#8634) (#8640)
* Fix #8582 by handling empty repos (#8587) (#8593)
* Fix bug on pull requests when transfer head repository (#8571)
* Add missed close in ServeBlobLFS (#8527) (#8543)
* Return false if provided branch name is empty for IsBranchExist (#8485) (#8492)
* Create .ssh dir as necessary (#8369) (#8486) (#8489)
* Restore functionality for early gits (#7775) (#8476)
* Add check for empty set when dropping indexes during migration (#8475)
* Ensure Request Body Readers are closed in LFS server (#8454) (#8459)
* Ensure that LFS files are relative to the LFS content path (#8455) (#8458)
* SECURITY
* Ignore mentions for users with no access (#8395) (#8484)
* TESTING
* Update heatmap fixtures to restore tests (#8615) (#8617)
## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08 ## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08
* BUGFIXES * BUGFIXES
* Highlight issue references (#8101) (#8404) * Highlight issue references (#8101) (#8404)

View File

@ -66,7 +66,7 @@ var (
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "must-change-password", Name: "must-change-password",
Usage: "Force the user to change his/her password after initial login", Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
}, },
cli.IntFlag{ cli.IntFlag{
Name: "random-password-length", Name: "random-password-length",

View File

@ -69,6 +69,10 @@ MAX_FILES = 5
[repository.pull-request] [repository.pull-request]
; List of prefixes used in Pull Request title to mark them as Work In Progress ; List of prefixes used in Pull Request title to mark them as Work In Progress
WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]
; List of keywords used in Pull Request comments to automatically close a related issue
CLOSE_KEYWORDS=close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved
; List of keywords used in Pull Request comments to automatically reopen a related issue
REOPEN_KEYWORDS=reopen,reopens,reopened
[repository.issue] [repository.issue]
; List of reasons why a Pull Request or Issue can be locked ; List of reasons why a Pull Request or Issue can be locked
@ -475,6 +479,8 @@ DEFAULT_ORG_MEMBER_VISIBLE = false
; Default value for EnableDependencies ; Default value for EnableDependencies
; Repositories will use dependencies by default depending on this setting ; Repositories will use dependencies by default depending on this setting
DEFAULT_ENABLE_DEPENDENCIES = true DEFAULT_ENABLE_DEPENDENCIES = true
; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true
; Enable heatmap on users profiles. ; Enable heatmap on users profiles.
ENABLE_USER_HEATMAP = true ENABLE_USER_HEATMAP = true
; Enable Timetracking ; Enable Timetracking

View File

@ -71,6 +71,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request - `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request
title to mark them as Work In Progress title to mark them as Work In Progress
- `CLOSE_KEYWORDS`: **close**, **closes**, **closed**, **fix**, **fixes**, **fixed**, **resolve**, **resolves**, **resolved**: List of
keywords used in Pull Request comments to automatically close a related issue
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
a related issue
### Repository - Issue (`repository.issue`) ### Repository - Issue (`repository.issue`)
@ -293,6 +297,7 @@ relation to port exhaustion.
- `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha.
- `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net. - `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net.
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default. - `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles. - `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register - `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
on this instance. on this instance.

9
go.mod
View File

@ -22,7 +22,6 @@ require (
github.com/blevesearch/go-porterstemmer v0.0.0-20141230013033-23a2c8e5cf1f // indirect github.com/blevesearch/go-porterstemmer v0.0.0-20141230013033-23a2c8e5cf1f // indirect
github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc // indirect github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc // indirect
github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26 // indirect github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26 // indirect
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f
github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe // indirect github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe // indirect
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
@ -73,6 +72,7 @@ require (
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
github.com/niklasfasching/go-org v0.1.7
github.com/oliamb/cutter v0.2.2 github.com/oliamb/cutter v0.2.2
github.com/philhofer/fwd v1.0.0 // indirect github.com/philhofer/fwd v1.0.0 // indirect
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
@ -80,12 +80,13 @@ require (
github.com/prometheus/client_golang v1.1.0 github.com/prometheus/client_golang v1.1.0
github.com/prometheus/procfs v0.0.4 // indirect github.com/prometheus/procfs v0.0.4 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff github.com/russross/blackfriday v2.0.0+incompatible // indirect
github.com/russross/blackfriday/v2 v2.0.1
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid v1.2.0
github.com/sergi/go-diff v1.0.0 github.com/sergi/go-diff v1.0.0
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/steveyen/gtreap v0.0.0-20150807155958-0abe01ef9be2 // indirect github.com/steveyen/gtreap v0.0.0-20150807155958-0abe01ef9be2 // indirect
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
@ -100,7 +101,7 @@ require (
github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 // indirect github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 // indirect
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53 github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b
golang.org/x/text v0.3.2 golang.org/x/text v0.3.2

16
go.sum
View File

@ -86,8 +86,6 @@ github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26/go.mod h1:paBWMc
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA=
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f/go.mod h1:6QaC0vFoKWYDth94dHFNgRT2YkT5FHdQp/Yx15aAAi0=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/corbym/gocrest v1.0.3 h1:gwEdq6RkTmq+09CTuM29DfKOCtZ7G7bcyxs3IZ6EVdU= github.com/corbym/gocrest v1.0.3 h1:gwEdq6RkTmq+09CTuM29DfKOCtZ7G7bcyxs3IZ6EVdU=
github.com/corbym/gocrest v1.0.3/go.mod h1:maVFL5lbdS2PgfOQgGRWDYTeunSWQeiEgoNdTABShCs= github.com/corbym/gocrest v1.0.3/go.mod h1:maVFL5lbdS2PgfOQgGRWDYTeunSWQeiEgoNdTABShCs=
@ -425,6 +423,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8=
github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
github.com/niklasfasching/go-org v0.1.7 h1:t3V+3XnS/7BhKv/7SlMUa8FvAiq577/a1T3D7mLIRXE=
github.com/niklasfasching/go-org v0.1.7/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k= github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU= github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
@ -487,8 +489,10 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff h1:g9ZlAHmkc/h5So+OjNCkZWh+FjuKEOOOoyRkqlGA8+c= github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
@ -499,6 +503,8 @@ github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnP
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE= github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
@ -650,6 +656,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc= golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss=
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=

View File

@ -9,6 +9,7 @@ import (
"path" "path"
"regexp" "regexp"
"sort" "sort"
"strconv"
"strings" "strings"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -378,6 +379,12 @@ func (issue *Issue) apiFormat(e Engine) *api.Issue {
Updated: issue.UpdatedUnix.AsTime(), Updated: issue.UpdatedUnix.AsTime(),
} }
apiIssue.Repo = &api.RepositoryMeta{
ID: issue.Repo.ID,
Name: issue.Repo.Name,
FullName: issue.Repo.FullName(),
}
if issue.ClosedUnix != 0 { if issue.ClosedUnix != 0 {
apiIssue.Closed = issue.ClosedUnix.AsTimePtr() apiIssue.Closed = issue.ClosedUnix.AsTimePtr()
} }
@ -750,7 +757,6 @@ func (issue *Issue) UpdateAttachments(uuids []string) (err error) {
// ChangeContent changes issue content, as the given user. // ChangeContent changes issue content, as the given user.
func (issue *Issue) ChangeContent(doer *User, content string) (err error) { func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
oldContent := issue.Content
issue.Content = content issue.Content = content
sess := x.NewSession() sess := x.NewSession()
@ -769,47 +775,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return err return err
} }
if err = sess.Commit(); err != nil { return sess.Commit()
return err
}
sess.Close()
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
}
if err != nil {
log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
go HookQueue.Add(issue.RepoID)
}
return nil
} }
// GetTasks returns the amount of tasks in the issues content // GetTasks returns the amount of tasks in the issues content
@ -1088,11 +1054,13 @@ type IssuesOptions struct {
LabelIDs []int64 LabelIDs []int64
SortType string SortType string
IssueIDs []int64 IssueIDs []int64
// prioritize issues from this repo
PriorityRepoID int64
} }
// sortIssuesSession sort an issues-related session based on the provided // sortIssuesSession sort an issues-related session based on the provided
// sortType string // sortType string
func sortIssuesSession(sess *xorm.Session, sortType string) { func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64) {
switch sortType { switch sortType {
case "oldest": case "oldest":
sess.Asc("issue.created_unix") sess.Asc("issue.created_unix")
@ -1110,6 +1078,8 @@ func sortIssuesSession(sess *xorm.Session, sortType string) {
sess.Asc("issue.deadline_unix") sess.Asc("issue.deadline_unix")
case "farduedate": case "farduedate":
sess.Desc("issue.deadline_unix") sess.Desc("issue.deadline_unix")
case "priorityrepo":
sess.OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 ELSE 2 END, issue.created_unix DESC")
default: default:
sess.Desc("issue.created_unix") sess.Desc("issue.created_unix")
} }
@ -1211,7 +1181,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
defer sess.Close() defer sess.Close()
opts.setupSession(sess) opts.setupSession(sess)
sortIssuesSession(sess, opts.SortType) sortIssuesSession(sess, opts.SortType, opts.PriorityRepoID)
issues := make([]*Issue, 0, setting.UI.IssuePagingNum) issues := make([]*Issue, 0, setting.UI.IssuePagingNum)
if err := sess.Find(&issues); err != nil { if err := sess.Find(&issues); err != nil {
@ -1517,8 +1487,8 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen
} }
// SearchIssueIDsByKeyword search issues on database // SearchIssueIDsByKeyword search issues on database
func SearchIssueIDsByKeyword(kw string, repoID int64, limit, start int) (int64, []int64, error) { func SearchIssueIDsByKeyword(kw string, repoIDs []int64, limit, start int) (int64, []int64, error) {
var repoCond = builder.Eq{"repo_id": repoID} var repoCond = builder.In("repo_id", repoIDs)
var subQuery = builder.Select("id").From("issue").Where(repoCond) var subQuery = builder.Select("id").From("issue").Where(repoCond)
var cond = builder.And( var cond = builder.And(
repoCond, repoCond,
@ -1607,33 +1577,43 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *Us
return sess.Commit() return sess.Commit()
} }
// DependencyInfo represents high level information about an issue which is a dependency of another issue.
type DependencyInfo struct {
Issue `xorm:"extends"`
Repository `xorm:"extends"`
}
// Get Blocked By Dependencies, aka all issues this issue is blocked by. // Get Blocked By Dependencies, aka all issues this issue is blocked by.
func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*Issue, err error) { func (issue *Issue) getBlockedByDependencies(e Engine) (issueDeps []*DependencyInfo, err error) {
return issueDeps, e. return issueDeps, e.
Table("issue_dependency"). Table("issue").
Select("issue.*"). Join("INNER", "repository", "repository.id = issue.repo_id").
Join("INNER", "issue", "issue.id = issue_dependency.dependency_id"). Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id").
Where("issue_id = ?", issue.ID). Where("issue_id = ?", issue.ID).
//sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC").
Find(&issueDeps) Find(&issueDeps)
} }
// Get Blocking Dependencies, aka all issues this issue blocks. // Get Blocking Dependencies, aka all issues this issue blocks.
func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*Issue, err error) { func (issue *Issue) getBlockingDependencies(e Engine) (issueDeps []*DependencyInfo, err error) {
return issueDeps, e. return issueDeps, e.
Table("issue_dependency"). Table("issue").
Select("issue.*"). Join("INNER", "repository", "repository.id = issue.repo_id").
Join("INNER", "issue", "issue.id = issue_dependency.issue_id"). Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id").
Where("dependency_id = ?", issue.ID). Where("dependency_id = ?", issue.ID).
//sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC").
Find(&issueDeps) Find(&issueDeps)
} }
// BlockedByDependencies finds all Dependencies an issue is blocked by // BlockedByDependencies finds all Dependencies an issue is blocked by
func (issue *Issue) BlockedByDependencies() ([]*Issue, error) { func (issue *Issue) BlockedByDependencies() ([]*DependencyInfo, error) {
return issue.getBlockedByDependencies(x) return issue.getBlockedByDependencies(x)
} }
// BlockingDependencies returns all blocking dependencies, aka all other issues a given issue blocks // BlockingDependencies returns all blocking dependencies, aka all other issues a given issue blocks
func (issue *Issue) BlockingDependencies() ([]*Issue, error) { func (issue *Issue) BlockingDependencies() ([]*DependencyInfo, error) {
return issue.getBlockingDependencies(x) return issue.getBlockingDependencies(x)
} }

View File

@ -444,6 +444,10 @@ func (c *Comment) LoadReview() error {
func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error { func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error {
// FIXME differentiate between previous and proposed line // FIXME differentiate between previous and proposed line
commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine())) commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
if err != nil && strings.Contains(err.Error(), "fatal: no such path") {
c.Invalidated = true
return UpdateComment(c, doer)
}
if err != nil { if err != nil {
return err return err
} }

View File

@ -250,6 +250,19 @@ func GetLabelIDsInRepoByNames(repoID int64, labelNames []string) ([]int64, error
Find(&labelIDs) Find(&labelIDs)
} }
// GetLabelIDsInReposByNames returns a list of labelIDs by names in one of the given
// repositories.
// it silently ignores label names that do not belong to the repository.
func GetLabelIDsInReposByNames(repoIDs []int64, labelNames []string) ([]int64, error) {
labelIDs := make([]int64, 0, len(labelNames))
return labelIDs, x.Table("label").
In("repo_id", repoIDs).
In("name", labelNames).
Asc("name").
Cols("id").
Find(&labelIDs)
}
// GetLabelInRepoByID returns a label by ID in given repository. // GetLabelInRepoByID returns a label by ID in given repository.
func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) { func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) {
return getLabelInRepoByID(x, repoID, labelID) return getLabelInRepoByID(x, repoID, labelID)

View File

@ -264,24 +264,23 @@ func TestIssue_loadTotalTimes(t *testing.T) {
func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { func TestIssue_SearchIssueIDsByKeyword(t *testing.T) {
assert.NoError(t, PrepareTestDatabase()) assert.NoError(t, PrepareTestDatabase())
total, ids, err := SearchIssueIDsByKeyword("issue2", []int64{1}, 10, 0)
total, ids, err := SearchIssueIDsByKeyword("issue2", 1, 10, 0)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, total) assert.EqualValues(t, 1, total)
assert.EqualValues(t, []int64{2}, ids) assert.EqualValues(t, []int64{2}, ids)
total, ids, err = SearchIssueIDsByKeyword("first", 1, 10, 0) total, ids, err = SearchIssueIDsByKeyword("first", []int64{1}, 10, 0)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, total) assert.EqualValues(t, 1, total)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
total, ids, err = SearchIssueIDsByKeyword("for", 1, 10, 0) total, ids, err = SearchIssueIDsByKeyword("for", []int64{1}, 10, 0)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 4, total) assert.EqualValues(t, 4, total)
assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids)
// issue1's comment id 2 // issue1's comment id 2
total, ids, err = SearchIssueIDsByKeyword("good", 1, 10, 0) total, ids, err = SearchIssueIDsByKeyword("good", []int64{1}, 10, 0)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, total) assert.EqualValues(t, 1, total)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)

View File

@ -16,7 +16,6 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -26,7 +25,6 @@ import (
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"github.com/unknwon/com" "github.com/unknwon/com"
"xorm.io/xorm"
) )
var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength) var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength)
@ -753,66 +751,6 @@ func newPullRequestAttempt(repo *Repository, pull *Issue, labelIDs []int64, uuid
return nil return nil
} }
// PullRequestsOptions holds the options for PRs
type PullRequestsOptions struct {
Page int
State string
SortType string
Labels []string
MilestoneID int64
}
func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xorm.Session, error) {
sess := x.Where("pull_request.base_repo_id=?", baseRepoID)
sess.Join("INNER", "issue", "pull_request.issue_id = issue.id")
switch opts.State {
case "closed", "open":
sess.And("issue.is_closed=?", opts.State == "closed")
}
if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil {
return nil, err
} else if len(labelIDs) > 0 {
sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id").
In("issue_label.label_id", labelIDs)
}
if opts.MilestoneID > 0 {
sess.And("issue.milestone_id=?", opts.MilestoneID)
}
return sess, nil
}
// PullRequests returns all pull requests for a base Repo by the given conditions
func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
countSession, err := listPullRequestStatement(baseRepoID, opts)
if err != nil {
log.Error("listPullRequestStatement: %v", err)
return nil, 0, err
}
maxResults, err := countSession.Count(new(PullRequest))
if err != nil {
log.Error("Count PRs: %v", err)
return nil, maxResults, err
}
prs := make([]*PullRequest, 0, ItemsPerPage)
findSession, err := listPullRequestStatement(baseRepoID, opts)
sortIssuesSession(findSession, opts.SortType)
if err != nil {
log.Error("listPullRequestStatement: %v", err)
return nil, maxResults, err
}
findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage)
return prs, maxResults, findSession.Find(&prs)
}
// GetUnmergedPullRequest returns a pull request that is open and has not been merged // GetUnmergedPullRequest returns a pull request that is open and has not been merged
// by given head/base and repo/branch. // by given head/base and repo/branch.
func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) { func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) {
@ -831,17 +769,6 @@ func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch
return pr, nil return pr, nil
} }
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
// by given head information (repo and branch).
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id = pull_request.issue_id").
Find(&prs)
}
// GetLatestPullRequestByHeadInfo returns the latest pull request (regardless of its status) // GetLatestPullRequestByHeadInfo returns the latest pull request (regardless of its status)
// by given head information (repo and branch). // by given head information (repo and branch).
func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest, error) { func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest, error) {
@ -856,17 +783,6 @@ func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest,
return pr, err return pr, err
} }
// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged
// by given base information (repo and branch).
func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Find(&prs)
}
// GetPullRequestByIndex returns a pull request by the given index // GetPullRequestByIndex returns a pull request by the given index
func GetPullRequestByIndex(repoID int64, index int64) (*PullRequest, error) { func GetPullRequestByIndex(repoID int64, index int64) (*PullRequest, error) {
pr := &PullRequest{ pr := &PullRequest{
@ -1035,72 +951,6 @@ func (pr *PullRequest) AddToTaskQueue() {
}) })
} }
// PullRequestList defines a list of pull requests
type PullRequestList []*PullRequest
func (prs PullRequestList) loadAttributes(e Engine) error {
if len(prs) == 0 {
return nil
}
// Load issues.
issueIDs := prs.getIssueIDs()
issues := make([]*Issue, 0, len(issueIDs))
if err := e.
Where("id > 0").
In("id", issueIDs).
Find(&issues); err != nil {
return fmt.Errorf("find issues: %v", err)
}
set := make(map[int64]*Issue)
for i := range issues {
set[issues[i].ID] = issues[i]
}
for i := range prs {
prs[i].Issue = set[prs[i].IssueID]
}
return nil
}
func (prs PullRequestList) getIssueIDs() []int64 {
issueIDs := make([]int64, 0, len(prs))
for i := range prs {
issueIDs = append(issueIDs, prs[i].IssueID)
}
return issueIDs
}
// LoadAttributes load all the prs attributes
func (prs PullRequestList) LoadAttributes() error {
return prs.loadAttributes(x)
}
func (prs PullRequestList) invalidateCodeComments(e Engine, doer *User, repo *git.Repository, branch string) error {
if len(prs) == 0 {
return nil
}
issueIDs := prs.getIssueIDs()
var codeComments []*Comment
if err := e.
Where("type = ? and invalidated = ?", CommentTypeCode, false).
In("issue_id", issueIDs).
Find(&codeComments); err != nil {
return fmt.Errorf("find code comments: %v", err)
}
for _, comment := range codeComments {
if err := comment.CheckInvalidation(repo, doer, branch); err != nil {
return err
}
}
return nil
}
// InvalidateCodeComments will lookup the prs for code comments which got invalidated by change
func (prs PullRequestList) InvalidateCodeComments(doer *User, repo *git.Repository, branch string) error {
return prs.invalidateCodeComments(x, doer, repo, branch)
}
// checkAndUpdateStatus checks if pull request is possible to leaving checking status, // checkAndUpdateStatus checks if pull request is possible to leaving checking status,
// and set to be either conflict or mergeable. // and set to be either conflict or mergeable.
func (pr *PullRequest) checkAndUpdateStatus() { func (pr *PullRequest) checkAndUpdateStatus() {
@ -1152,64 +1002,3 @@ func (pr *PullRequest) GetWorkInProgressPrefix() string {
} }
return "" return ""
} }
// TestPullRequests checks and tests untested patches of pull requests.
// TODO: test more pull requests at same time.
func TestPullRequests() {
prs := make([]*PullRequest, 0, 10)
err := x.Where("status = ?", PullRequestStatusChecking).Find(&prs)
if err != nil {
log.Error("Find Checking PRs: %v", err)
return
}
var checkedPRs = make(map[int64]struct{})
// Update pull request status.
for _, pr := range prs {
checkedPRs[pr.ID] = struct{}{}
if err := pr.GetBaseRepo(); err != nil {
log.Error("GetBaseRepo: %v", err)
continue
}
if pr.manuallyMerged() {
continue
}
if err := pr.testPatch(x); err != nil {
log.Error("testPatch: %v", err)
continue
}
pr.checkAndUpdateStatus()
}
// Start listening on new test requests.
for prID := range pullRequestQueue.Queue() {
log.Trace("TestPullRequests[%v]: processing test task", prID)
pullRequestQueue.Remove(prID)
id := com.StrTo(prID).MustInt64()
if _, ok := checkedPRs[id]; ok {
continue
}
pr, err := GetPullRequestByID(id)
if err != nil {
log.Error("GetPullRequestByID[%s]: %v", prID, err)
continue
} else if pr.manuallyMerged() {
continue
} else if err = pr.testPatch(x); err != nil {
log.Error("testPatch[%d]: %v", pr.ID, err)
continue
}
pr.checkAndUpdateStatus()
}
}
// InitTestPullRequests runs the task to test all the checking status pull requests
func InitTestPullRequests() {
go TestPullRequests()
}

224
models/pull_list.go Normal file
View File

@ -0,0 +1,224 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"fmt"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"github.com/unknwon/com"
"xorm.io/xorm"
)
// PullRequestsOptions holds the options for PRs
type PullRequestsOptions struct {
Page int
State string
SortType string
Labels []string
MilestoneID int64
}
func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xorm.Session, error) {
sess := x.Where("pull_request.base_repo_id=?", baseRepoID)
sess.Join("INNER", "issue", "pull_request.issue_id = issue.id")
switch opts.State {
case "closed", "open":
sess.And("issue.is_closed=?", opts.State == "closed")
}
if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil {
return nil, err
} else if len(labelIDs) > 0 {
sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id").
In("issue_label.label_id", labelIDs)
}
if opts.MilestoneID > 0 {
sess.And("issue.milestone_id=?", opts.MilestoneID)
}
return sess, nil
}
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
// by given head information (repo and branch).
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id = pull_request.issue_id").
Find(&prs)
}
// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged
// by given base information (repo and branch).
func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) {
prs := make([]*PullRequest, 0, 2)
return prs, x.
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",
repoID, branch, false, false).
Join("INNER", "issue", "issue.id=pull_request.issue_id").
Find(&prs)
}
// PullRequests returns all pull requests for a base Repo by the given conditions
func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
countSession, err := listPullRequestStatement(baseRepoID, opts)
if err != nil {
log.Error("listPullRequestStatement: %v", err)
return nil, 0, err
}
maxResults, err := countSession.Count(new(PullRequest))
if err != nil {
log.Error("Count PRs: %v", err)
return nil, maxResults, err
}
prs := make([]*PullRequest, 0, ItemsPerPage)
findSession, err := listPullRequestStatement(baseRepoID, opts)
sortIssuesSession(findSession, opts.SortType, 0)
if err != nil {
log.Error("listPullRequestStatement: %v", err)
return nil, maxResults, err
}
findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage)
return prs, maxResults, findSession.Find(&prs)
}
// PullRequestList defines a list of pull requests
type PullRequestList []*PullRequest
func (prs PullRequestList) loadAttributes(e Engine) error {
if len(prs) == 0 {
return nil
}
// Load issues.
issueIDs := prs.getIssueIDs()
issues := make([]*Issue, 0, len(issueIDs))
if err := e.
Where("id > 0").
In("id", issueIDs).
Find(&issues); err != nil {
return fmt.Errorf("find issues: %v", err)
}
set := make(map[int64]*Issue)
for i := range issues {
set[issues[i].ID] = issues[i]
}
for i := range prs {
prs[i].Issue = set[prs[i].IssueID]
}
return nil
}
func (prs PullRequestList) getIssueIDs() []int64 {
issueIDs := make([]int64, 0, len(prs))
for i := range prs {
issueIDs = append(issueIDs, prs[i].IssueID)
}
return issueIDs
}
// LoadAttributes load all the prs attributes
func (prs PullRequestList) LoadAttributes() error {
return prs.loadAttributes(x)
}
func (prs PullRequestList) invalidateCodeComments(e Engine, doer *User, repo *git.Repository, branch string) error {
if len(prs) == 0 {
return nil
}
issueIDs := prs.getIssueIDs()
var codeComments []*Comment
if err := e.
Where("type = ? and invalidated = ?", CommentTypeCode, false).
In("issue_id", issueIDs).
Find(&codeComments); err != nil {
return fmt.Errorf("find code comments: %v", err)
}
for _, comment := range codeComments {
if err := comment.CheckInvalidation(repo, doer, branch); err != nil {
return err
}
}
return nil
}
// InvalidateCodeComments will lookup the prs for code comments which got invalidated by change
func (prs PullRequestList) InvalidateCodeComments(doer *User, repo *git.Repository, branch string) error {
return prs.invalidateCodeComments(x, doer, repo, branch)
}
// TestPullRequests checks and tests untested patches of pull requests.
// TODO: test more pull requests at same time.
func TestPullRequests() {
prs := make([]*PullRequest, 0, 10)
err := x.Where("status = ?", PullRequestStatusChecking).Find(&prs)
if err != nil {
log.Error("Find Checking PRs: %v", err)
return
}
var checkedPRs = make(map[int64]struct{})
// Update pull request status.
for _, pr := range prs {
checkedPRs[pr.ID] = struct{}{}
if err := pr.GetBaseRepo(); err != nil {
log.Error("GetBaseRepo: %v", err)
continue
}
if pr.manuallyMerged() {
continue
}
if err := pr.testPatch(x); err != nil {
log.Error("testPatch: %v", err)
continue
}
pr.checkAndUpdateStatus()
}
// Start listening on new test requests.
for prID := range pullRequestQueue.Queue() {
log.Trace("TestPullRequests[%v]: processing test task", prID)
pullRequestQueue.Remove(prID)
id := com.StrTo(prID).MustInt64()
if _, ok := checkedPRs[id]; ok {
continue
}
pr, err := GetPullRequestByID(id)
if err != nil {
log.Error("GetPullRequestByID[%s]: %v", prID, err)
continue
} else if pr.manuallyMerged() {
continue
} else if err = pr.testPatch(x); err != nil {
log.Error("testPatch[%d]: %v", pr.ID, err)
continue
}
pr.checkAndUpdateStatus()
}
}
// InitTestPullRequests runs the task to test all the checking status pull requests
func InitTestPullRequests() {
go TestPullRequests()
}

View File

@ -218,9 +218,18 @@ func (b *BleveIndexer) Delete(ids ...int64) error {
// Search searches for issues by given conditions. // Search searches for issues by given conditions.
// Returns the matching issue IDs // Returns the matching issue IDs
func (b *BleveIndexer) Search(keyword string, repoID int64, limit, start int) (*SearchResult, error) { func (b *BleveIndexer) Search(keyword string, repoIDs []int64, limit, start int) (*SearchResult, error) {
var repoQueriesP []*query.NumericRangeQuery
for _, repoID := range repoIDs {
repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "RepoID"))
}
repoQueries := make([]query.Query, len(repoQueriesP))
for i, v := range repoQueriesP {
repoQueries[i] = query.Query(v)
}
indexerQuery := bleve.NewConjunctionQuery( indexerQuery := bleve.NewConjunctionQuery(
numericEqualityQuery(repoID, "RepoID"), bleve.NewDisjunctionQuery(repoQueries...),
bleve.NewDisjunctionQuery( bleve.NewDisjunctionQuery(
newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer), newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer),
newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer), newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer),
@ -242,8 +251,7 @@ func (b *BleveIndexer) Search(keyword string, repoID int64, limit, start int) (*
return nil, err return nil, err
} }
ret.Hits = append(ret.Hits, Match{ ret.Hits = append(ret.Hits, Match{
ID: id, ID: id,
RepoID: repoID,
}) })
} }
return &ret, nil return &ret, nil

View File

@ -76,7 +76,7 @@ func TestBleveIndexAndSearch(t *testing.T) {
) )
for _, kw := range keywords { for _, kw := range keywords {
res, err := indexer.Search(kw.Keyword, 2, 10, 0) res, err := indexer.Search(kw.Keyword, []int64{2}, 10, 0)
assert.NoError(t, err) assert.NoError(t, err)
var ids = make([]int64, 0, len(res.Hits)) var ids = make([]int64, 0, len(res.Hits))

View File

@ -26,8 +26,8 @@ func (db *DBIndexer) Delete(ids ...int64) error {
} }
// Search dummy function // Search dummy function
func (db *DBIndexer) Search(kw string, repoID int64, limit, start int) (*SearchResult, error) { func (db *DBIndexer) Search(kw string, repoIDs []int64, limit, start int) (*SearchResult, error) {
total, ids, err := models.SearchIssueIDsByKeyword(kw, repoID, limit, start) total, ids, err := models.SearchIssueIDsByKeyword(kw, repoIDs, limit, start)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -37,8 +37,7 @@ func (db *DBIndexer) Search(kw string, repoID int64, limit, start int) (*SearchR
} }
for _, id := range ids { for _, id := range ids {
result.Hits = append(result.Hits, Match{ result.Hits = append(result.Hits, Match{
ID: id, ID: id,
RepoID: repoID,
}) })
} }
return &result, nil return &result, nil

View File

@ -28,9 +28,8 @@ type IndexerData struct {
// Match represents on search result // Match represents on search result
type Match struct { type Match struct {
ID int64 `json:"id"` ID int64 `json:"id"`
RepoID int64 `json:"repo_id"` Score float64 `json:"score"`
Score float64 `json:"score"`
} }
// SearchResult represents search results // SearchResult represents search results
@ -44,7 +43,7 @@ type Indexer interface {
Init() (bool, error) Init() (bool, error)
Index(issue []*IndexerData) error Index(issue []*IndexerData) error
Delete(ids ...int64) error Delete(ids ...int64) error
Search(kw string, repoID int64, limit, start int) (*SearchResult, error) Search(kw string, repoIDs []int64, limit, start int) (*SearchResult, error)
} }
type indexerHolder struct { type indexerHolder struct {
@ -262,9 +261,9 @@ func DeleteRepoIssueIndexer(repo *models.Repository) {
} }
// SearchIssuesByKeyword search issue ids by keywords and repo id // SearchIssuesByKeyword search issue ids by keywords and repo id
func SearchIssuesByKeyword(repoID int64, keyword string) ([]int64, error) { func SearchIssuesByKeyword(repoIDs []int64, keyword string) ([]int64, error) {
var issueIDs []int64 var issueIDs []int64
res, err := holder.get().Search(keyword, repoID, 1000, 0) res, err := holder.get().Search(keyword, repoIDs, 1000, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -30,19 +30,19 @@ func TestBleveSearchIssues(t *testing.T) {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
ids, err := SearchIssuesByKeyword(1, "issue2") ids, err := SearchIssuesByKeyword([]int64{1}, "issue2")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{2}, ids) assert.EqualValues(t, []int64{2}, ids)
ids, err = SearchIssuesByKeyword(1, "first") ids, err = SearchIssuesByKeyword([]int64{1}, "first")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
ids, err = SearchIssuesByKeyword(1, "for") ids, err = SearchIssuesByKeyword([]int64{1}, "for")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids)
ids, err = SearchIssuesByKeyword(1, "good") ids, err = SearchIssuesByKeyword([]int64{1}, "good")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
} }
@ -53,19 +53,19 @@ func TestDBSearchIssues(t *testing.T) {
setting.Indexer.IssueType = "db" setting.Indexer.IssueType = "db"
InitIssueIndexer(true) InitIssueIndexer(true)
ids, err := SearchIssuesByKeyword(1, "issue2") ids, err := SearchIssuesByKeyword([]int64{1}, "issue2")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{2}, ids) assert.EqualValues(t, []int64{2}, ids)
ids, err = SearchIssuesByKeyword(1, "first") ids, err = SearchIssuesByKeyword([]int64{1}, "first")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
ids, err = SearchIssuesByKeyword(1, "for") ids, err = SearchIssuesByKeyword([]int64{1}, "for")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1, 2, 3, 5}, ids) assert.EqualValues(t, []int64{1, 2, 3, 5}, ids)
ids, err = SearchIssuesByKeyword(1, "good") ids, err = SearchIssuesByKeyword([]int64{1}, "good")
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, []int64{1}, ids) assert.EqualValues(t, []int64{1}, ids)
} }

View File

@ -323,6 +323,6 @@ func TestRender_ShortLinks(t *testing.T) {
`<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`"/></a></p>`) `<p><a href="`+notencodedImgurlWiki+`" rel="nofollow"><img src="`+notencodedImgurlWiki+`"/></a></p>`)
test( test(
"<p><a href=\"https://example.org\">[[foobar]]</a></p>", "<p><a href=\"https://example.org\">[[foobar]]</a></p>",
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`, `<p></p><p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p><p></p>`,
`<p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p>`) `<p></p><p><a href="https://example.org" rel="nofollow">[[foobar]]</a></p><p></p>`)
} }

View File

@ -7,13 +7,14 @@ package markdown
import ( import (
"bytes" "bytes"
"io"
"strings" "strings"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/russross/blackfriday" "github.com/russross/blackfriday/v2"
) )
// Renderer is a extended version of underlying render object. // Renderer is a extended version of underlying render object.
@ -25,134 +26,138 @@ type Renderer struct {
var byteMailto = []byte("mailto:") var byteMailto = []byte("mailto:")
// Link defines how formal links should be processed to produce corresponding HTML elements. var htmlEscaper = [256][]byte{
func (r *Renderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { '&': []byte("&amp;"),
// special case: this is not a link, a hash link or a mailto:, so it's a '<': []byte("&lt;"),
// relative URL '>': []byte("&gt;"),
if len(link) > 0 && !markup.IsLink(link) && '"': []byte("&quot;"),
link[0] != '#' && !bytes.HasPrefix(link, byteMailto) { }
lnk := string(link)
func escapeHTML(w io.Writer, s []byte) {
var start, end int
for end < len(s) {
escSeq := htmlEscaper[s[end]]
if escSeq != nil {
_, _ = w.Write(s[start:end])
_, _ = w.Write(escSeq)
start = end + 1
}
end++
}
if start < len(s) && end <= len(s) {
_, _ = w.Write(s[start:end])
}
}
// RenderNode is a default renderer of a single node of a syntax tree. For
// block nodes it will be called twice: first time with entering=true, second
// time with entering=false, so that it could know when it's working on an open
// tag and when on close. It writes the result to w.
//
// The return value is a way to tell the calling walker to adjust its walk
// pattern: e.g. it can terminate the traversal by returning Terminate. Or it
// can ask the walker to skip a subtree of this node by returning SkipChildren.
// The typical behavior is to return GoToNext, which asks for the usual
// traversal to the next node.
func (r *Renderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
switch node.Type {
case blackfriday.Image:
prefix := r.URLPrefix
if r.IsWiki { if r.IsWiki {
lnk = util.URLJoin("wiki", lnk) prefix = util.URLJoin(prefix, "wiki", "raw")
} }
mLink := util.URLJoin(r.URLPrefix, lnk) prefix = strings.Replace(prefix, "/src/", "/media/", 1)
link = []byte(mLink) link := node.LinkData.Destination
} if len(link) > 0 && !markup.IsLink(link) {
lnk := string(link)
if len(content) > 10 && string(content[0:9]) == "<a href=\"" && bytes.Contains(content[9:], []byte("<img")) { lnk = util.URLJoin(prefix, lnk)
// Image with link case: markdown `[![]()]()` lnk = strings.Replace(lnk, " ", "+", -1)
// If the content is an image, then we change the original href around it link = []byte(lnk)
// which points to itself to a new address "link"
rightQuote := bytes.Index(content[9:], []byte("\""))
content = bytes.Replace(content, content[9:9+rightQuote], link, 1)
out.Write(content)
} else {
r.Renderer.Link(out, link, title, content)
}
}
// List renders markdown bullet or digit lists to HTML
func (r *Renderer) List(out *bytes.Buffer, text func() bool, flags int) {
marker := out.Len()
if out.Len() > 0 {
out.WriteByte('\n')
}
if flags&blackfriday.LIST_TYPE_DEFINITION != 0 {
out.WriteString("<dl>")
} else if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
out.WriteString("<ol class='ui list'>")
} else {
out.WriteString("<ul class='ui list'>")
}
if !text() {
out.Truncate(marker)
return
}
if flags&blackfriday.LIST_TYPE_DEFINITION != 0 {
out.WriteString("</dl>\n")
} else if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
out.WriteString("</ol>\n")
} else {
out.WriteString("</ul>\n")
}
}
// ListItem defines how list items should be processed to produce corresponding HTML elements.
func (r *Renderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
// Detect procedures to draw checkboxes.
prefix := ""
if bytes.HasPrefix(text, []byte("<p>")) {
prefix = "<p>"
}
switch {
case bytes.HasPrefix(text, []byte(prefix+"[ ] ")):
text = append([]byte(`<span class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
if prefix != "" {
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
} }
case bytes.HasPrefix(text, []byte(prefix+"[x] ")): node.LinkData.Destination = link
text = append([]byte(`<span class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...) // Render link around image only if parent is not link already
if prefix != "" { if node.Parent != nil && node.Parent.Type != blackfriday.Link {
text = bytes.Replace(text, []byte(prefix), []byte{}, 1) if entering {
_, _ = w.Write([]byte(`<a href="`))
escapeHTML(w, link)
_, _ = w.Write([]byte(`">`))
return r.Renderer.RenderNode(w, node, entering)
}
s := r.Renderer.RenderNode(w, node, entering)
_, _ = w.Write([]byte(`</a>`))
return s
}
return r.Renderer.RenderNode(w, node, entering)
case blackfriday.Link:
// special case: this is not a link, a hash link or a mailto:, so it's a
// relative URL
link := node.LinkData.Destination
if len(link) > 0 && !markup.IsLink(link) &&
link[0] != '#' && !bytes.HasPrefix(link, byteMailto) &&
node.LinkData.Footnote == nil {
lnk := string(link)
if r.IsWiki {
lnk = util.URLJoin("wiki", lnk)
}
link = []byte(util.URLJoin(r.URLPrefix, lnk))
}
node.LinkData.Destination = link
return r.Renderer.RenderNode(w, node, entering)
case blackfriday.Text:
isListItem := false
for n := node.Parent; n != nil; n = n.Parent {
if n.Type == blackfriday.Item {
isListItem = true
break
}
}
if isListItem {
text := node.Literal
switch {
case bytes.HasPrefix(text, []byte("[ ] ")):
_, _ = w.Write([]byte(`<span class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></span>`))
text = text[3:]
case bytes.HasPrefix(text, []byte("[x] ")):
_, _ = w.Write([]byte(`<span class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></span>`))
text = text[3:]
}
node.Literal = text
} }
} }
r.Renderer.ListItem(out, text, flags) return r.Renderer.RenderNode(w, node, entering)
}
// Image defines how images should be processed to produce corresponding HTML elements.
func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
prefix := r.URLPrefix
if r.IsWiki {
prefix = util.URLJoin(prefix, "wiki", "raw")
}
prefix = strings.Replace(prefix, "/src/", "/media/", 1)
if len(link) > 0 && !markup.IsLink(link) {
lnk := string(link)
lnk = util.URLJoin(prefix, lnk)
lnk = strings.Replace(lnk, " ", "+", -1)
link = []byte(lnk)
}
// Put a link around it pointing to itself by default
out.WriteString(`<a href="`)
out.Write(link)
out.WriteString(`">`)
r.Renderer.Image(out, link, title, alt)
out.WriteString("</a>")
} }
const ( const (
blackfridayExtensions = 0 | blackfridayExtensions = 0 |
blackfriday.EXTENSION_NO_INTRA_EMPHASIS | blackfriday.NoIntraEmphasis |
blackfriday.EXTENSION_TABLES | blackfriday.Tables |
blackfriday.EXTENSION_FENCED_CODE | blackfriday.FencedCode |
blackfriday.EXTENSION_STRIKETHROUGH | blackfriday.Strikethrough |
blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | blackfriday.NoEmptyLineBeforeBlock |
blackfriday.EXTENSION_DEFINITION_LISTS | blackfriday.DefinitionLists |
blackfriday.EXTENSION_FOOTNOTES | blackfriday.Footnotes |
blackfriday.EXTENSION_HEADER_IDS | blackfriday.HeadingIDs |
blackfriday.EXTENSION_AUTO_HEADER_IDS blackfriday.AutoHeadingIDs
blackfridayHTMLFlags = 0 | blackfridayHTMLFlags = 0 |
blackfriday.HTML_SKIP_STYLE | blackfriday.Smartypants
blackfriday.HTML_OMIT_CONTENTS |
blackfriday.HTML_USE_SMARTYPANTS
) )
// RenderRaw renders Markdown to HTML without handling special links. // RenderRaw renders Markdown to HTML without handling special links.
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte { func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
renderer := &Renderer{ renderer := &Renderer{
Renderer: blackfriday.HtmlRenderer(blackfridayHTMLFlags, "", ""), Renderer: blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
Flags: blackfridayHTMLFlags,
}),
URLPrefix: urlPrefix, URLPrefix: urlPrefix,
IsWiki: wikiMarkdown, IsWiki: wikiMarkdown,
} }
exts := blackfridayExtensions exts := blackfridayExtensions
if setting.Markdown.EnableHardLineBreak { if setting.Markdown.EnableHardLineBreak {
exts |= blackfriday.EXTENSION_HARD_LINE_BREAK exts |= blackfriday.HardLineBreak
} }
body = blackfriday.Markdown(body, renderer, exts) body = blackfriday.Run(body, blackfriday.WithRenderer(renderer), blackfriday.WithExtensions(exts))
return markup.SanitizeBytes(body) return markup.SanitizeBytes(body)
} }

View File

@ -166,13 +166,13 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
<h3 id="footnotes">Footnotes</h3> <h3 id="footnotes">Footnotes</h3>
<p>Here is a simple footnote,<sup id="fnref:1"><a href="#fn:1" rel="nofollow">1</a></sup> and here is a longer one.<sup id="fnref:bignote"><a href="#fn:bignote" rel="nofollow">2</a></sup></p> <p>Here is a simple footnote,<sup id="fnref:1"><a href="#fn:1" rel="nofollow">1</a></sup> and here is a longer one.<sup id="fnref:bignote"><a href="#fn:bignote" rel="nofollow">2</a></sup></p>
<div> <div>
<hr/> <hr/>
<ol> <ol>
<li id="fn:1">This is the first footnote. <li id="fn:1">This is the first footnote.</li>
</li>
<li id="fn:bignote"><p>Here is one with multiple paragraphs and code.</p> <li id="fn:bignote"><p>Here is one with multiple paragraphs and code.</p>
@ -180,9 +180,9 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
<p><code>{ my code }</code></p> <p><code>{ my code }</code></p>
<p>Add as many paragraphs as you like.</p> <p>Add as many paragraphs as you like.</p></li>
</li>
</ol> </ol>
</div> </div>
`, `,
} }

View File

@ -6,43 +6,39 @@ package mdstripper
import ( import (
"bytes" "bytes"
"io"
"github.com/russross/blackfriday" "github.com/russross/blackfriday/v2"
) )
// MarkdownStripper extends blackfriday.Renderer // MarkdownStripper extends blackfriday.Renderer
type MarkdownStripper struct { type MarkdownStripper struct {
blackfriday.Renderer
links []string links []string
coallesce bool coallesce bool
empty bool
} }
const ( const (
blackfridayExtensions = 0 | blackfridayExtensions = 0 |
blackfriday.EXTENSION_NO_INTRA_EMPHASIS | blackfriday.NoIntraEmphasis |
blackfriday.EXTENSION_TABLES | blackfriday.Tables |
blackfriday.EXTENSION_FENCED_CODE | blackfriday.FencedCode |
blackfriday.EXTENSION_STRIKETHROUGH | blackfriday.Strikethrough |
blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | blackfriday.NoEmptyLineBeforeBlock |
blackfriday.EXTENSION_DEFINITION_LISTS | blackfriday.DefinitionLists |
blackfriday.EXTENSION_FOOTNOTES | blackfriday.Footnotes |
blackfriday.EXTENSION_HEADER_IDS | blackfriday.HeadingIDs |
blackfriday.EXTENSION_AUTO_HEADER_IDS | blackfriday.AutoHeadingIDs |
// Not included in modules/markup/markdown/markdown.go; // Not included in modules/markup/markdown/markdown.go;
// required here to process inline links // required here to process inline links
blackfriday.EXTENSION_AUTOLINK blackfriday.Autolink
) )
//revive:disable:var-naming Implementing the Rendering interface requires breaking some linting rules
// StripMarkdown parses markdown content by removing all markup and code blocks // StripMarkdown parses markdown content by removing all markup and code blocks
// in order to extract links and other references // in order to extract links and other references
func StripMarkdown(rawBytes []byte) (string, []string) { func StripMarkdown(rawBytes []byte) (string, []string) {
stripper := &MarkdownStripper{ buf, links := StripMarkdownBytes(rawBytes)
links: make([]string, 0, 10), return string(buf), links
}
body := blackfriday.Markdown(rawBytes, stripper, blackfridayExtensions)
return string(body), stripper.GetLinks()
} }
// StripMarkdownBytes parses markdown content by removing all markup and code blocks // StripMarkdownBytes parses markdown content by removing all markup and code blocks
@ -50,205 +46,67 @@ func StripMarkdown(rawBytes []byte) (string, []string) {
func StripMarkdownBytes(rawBytes []byte) ([]byte, []string) { func StripMarkdownBytes(rawBytes []byte) ([]byte, []string) {
stripper := &MarkdownStripper{ stripper := &MarkdownStripper{
links: make([]string, 0, 10), links: make([]string, 0, 10),
empty: true,
} }
body := blackfriday.Markdown(rawBytes, stripper, blackfridayExtensions)
return body, stripper.GetLinks() parser := blackfriday.New(blackfriday.WithRenderer(stripper), blackfriday.WithExtensions(blackfridayExtensions))
ast := parser.Parse(rawBytes)
var buf bytes.Buffer
stripper.RenderHeader(&buf, ast)
ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
return stripper.RenderNode(&buf, node, entering)
})
stripper.RenderFooter(&buf, ast)
return buf.Bytes(), stripper.GetLinks()
} }
// block-level callbacks // RenderNode is the main rendering method. It will be called once for
// every leaf node and twice for every non-leaf node (first with
// BlockCode dummy function to proceed with rendering // entering=true, then with entering=false). The method should write its
func (r *MarkdownStripper) BlockCode(out *bytes.Buffer, text []byte, infoString string) { // rendition of the node to the supplied writer w.
// Not rendered func (r *MarkdownStripper) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
if !entering {
return blackfriday.GoToNext
}
switch node.Type {
case blackfriday.Text:
r.processString(w, node.Literal, node.Parent == nil)
return blackfriday.GoToNext
case blackfriday.Link:
r.processLink(w, node.LinkData.Destination)
r.coallesce = false
return blackfriday.SkipChildren
}
r.coallesce = false r.coallesce = false
return blackfriday.GoToNext
} }
// BlockQuote dummy function to proceed with rendering // RenderHeader is a method that allows the renderer to produce some
func (r *MarkdownStripper) BlockQuote(out *bytes.Buffer, text []byte) { // content preceding the main body of the output document.
// FIXME: perhaps it's better to leave out block quote for this? func (r *MarkdownStripper) RenderHeader(w io.Writer, ast *blackfriday.Node) {
r.processString(out, text, false)
} }
// BlockHtml dummy function to proceed with rendering // RenderFooter is a symmetric counterpart of RenderHeader.
func (r *MarkdownStripper) BlockHtml(out *bytes.Buffer, text []byte) { //nolint func (r *MarkdownStripper) RenderFooter(w io.Writer, ast *blackfriday.Node) {
// Not rendered
r.coallesce = false
} }
// Header dummy function to proceed with rendering func (r *MarkdownStripper) doubleSpace(w io.Writer) {
func (r *MarkdownStripper) Header(out *bytes.Buffer, text func() bool, level int, id string) { if !r.empty {
text() _, _ = w.Write([]byte{'\n'})
r.coallesce = false
}
// HRule dummy function to proceed with rendering
func (r *MarkdownStripper) HRule(out *bytes.Buffer) {
// Not rendered
r.coallesce = false
}
// List dummy function to proceed with rendering
func (r *MarkdownStripper) List(out *bytes.Buffer, text func() bool, flags int) {
text()
r.coallesce = false
}
// ListItem dummy function to proceed with rendering
func (r *MarkdownStripper) ListItem(out *bytes.Buffer, text []byte, flags int) {
r.processString(out, text, false)
}
// Paragraph dummy function to proceed with rendering
func (r *MarkdownStripper) Paragraph(out *bytes.Buffer, text func() bool) {
text()
r.coallesce = false
}
// Table dummy function to proceed with rendering
func (r *MarkdownStripper) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
r.processString(out, header, false)
r.processString(out, body, false)
}
// TableRow dummy function to proceed with rendering
func (r *MarkdownStripper) TableRow(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// TableHeaderCell dummy function to proceed with rendering
func (r *MarkdownStripper) TableHeaderCell(out *bytes.Buffer, text []byte, flags int) {
r.processString(out, text, false)
}
// TableCell dummy function to proceed with rendering
func (r *MarkdownStripper) TableCell(out *bytes.Buffer, text []byte, flags int) {
r.processString(out, text, false)
}
// Footnotes dummy function to proceed with rendering
func (r *MarkdownStripper) Footnotes(out *bytes.Buffer, text func() bool) {
text()
}
// FootnoteItem dummy function to proceed with rendering
func (r *MarkdownStripper) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
r.processString(out, text, false)
}
// TitleBlock dummy function to proceed with rendering
func (r *MarkdownStripper) TitleBlock(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// Span-level callbacks
// AutoLink dummy function to proceed with rendering
func (r *MarkdownStripper) AutoLink(out *bytes.Buffer, link []byte, kind int) {
r.processLink(out, link, []byte{})
}
// CodeSpan dummy function to proceed with rendering
func (r *MarkdownStripper) CodeSpan(out *bytes.Buffer, text []byte) {
// Not rendered
r.coallesce = false
}
// DoubleEmphasis dummy function to proceed with rendering
func (r *MarkdownStripper) DoubleEmphasis(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// Emphasis dummy function to proceed with rendering
func (r *MarkdownStripper) Emphasis(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// Image dummy function to proceed with rendering
func (r *MarkdownStripper) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
// Not rendered
r.coallesce = false
}
// LineBreak dummy function to proceed with rendering
func (r *MarkdownStripper) LineBreak(out *bytes.Buffer) {
// Not rendered
r.coallesce = false
}
// Link dummy function to proceed with rendering
func (r *MarkdownStripper) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
r.processLink(out, link, content)
}
// RawHtmlTag dummy function to proceed with rendering
func (r *MarkdownStripper) RawHtmlTag(out *bytes.Buffer, tag []byte) { //nolint
// Not rendered
r.coallesce = false
}
// TripleEmphasis dummy function to proceed with rendering
func (r *MarkdownStripper) TripleEmphasis(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// StrikeThrough dummy function to proceed with rendering
func (r *MarkdownStripper) StrikeThrough(out *bytes.Buffer, text []byte) {
r.processString(out, text, false)
}
// FootnoteRef dummy function to proceed with rendering
func (r *MarkdownStripper) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
// Not rendered
r.coallesce = false
}
// Low-level callbacks
// Entity dummy function to proceed with rendering
func (r *MarkdownStripper) Entity(out *bytes.Buffer, entity []byte) {
// FIXME: literal entities are not parsed; perhaps they should
r.coallesce = false
}
// NormalText dummy function to proceed with rendering
func (r *MarkdownStripper) NormalText(out *bytes.Buffer, text []byte) {
r.processString(out, text, true)
}
// Header and footer
// DocumentHeader dummy function to proceed with rendering
func (r *MarkdownStripper) DocumentHeader(out *bytes.Buffer) {
r.coallesce = false
}
// DocumentFooter dummy function to proceed with rendering
func (r *MarkdownStripper) DocumentFooter(out *bytes.Buffer) {
r.coallesce = false
}
// GetFlags returns rendering flags
func (r *MarkdownStripper) GetFlags() int {
return 0
}
//revive:enable:var-naming
func doubleSpace(out *bytes.Buffer) {
if out.Len() > 0 {
out.WriteByte('\n')
} }
} }
func (r *MarkdownStripper) processString(out *bytes.Buffer, text []byte, coallesce bool) { func (r *MarkdownStripper) processString(w io.Writer, text []byte, coallesce bool) {
// Always break-up words // Always break-up words
if !coallesce || !r.coallesce { if !coallesce || !r.coallesce {
doubleSpace(out) r.doubleSpace(w)
} }
out.Write(text) _, _ = w.Write(text)
r.coallesce = coallesce r.coallesce = coallesce
r.empty = false
} }
func (r *MarkdownStripper) processLink(out *bytes.Buffer, link []byte, content []byte) {
func (r *MarkdownStripper) processLink(w io.Writer, link []byte) {
// Links are processed out of band // Links are processed out of band
r.links = append(r.links, string(link)) r.links = append(r.links, string(link))
r.coallesce = false r.coallesce = false

View File

@ -5,12 +5,16 @@
package markup package markup
import ( import (
"bytes"
"fmt"
"html"
"strings"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/util"
"github.com/chaseadamsio/goorgeous" "github.com/niklasfasching/go-org/org"
"github.com/russross/blackfriday"
) )
func init() { func init() {
@ -32,23 +36,23 @@ func (Parser) Extensions() []string {
} }
// Render renders orgmode rawbytes to HTML // Render renders orgmode rawbytes to HTML
func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) (result []byte) { func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
defer func() { htmlWriter := org.NewHTMLWriter()
if err := recover(); err != nil {
log.Error("Panic in orgmode.Render: %v Just returning the rawBytes", err) renderer := &Renderer{
result = rawBytes HTMLWriter: htmlWriter,
} URLPrefix: urlPrefix,
}() IsWiki: isWiki,
htmlFlags := blackfriday.HTML_USE_XHTML
htmlFlags |= blackfriday.HTML_SKIP_STYLE
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
renderer := &markdown.Renderer{
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
URLPrefix: urlPrefix,
IsWiki: isWiki,
} }
result = goorgeous.Org(rawBytes, renderer)
return htmlWriter.ExtendingWriter = renderer
res, err := org.New().Silent().Parse(bytes.NewReader(rawBytes), "").Write(renderer)
if err != nil {
log.Error("Panic in orgmode.Render: %v Just returning the rawBytes", err)
return rawBytes
}
return []byte(res)
} }
// RenderString reners orgmode string to HTML string // RenderString reners orgmode string to HTML string
@ -56,7 +60,63 @@ func RenderString(rawContent string, urlPrefix string, metas map[string]string,
return string(Render([]byte(rawContent), urlPrefix, metas, isWiki)) return string(Render([]byte(rawContent), urlPrefix, metas, isWiki))
} }
// Render implements markup.Parser // Render reners orgmode string to HTML string
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte { func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
return Render(rawBytes, urlPrefix, metas, isWiki) return Render(rawBytes, urlPrefix, metas, isWiki)
} }
// Renderer implements org.Writer
type Renderer struct {
*org.HTMLWriter
URLPrefix string
IsWiki bool
}
var byteMailto = []byte("mailto:")
// WriteRegularLink renders images, links or videos
func (r *Renderer) WriteRegularLink(l org.RegularLink) {
link := []byte(html.EscapeString(l.URL))
if l.Protocol == "file" {
link = link[len("file:"):]
}
if len(link) > 0 && !markup.IsLink(link) &&
link[0] != '#' && !bytes.HasPrefix(link, byteMailto) {
lnk := string(link)
if r.IsWiki {
lnk = util.URLJoin("wiki", lnk)
}
link = []byte(util.URLJoin(r.URLPrefix, lnk))
}
description := string(link)
if l.Description != nil {
description = r.nodesAsString(l.Description...)
}
switch l.Kind() {
case "image":
r.WriteString(fmt.Sprintf(`<img src="%s" alt="%s" title="%s" />`, link, description, description))
case "video":
r.WriteString(fmt.Sprintf(`<video src="%s" title="%s">%s</video>`, link, description, description))
default:
r.WriteString(fmt.Sprintf(`<a href="%s" title="%s">%s</a>`, link, description, description))
}
}
func (r *Renderer) emptyClone() *Renderer {
wcopy := *(r.HTMLWriter)
wcopy.Builder = strings.Builder{}
rcopy := *r
rcopy.HTMLWriter = &wcopy
wcopy.ExtendingWriter = &rcopy
return &rcopy
}
func (r *Renderer) nodesAsString(nodes ...org.Node) string {
tmp := r.emptyClone()
org.WriteNodes(tmp, nodes...)
return tmp.String()
}

View File

@ -27,12 +27,12 @@ func TestRender_StandardLinks(t *testing.T) {
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
} }
googleRendered := `<p><a href="https://google.com/" title="https://google.com/">https://google.com/</a></p>` googleRendered := "<p>\n<a href=\"https://google.com/\" title=\"https://google.com/\">https://google.com/</a>\n</p>"
test("[[https://google.com/]]", googleRendered) test("[[https://google.com/]]", googleRendered)
lnk := util.URLJoin(AppSubURL, "WikiPage") lnk := util.URLJoin(AppSubURL, "WikiPage")
test("[[WikiPage][WikiPage]]", test("[[WikiPage][WikiPage]]",
`<p><a href="`+lnk+`" title="WikiPage">WikiPage</a></p>`) "<p>\n<a href=\""+lnk+"\" title=\"WikiPage\">WikiPage</a>\n</p>")
} }
func TestRender_Images(t *testing.T) { func TestRender_Images(t *testing.T) {
@ -45,10 +45,8 @@ func TestRender_Images(t *testing.T) {
} }
url := "../../.images/src/02/train.jpg" url := "../../.images/src/02/train.jpg"
title := "Train"
result := util.URLJoin(AppSubURL, url) result := util.URLJoin(AppSubURL, url)
test( test("[[file:"+url+"]]",
"[[file:"+url+"]["+title+"]]", "<p>\n<img src=\""+result+"\" alt=\""+result+"\" title=\""+result+"\" />\n</p>")
`<p><a href="`+result+`"><img src="`+result+`" alt="`+title+`" title="`+title+`" /></a></p>`)
} }

View File

@ -74,6 +74,11 @@ func (r *indexerNotifier) NotifyUpdateComment(doer *models.User, c *models.Comme
func (r *indexerNotifier) NotifyDeleteComment(doer *models.User, comment *models.Comment) { func (r *indexerNotifier) NotifyDeleteComment(doer *models.User, comment *models.Comment) {
if comment.Type == models.CommentTypeComment { if comment.Type == models.CommentTypeComment {
if err := comment.LoadIssue(); err != nil {
log.Error("LoadIssue: %v", err)
return
}
var found bool var found bool
if comment.Issue.Comments != nil { if comment.Issue.Comments != nil {
for i := 0; i < len(comment.Issue.Comments); i++ { for i := 0; i < len(comment.Issue.Comments); i++ {

View File

@ -277,3 +277,124 @@ func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue) {
go models.HookQueue.Add(issue.RepoID) go models.HookQueue.Add(issue.RepoID)
} }
} }
func (m *webhookNotifier) NotifyIssueChangeContent(doer *models.User, issue *models.Issue, oldContent string) {
mode, _ := models.AccessLevel(issue.Poster, issue.Repo)
var err error
if issue.IsPull {
issue.PullRequest.Issue = issue
err = models.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = models.PrepareWebhooks(issue.Repo, models.HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
}
if err != nil {
log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
go models.HookQueue.Add(issue.RepoID)
}
}
func (m *webhookNotifier) NotifyUpdateComment(doer *models.User, c *models.Comment, oldContent string) {
if err := c.LoadPoster(); err != nil {
log.Error("LoadPoster: %v", err)
return
}
if err := c.LoadIssue(); err != nil {
log.Error("LoadIssue: %v", err)
return
}
if err := c.Issue.LoadAttributes(); err != nil {
log.Error("LoadAttributes: %v", err)
return
}
mode, _ := models.AccessLevel(doer, c.Issue.Repo)
if err := models.PrepareWebhooks(c.Issue.Repo, models.HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentEdited,
Issue: c.Issue.APIFormat(),
Comment: c.APIFormat(),
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Repository: c.Issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
IsPull: c.Issue.IsPull,
}); err != nil {
log.Error("PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
} else {
go models.HookQueue.Add(c.Issue.Repo.ID)
}
}
func (m *webhookNotifier) NotifyCreateIssueComment(doer *models.User, repo *models.Repository,
issue *models.Issue, comment *models.Comment) {
mode, _ := models.AccessLevel(doer, repo)
if err := models.PrepareWebhooks(repo, models.HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated,
Issue: issue.APIFormat(),
Comment: comment.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(),
IsPull: issue.IsPull,
}); err != nil {
log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go models.HookQueue.Add(repo.ID)
}
}
func (m *webhookNotifier) NotifyDeleteComment(doer *models.User, comment *models.Comment) {
if err := comment.LoadPoster(); err != nil {
log.Error("LoadPoster: %v", err)
return
}
if err := comment.LoadIssue(); err != nil {
log.Error("LoadIssue: %v", err)
return
}
if err := comment.Issue.LoadAttributes(); err != nil {
log.Error("LoadAttributes: %v", err)
return
}
mode, _ := models.AccessLevel(doer, comment.Issue.Repo)
if err := models.PrepareWebhooks(comment.Issue.Repo, models.HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentDeleted,
Issue: comment.Issue.APIFormat(),
Comment: comment.APIFormat(),
Repository: comment.Issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
IsPull: comment.Issue.IsPull,
}); err != nil {
log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go models.HookQueue.Add(comment.Issue.Repo.ID)
}
}

View File

@ -11,6 +11,7 @@ import (
"strings" "strings"
"sync" "sync"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/mdstripper" "code.gitea.io/gitea/modules/markup/mdstripper"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -35,12 +36,8 @@ var (
// e.g. gogits/gogs#12345 // e.g. gogits/gogs#12345
crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+#[0-9]+)(?:\s|$|\)|\]|\.(\s|$))`) crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+#[0-9]+)(?:\s|$|\)|\]|\.(\s|$))`)
// Same as GitHub. See
// https://help.github.com/articles/closing-issues-via-commit-messages
issueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
issueReopenKeywords = []string{"reopen", "reopens", "reopened"}
issueCloseKeywordsPat, issueReopenKeywordsPat *regexp.Regexp issueCloseKeywordsPat, issueReopenKeywordsPat *regexp.Regexp
issueKeywordsOnce sync.Once
giteaHostInit sync.Once giteaHostInit sync.Once
giteaHost string giteaHost string
@ -107,13 +104,40 @@ type RefSpan struct {
End int End int
} }
func makeKeywordsPat(keywords []string) *regexp.Regexp { func makeKeywordsPat(words []string) *regexp.Regexp {
return regexp.MustCompile(`(?i)(?:\s|^|\(|\[)(` + strings.Join(keywords, `|`) + `):? $`) acceptedWords := parseKeywords(words)
if len(acceptedWords) == 0 {
// Never match
return nil
}
return regexp.MustCompile(`(?i)(?:\s|^|\(|\[)(` + strings.Join(acceptedWords, `|`) + `):? $`)
} }
func init() { func parseKeywords(words []string) []string {
issueCloseKeywordsPat = makeKeywordsPat(issueCloseKeywords) acceptedWords := make([]string, 0, 5)
issueReopenKeywordsPat = makeKeywordsPat(issueReopenKeywords) wordPat := regexp.MustCompile(`^[\pL]+$`)
for _, word := range words {
word = strings.ToLower(strings.TrimSpace(word))
// Accept Unicode letter class runes (a-z, á, à, ä, )
if wordPat.MatchString(word) {
acceptedWords = append(acceptedWords, word)
} else {
log.Info("Invalid keyword: %s", word)
}
}
return acceptedWords
}
func newKeywords() {
issueKeywordsOnce.Do(func() {
// Delay initialization until after the settings module is initialized
doNewKeywords(setting.Repository.PullRequest.CloseKeywords, setting.Repository.PullRequest.ReopenKeywords)
})
}
func doNewKeywords(close []string, reopen []string) {
issueCloseKeywordsPat = makeKeywordsPat(close)
issueReopenKeywordsPat = makeKeywordsPat(reopen)
} }
// getGiteaHostName returns a normalized string with the local host name, with no scheme or port information // getGiteaHostName returns a normalized string with the local host name, with no scheme or port information
@ -310,13 +334,19 @@ func getCrossReference(content []byte, start, end int, fromLink bool) *rawRefere
} }
func findActionKeywords(content []byte, start int) (XRefAction, *RefSpan) { func findActionKeywords(content []byte, start int) (XRefAction, *RefSpan) {
m := issueCloseKeywordsPat.FindSubmatchIndex(content[:start]) newKeywords()
if m != nil { var m []int
return XRefActionCloses, &RefSpan{Start: m[2], End: m[3]} if issueCloseKeywordsPat != nil {
m = issueCloseKeywordsPat.FindSubmatchIndex(content[:start])
if m != nil {
return XRefActionCloses, &RefSpan{Start: m[2], End: m[3]}
}
} }
m = issueReopenKeywordsPat.FindSubmatchIndex(content[:start]) if issueReopenKeywordsPat != nil {
if m != nil { m = issueReopenKeywordsPat.FindSubmatchIndex(content[:start])
return XRefActionReopens, &RefSpan{Start: m[2], End: m[3]} if m != nil {
return XRefActionReopens, &RefSpan{Start: m[2], End: m[3]}
}
} }
return XRefActionNone, nil return XRefActionNone, nil
} }

View File

@ -12,161 +12,136 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
type testFixture struct {
input string
expected []testResult
}
type testResult struct {
Index int64
Owner string
Name string
Issue string
Action XRefAction
RefLocation *RefSpan
ActionLocation *RefSpan
}
func TestFindAllIssueReferences(t *testing.T) { func TestFindAllIssueReferences(t *testing.T) {
type result struct {
Index int64
Owner string
Name string
Issue string
Action XRefAction
RefLocation *RefSpan
ActionLocation *RefSpan
}
type testFixture struct {
input string
expected []result
}
fixtures := []testFixture{ fixtures := []testFixture{
{ {
"Simply closes: #29 yes", "Simply closes: #29 yes",
[]result{ []testResult{
{29, "", "", "29", XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}}, {29, "", "", "29", XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}},
}, },
}, },
{ {
"#123 no, this is a title.", "#123 no, this is a title.",
[]result{}, []testResult{},
}, },
{ {
" #124 yes, this is a reference.", " #124 yes, this is a reference.",
[]result{ []testResult{
{124, "", "", "124", XRefActionNone, &RefSpan{Start: 0, End: 4}, nil}, {124, "", "", "124", XRefActionNone, &RefSpan{Start: 0, End: 4}, nil},
}, },
}, },
{ {
"```\nThis is a code block.\n#723 no, it's a code block.```", "```\nThis is a code block.\n#723 no, it's a code block.```",
[]result{}, []testResult{},
}, },
{ {
"This `#724` no, it's inline code.", "This `#724` no, it's inline code.",
[]result{}, []testResult{},
}, },
{ {
"This user3/repo4#200 yes.", "This user3/repo4#200 yes.",
[]result{ []testResult{
{200, "user3", "repo4", "200", XRefActionNone, &RefSpan{Start: 5, End: 20}, nil}, {200, "user3", "repo4", "200", XRefActionNone, &RefSpan{Start: 5, End: 20}, nil},
}, },
}, },
{ {
"This [one](#919) no, this is a URL fragment.", "This [one](#919) no, this is a URL fragment.",
[]result{}, []testResult{},
}, },
{ {
"This [two](/user2/repo1/issues/921) yes.", "This [two](/user2/repo1/issues/921) yes.",
[]result{ []testResult{
{921, "user2", "repo1", "921", XRefActionNone, nil, nil}, {921, "user2", "repo1", "921", XRefActionNone, nil, nil},
}, },
}, },
{ {
"This [three](/user2/repo1/pulls/922) yes.", "This [three](/user2/repo1/pulls/922) yes.",
[]result{ []testResult{
{922, "user2", "repo1", "922", XRefActionNone, nil, nil}, {922, "user2", "repo1", "922", XRefActionNone, nil, nil},
}, },
}, },
{ {
"This [four](http://gitea.com:3000/user3/repo4/issues/203) yes.", "This [four](http://gitea.com:3000/user3/repo4/issues/203) yes.",
[]result{ []testResult{
{203, "user3", "repo4", "203", XRefActionNone, nil, nil}, {203, "user3", "repo4", "203", XRefActionNone, nil, nil},
}, },
}, },
{ {
"This [five](http://github.com/user3/repo4/issues/204) no.", "This [five](http://github.com/user3/repo4/issues/204) no.",
[]result{}, []testResult{},
}, },
{ {
"This http://gitea.com:3000/user4/repo5/201 no, bad URL.", "This http://gitea.com:3000/user4/repo5/201 no, bad URL.",
[]result{}, []testResult{},
}, },
{ {
"This http://gitea.com:3000/user4/repo5/pulls/202 yes.", "This http://gitea.com:3000/user4/repo5/pulls/202 yes.",
[]result{ []testResult{
{202, "user4", "repo5", "202", XRefActionNone, nil, nil}, {202, "user4", "repo5", "202", XRefActionNone, nil, nil},
}, },
}, },
{ {
"This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.", "This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.",
[]result{ []testResult{
{205, "user4", "repo6", "205", XRefActionNone, nil, nil}, {205, "user4", "repo6", "205", XRefActionNone, nil, nil},
}, },
}, },
{ {
"Reopens #15 yes", "Reopens #15 yes",
[]result{ []testResult{
{15, "", "", "15", XRefActionReopens, &RefSpan{Start: 8, End: 11}, &RefSpan{Start: 0, End: 7}}, {15, "", "", "15", XRefActionReopens, &RefSpan{Start: 8, End: 11}, &RefSpan{Start: 0, End: 7}},
}, },
}, },
{ {
"This closes #20 for you yes", "This closes #20 for you yes",
[]result{ []testResult{
{20, "", "", "20", XRefActionCloses, &RefSpan{Start: 12, End: 15}, &RefSpan{Start: 5, End: 11}}, {20, "", "", "20", XRefActionCloses, &RefSpan{Start: 12, End: 15}, &RefSpan{Start: 5, End: 11}},
}, },
}, },
{ {
"Do you fix user6/repo6#300 ? yes", "Do you fix user6/repo6#300 ? yes",
[]result{ []testResult{
{300, "user6", "repo6", "300", XRefActionCloses, &RefSpan{Start: 11, End: 26}, &RefSpan{Start: 7, End: 10}}, {300, "user6", "repo6", "300", XRefActionCloses, &RefSpan{Start: 11, End: 26}, &RefSpan{Start: 7, End: 10}},
}, },
}, },
{ {
"For 999 #1235 no keyword, but yes", "For 999 #1235 no keyword, but yes",
[]result{ []testResult{
{1235, "", "", "1235", XRefActionNone, &RefSpan{Start: 8, End: 13}, nil}, {1235, "", "", "1235", XRefActionNone, &RefSpan{Start: 8, End: 13}, nil},
}, },
}, },
{ {
"Which abc. #9434 same as above", "Which abc. #9434 same as above",
[]result{ []testResult{
{9434, "", "", "9434", XRefActionNone, &RefSpan{Start: 11, End: 16}, nil}, {9434, "", "", "9434", XRefActionNone, &RefSpan{Start: 11, End: 16}, nil},
}, },
}, },
{ {
"This closes #600 and reopens #599", "This closes #600 and reopens #599",
[]result{ []testResult{
{600, "", "", "600", XRefActionCloses, &RefSpan{Start: 12, End: 16}, &RefSpan{Start: 5, End: 11}}, {600, "", "", "600", XRefActionCloses, &RefSpan{Start: 12, End: 16}, &RefSpan{Start: 5, End: 11}},
{599, "", "", "599", XRefActionReopens, &RefSpan{Start: 29, End: 33}, &RefSpan{Start: 21, End: 28}}, {599, "", "", "599", XRefActionReopens, &RefSpan{Start: 29, End: 33}, &RefSpan{Start: 21, End: 28}},
}, },
}, },
} }
// Save original value for other tests that may rely on it testFixtures(t, fixtures, "default")
prevURL := setting.AppURL
setting.AppURL = "https://gitea.com:3000/"
for _, fixture := range fixtures {
expraw := make([]*rawReference, len(fixture.expected))
for i, e := range fixture.expected {
expraw[i] = &rawReference{
index: e.Index,
owner: e.Owner,
name: e.Name,
action: e.Action,
issue: e.Issue,
refLocation: e.RefLocation,
actionLocation: e.ActionLocation,
}
}
expref := rawToIssueReferenceList(expraw)
refs := FindAllIssueReferencesMarkdown(fixture.input)
assert.EqualValues(t, expref, refs, "Failed to parse: {%s}", fixture.input)
rawrefs := findAllIssueReferencesMarkdown(fixture.input)
assert.EqualValues(t, expraw, rawrefs, "Failed to parse: {%s}", fixture.input)
}
// Restore for other tests that may rely on the original value
setting.AppURL = prevURL
type alnumFixture struct { type alnumFixture struct {
input string input string
@ -203,6 +178,35 @@ func TestFindAllIssueReferences(t *testing.T) {
} }
} }
func testFixtures(t *testing.T, fixtures []testFixture, context string) {
// Save original value for other tests that may rely on it
prevURL := setting.AppURL
setting.AppURL = "https://gitea.com:3000/"
for _, fixture := range fixtures {
expraw := make([]*rawReference, len(fixture.expected))
for i, e := range fixture.expected {
expraw[i] = &rawReference{
index: e.Index,
owner: e.Owner,
name: e.Name,
action: e.Action,
issue: e.Issue,
refLocation: e.RefLocation,
actionLocation: e.ActionLocation,
}
}
expref := rawToIssueReferenceList(expraw)
refs := FindAllIssueReferencesMarkdown(fixture.input)
assert.EqualValues(t, expref, refs, "[%s] Failed to parse: {%s}", context, fixture.input)
rawrefs := findAllIssueReferencesMarkdown(fixture.input)
assert.EqualValues(t, expraw, rawrefs, "[%s] Failed to parse: {%s}", context, fixture.input)
}
// Restore for other tests that may rely on the original value
setting.AppURL = prevURL
}
func TestRegExp_mentionPattern(t *testing.T) { func TestRegExp_mentionPattern(t *testing.T) {
trueTestCases := []string{ trueTestCases := []string{
"@Unknwon", "@Unknwon",
@ -294,3 +298,75 @@ func TestRegExp_issueAlphanumericPattern(t *testing.T) {
assert.False(t, issueAlphanumericPattern.MatchString(testCase)) assert.False(t, issueAlphanumericPattern.MatchString(testCase))
} }
} }
func TestCustomizeCloseKeywords(t *testing.T) {
fixtures := []testFixture{
{
"Simplemente cierra: #29 yes",
[]testResult{
{29, "", "", "29", XRefActionCloses, &RefSpan{Start: 20, End: 23}, &RefSpan{Start: 12, End: 18}},
},
},
{
"Closes: #123 no, this English.",
[]testResult{
{123, "", "", "123", XRefActionNone, &RefSpan{Start: 8, End: 12}, nil},
},
},
{
"Cerró user6/repo6#300 yes",
[]testResult{
{300, "user6", "repo6", "300", XRefActionCloses, &RefSpan{Start: 7, End: 22}, &RefSpan{Start: 0, End: 6}},
},
},
{
"Reabre user3/repo4#200 yes",
[]testResult{
{200, "user3", "repo4", "200", XRefActionReopens, &RefSpan{Start: 7, End: 22}, &RefSpan{Start: 0, End: 6}},
},
},
}
issueKeywordsOnce.Do(func() {})
doNewKeywords([]string{"cierra", "cerró"}, []string{"reabre"})
testFixtures(t, fixtures, "spanish")
// Restore default settings
doNewKeywords(setting.Repository.PullRequest.CloseKeywords, setting.Repository.PullRequest.ReopenKeywords)
}
func TestParseCloseKeywords(t *testing.T) {
// Test parsing of CloseKeywords and ReopenKeywords
assert.Len(t, parseKeywords([]string{""}), 0)
assert.Len(t, parseKeywords([]string{" aa ", " bb ", "99", "#", "", "this is", "cc"}), 3)
for _, test := range []struct {
pattern string
match string
expected string
}{
{"close", "This PR will close ", "close"},
{"cerró", "cerró ", "cerró"},
{"cerró", "AQUÍ SE CERRÓ: ", "CERRÓ"},
{"закрывается", "закрывается ", "закрывается"},
{"κλείνει", "κλείνει: ", "κλείνει"},
{"关闭", "关闭 ", "关闭"},
{"閉じます", "閉じます ", "閉じます"},
{",$!", "", ""},
{"1234", "", ""},
} {
// The patern only needs to match the part that precedes the reference.
// getCrossReference() takes care of finding the reference itself.
pat := makeKeywordsPat([]string{test.pattern})
if test.expected == "" {
assert.Nil(t, pat)
} else {
assert.NotNil(t, pat)
res := pat.FindAllStringSubmatch(test.match, -1)
assert.Len(t, res, 1)
assert.Len(t, res[0], 2)
assert.EqualValues(t, test.expected, res[0][1])
}
}
}

View File

@ -59,6 +59,8 @@ var (
// Pull request settings // Pull request settings
PullRequest struct { PullRequest struct {
WorkInProgressPrefixes []string WorkInProgressPrefixes []string
CloseKeywords []string
ReopenKeywords []string
} `ini:"repository.pull-request"` } `ini:"repository.pull-request"`
// Issue Setting // Issue Setting
@ -122,8 +124,14 @@ var (
// Pull request settings // Pull request settings
PullRequest: struct { PullRequest: struct {
WorkInProgressPrefixes []string WorkInProgressPrefixes []string
CloseKeywords []string
ReopenKeywords []string
}{ }{
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"}, WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
// Same as GitHub. See
// https://help.github.com/articles/closing-issues-via-commit-messages
CloseKeywords: strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
ReopenKeywords: strings.Split("reopen,reopens,reopened", ","),
}, },
// Issue settings // Issue settings

View File

@ -39,6 +39,7 @@ var Service struct {
EnableTimetracking bool EnableTimetracking bool
DefaultEnableTimetracking bool DefaultEnableTimetracking bool
DefaultEnableDependencies bool DefaultEnableDependencies bool
AllowCrossRepositoryDependencies bool
DefaultAllowOnlyContributorsToTrackTime bool DefaultAllowOnlyContributorsToTrackTime bool
NoReplyAddress string NoReplyAddress string
EnableUserHeatmap bool EnableUserHeatmap bool
@ -79,6 +80,7 @@ func newService() {
Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true) Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)
} }
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true) Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true) Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org")
Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)

View File

@ -26,6 +26,13 @@ type PullRequestMeta struct {
Merged *time.Time `json:"merged_at"` Merged *time.Time `json:"merged_at"`
} }
// RepositoryMeta basic repository information
type RepositoryMeta struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
}
// Issue represents an issue in a repository // Issue represents an issue in a repository
// swagger:model // swagger:model
type Issue struct { type Issue struct {
@ -57,6 +64,7 @@ type Issue struct {
Deadline *time.Time `json:"due_date"` Deadline *time.Time `json:"due_date"`
PullRequest *PullRequestMeta `json:"pull_request"` PullRequest *PullRequestMeta `json:"pull_request"`
Repo *RepositoryMeta `json:"repository"`
} }
// ListIssueOption list issue options // ListIssueOption list issue options

View File

@ -1,7 +1,5 @@
Attribution Assurance License Attribution Assurance License Copyright (c) 2002 by AUTHOR PROFESSIONAL IDENTIFICATION
* URL "PROMOTIONAL SLOGAN FOR AUTHOR'S PROFESSIONAL PRACTICE"
Copyright (c) 2002 by AUTHOR PROFESSIONAL IDENTIFICATION * URL "PROMOTIONAL
SLOGAN FOR AUTHOR'S PROFESSIONAL PRACTICE"
All Rights Reserved ATTRIBUTION ASSURANCE LICENSE (adapted from the original All Rights Reserved ATTRIBUTION ASSURANCE LICENSE (adapted from the original
BSD license) BSD license)

View File

@ -1,6 +1,6 @@
This software code is made available "AS IS" without warranties of any kind. This software code is made available "AS IS" without warranties of any kind.
You may copy, display, modify and redistribute the software code either by You may copy, display, modify and redistribute the software code either by
itself or as incorporated into your code; provided that > you do not remove itself or as incorporated into your code; provided that you do not remove
any proprietary notices. Your use of this software code is at your own risk any proprietary notices. Your use of this software code is at your own risk
and you waive any claim against Amazon Digital Services, Inc. or its affiliates and you waive any claim against Amazon Digital Services, Inc. or its affiliates
with respect to your use of this software code. (c) 2006 Amazon Digital Services, with respect to your use of this software code. (c) 2006 Amazon Digital Services,

View File

@ -4,7 +4,7 @@ Version 1.1 The Academic Free License applies to any original work of authorship
(the "Original Work") whose owner (the "Licensor") has placed the following (the "Original Work") whose owner (the "Licensor") has placed the following
notice immediately following the copyright notice for the Original Work: notice immediately following the copyright notice for the Original Work:
" Licensed under the Academic Free License version 1.1. " "Licensed under the Academic Free License version 1.1."
Grant of License. Licensor hereby grants to any person obtaining a copy of Grant of License. Licensor hereby grants to any person obtaining a copy of
the Original Work ("You") a world-wide, royalty-free, non-exclusive, perpetual, the Original Work ("You") a world-wide, royalty-free, non-exclusive, perpetual,

View File

@ -2,7 +2,7 @@ GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007 Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -597,7 +597,7 @@ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details. details.
You should have received a copy of the GNU Affero General Public License along You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <http s ://www.gnu.org/licenses/>. with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -610,5 +610,4 @@ programs; see section 13 for the specific requirements.
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU AGPL, see <http more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
s ://www.gnu.org/licenses/>.

View File

@ -2,7 +2,7 @@ GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007 Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -597,7 +597,7 @@ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details. details.
You should have received a copy of the GNU Affero General Public License along You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <http s ://www.gnu.org/licenses/>. with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -610,5 +610,4 @@ programs; see section 13 for the specific requirements.
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU AGPL, see <http more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
s ://www.gnu.org/licenses/>.

View File

@ -1,6 +1,5 @@
Adobe Systems Incorporated(r) Source Code License Agreement Adobe Systems Incorporated(r) Source Code License Agreement Copyright(c) 2006
Adobe Systems Incorporated. All rights reserved.
Copyright(c) 2006 Adobe Systems Incorporated. All rights reserved.
Please read this Source Code License Agreement carefully before using the Please read this Source Code License Agreement carefully before using the
source code. source code.

View File

@ -1,8 +1,7 @@
Aladdin Free Public License Aladdin Free Public License
(Version 8, November 18, 1999) (Version 8, November 18, 1999) Copyright (C) 1994, 1995, 1997, 1998, 1999
Aladdin Enterprises,
Copyright (C) 1994, 1995, 1997, 1998, 1999 Aladdin Enterprises,
Menlo Park, California, U.S.A. All rights reserved. NOTE: This License is Menlo Park, California, U.S.A. All rights reserved. NOTE: This License is
not the same as any of the GNU Licenses published by the Free Software Foundation. not the same as any of the GNU Licenses published by the Free Software Foundation.

View File

@ -1,6 +1,5 @@
Apache License 1.1 Apache License 1.1 Copyright (c) 2000 The Apache Software Foundation. All
rights reserved.
Copyright (c) 2000 The Apache Software Foundation . All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,8 +1,6 @@
AUTOCONF CONFIGURE SCRIPT EXCEPTION AUTOCONF CONFIGURE SCRIPT EXCEPTION
Version 3.0, 18 August 2009 Version 3.0, 18 August 2009 Copyright © 2009 Free Software Foundation, Inc. <http://fsf.org/>
Copyright © 2009 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

View File

@ -1,4 +1,4 @@
Copyright (c) <year> <owner> . All rights reserved. Copyright (c) <year> <owner>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,6 +1,5 @@
The FreeBSD Copyright The FreeBSD Copyright Copyright 1992-2012 The FreeBSD Project. All rights
reserved.
Copyright 1992-2012 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,4 +1,4 @@
Copyright (c) <year> <owner> . All rights reserved. Copyright (c) <year> <owner>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,6 +1,4 @@
The Clear BSD License The Clear BSD License Copyright (c) [xxxx]-[xxxx] [Owner Organization]
Copyright (c) [xxxx]-[xxxx] [Owner Organization]
All rights reserved. All rights reserved.

View File

@ -1,4 +1,4 @@
Copyright (c) <year> <owner> . All rights reserved. Copyright (c) <year> <owner>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -202,4 +202,4 @@ consent of Creative Commons. Any permitted use will be in compliance with
Creative Commons' then-current trademark usage guidelines, as may be published Creative Commons' then-current trademark usage guidelines, as may be published
on its website or otherwise made available upon request from time to time. on its website or otherwise made available upon request from time to time.
Creative Commons may be contacted at http s ://creativecommons.org/. Creative Commons may be contacted at https://creativecommons.org/.

View File

@ -378,7 +378,7 @@ portions of the Covered Code under Your choice of the NPL or the alternative
licenses, if any, specified by the Initial Developer in the file described licenses, if any, specified by the Initial Developer in the file described
in Exhibit A. EXHIBIT A - CUA Office Public License. in Exhibit A. EXHIBIT A - CUA Office Public License.
" The contents of this file are subject to the CUA Office Public License Version "The contents of this file are subject to the CUA Office Public License Version
1.0 (the "License"); you may not use this file except in compliance with the 1.0 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://cuaoffice.sourceforge.net/ License. You may obtain a copy of the License at http://cuaoffice.sourceforge.net/
@ -402,7 +402,7 @@ to allow others to use your version of this file under the CUAPL, indicate
your decision by deleting the provisions above and replace them with the notice your decision by deleting the provisions above and replace them with the notice
and other provisions required by the [___] License. If you do not delete the and other provisions required by the [___] License. If you do not delete the
provisions above, a recipient may use your version of this file under either provisions above, a recipient may use your version of this file under either
the CUAPL or the [___] License. " the CUAPL or the [___] License."
[NOTE: The text of this Exhibit A may differ slightly from the text of the [NOTE: The text of this Exhibit A may differ slightly from the text of the
notices in the Source Code files of the Original Code. You should use the notices in the Source Code files of the Original Code. You should use the

View File

@ -1,11 +1,10 @@
Condor Public License Condor Public License
Version 1.1, October 30, 2003 Version 1.1, October 30, 2003 Copyright © 1990-2006 Condor Team, Computer
Sciences Department, University of Wisconsin-Madison, Madison, WI. All Rights
Copyright © 1990-2006 Condor Team, Computer Sciences Department, University Reserved. For more information contact: Condor Team, Attention: Professor
of Wisconsin-Madison, Madison, WI. All Rights Reserved. For more information Miron Livny, Dept of Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
contact: Condor Team, Attention: Professor Miron Livny, Dept of Computer Sciences, (608) 262-0856 or miron@cs.wisc.edu.
1210 W. Dayton St., Madison, WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
This software referred to as the Condor® Version 6.x software ("Software") This software referred to as the Condor® Version 6.x software ("Software")
was developed by the Condor Project, Condor Team, Computer Sciences Department, was developed by the Condor Project, Condor Team, Computer Sciences Department,

View File

@ -1,6 +1,5 @@
Cube game engine source code, 20 dec 2003 release. Cube game engine source code, 20 dec 2003 release. Copyright (C) 2001-2003
Wouter van Oortmerssen.
Copyright (C) 2001-2003 Wouter van Oortmerssen.
This software is provided 'as-is', without any express or implied warranty. This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the In no event will the authors be held liable for any damages arising from the

View File

@ -1,6 +1,4 @@
COPYRIGHT NOTIFICATION COPYRIGHT NOTIFICATION (C) COPYRIGHT 2004 UNIVERSITY OF CHICAGO
(C) COPYRIGHT 2004 UNIVERSITY OF CHICAGO
This program discloses material protectable under copyright laws of the United This program discloses material protectable under copyright laws of the United
States. Permission to copy and modify this software and its documentation States. Permission to copy and modify this software and its documentation

View File

@ -1,6 +1,4 @@
EU DataGrid Software License EU DataGrid Software License Copyright (c) 2001 EU DataGrid. All rights reserved.
Copyright (c) 2001 EU DataGrid. All rights reserved.
This software includes voluntary contributions made to the EU DataGrid. For This software includes voluntary contributions made to the EU DataGrid. For
more information on the EU DataGrid, please see http://www.eu-datagrid.org/. more information on the EU DataGrid, please see http://www.eu-datagrid.org/.

View File

@ -1,10 +1,9 @@
European Union Public Licence V.1.0 European Union Public Licence V.1.0 EUPL (c) the European Community 2007 This
European Union Public Licence (the "EUPL") applies to the Work or Software
EUPL (c) the European Community 2007 This European Union Public Licence (the (as defined below) which is provided under the terms of this Licence. Any
"EUPL") applies to the Work or Software (as defined below) which is provided use of the Work, other than as authorised under this Licence is prohibited
under the terms of this Licence. Any use of the Work, other than as authorised (to the extent such use is covered by a right of the copyright holder of the
under this Licence is prohibited (to the extent such use is covered by a right Work).
of the copyright holder of the Work).
The Original Work is provided under the terms of this Licence when the Licensor The Original Work is provided under the terms of this Licence when the Licensor
(as defined below) has placed the following notice immediately following the (as defined below) has placed the following notice immediately following the

View File

@ -1,6 +1,4 @@
European Union Public Licence V. 1.1 European Union Public Licence V. 1.1 EUPL (c) the European Community 2007
EUPL (c) the European Community 2007
This European Union Public Licence (the "EUPL") applies to the Work or Software This European Union Public Licence (the "EUPL") applies to the Work or Software
(as defined below) which is provided under the terms of this Licence. Any (as defined below) which is provided under the terms of this Licence. Any

View File

@ -1,6 +1,5 @@
Entessa Public License Version. 1.0 Entessa Public License Version. 1.0 Copyright (c) 2003 Entessa, LLC. All rights
reserved.
Copyright (c) 2003 Entessa, LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,6 +1,4 @@
Fair License Fair License <Copyright Information>
<Copyright Information>
Usage of the works is permitted provided that this instrument is retained Usage of the works is permitted provided that this instrument is retained
with the works, so that any entity that uses the works is notified of this with the works, so that any entity that uses the works is notified of this

View File

@ -1,9 +1,7 @@
GNU Free Documentation License GNU Free Documentation License
Version 1.3, 3 November 2008 Version 1.3, 3 November 2008 Copyright (C) 2000, 2001, 2002, 2007, 2008 Free
Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.

View File

@ -1,9 +1,7 @@
GNU Free Documentation License GNU Free Documentation License
Version 1.3, 3 November 2008 Version 1.3, 3 November 2008 Copyright (C) 2000, 2001, 2002, 2007, 2008 Free
Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.

View File

@ -1,6 +1,4 @@
GL2PS LICENSE Version 2, November 2003 GL2PS LICENSE Version 2, November 2003 Copyright (C) 2003, Christophe Geuzaine
Copyright (C) 2003, Christophe Geuzaine
Permission to use, copy, and distribute this software and its documentation Permission to use, copy, and distribute this software and its documentation
for any purpose with or without fee is hereby granted, provided that the copyright for any purpose with or without fee is hereby granted, provided that the copyright

View File

@ -4,7 +4,7 @@ Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 , USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -272,9 +272,9 @@ them to the start of each source file to most effectively convey the exclusion
of warranty; and each file should have at least the "copyright" line and a of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found. pointer to where the full notice is found.
< one line to give the program's name and an idea of what it does. > <one line to give the program's name and an idea of what it does.>
Copyright (C) < yyyy > < name of author > Copyright (C)< yyyy> <name of author>
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -287,7 +287,7 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301 , USA. Street, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -311,7 +311,7 @@ is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
(which makes passes at compilers) written by James Hacker. (which makes passes at compilers) written by James Hacker.
< signature of Ty Coon > , 1 April 1989 Ty Coon, President of Vice This General <signature of Ty Coon >, 1 April 1989 Ty Coon, President of Vice This General
Public License does not permit incorporating your program into proprietary Public License does not permit incorporating your program into proprietary
programs. If your program is a subroutine library, you may consider it more programs. If your program is a subroutine library, you may consider it more
useful to permit linking proprietary applications with the library. If this useful to permit linking proprietary applications with the library. If this

View File

@ -4,7 +4,7 @@ Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 , USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -287,7 +287,7 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301 , USA. Street, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -311,7 +311,7 @@ is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
(which makes passes at compilers) written by James Hacker. (which makes passes at compilers) written by James Hacker.
< signature of Ty Coon > , 1 April 1989 Ty Coon, President of Vice This General <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General
Public License does not permit incorporating your program into proprietary Public License does not permit incorporating your program into proprietary
programs. If your program is a subroutine library, you may consider it more programs. If your program is a subroutine library, you may consider it more
useful to permit linking proprietary applications with the library. If this useful to permit linking proprietary applications with the library. If this

View File

@ -2,7 +2,7 @@ GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -595,7 +595,7 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http s ://www.gnu.org/licenses/>. this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -615,12 +615,11 @@ be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU GPL, see <http more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
s ://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you may into proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General Public library. If this is what you want to do, use the GNU Lesser General Public
License instead of this License. But first, please read <http s ://www.gnu.org/ License instead of this License. But first, please read <https://www.gnu.org/
licenses /why-not-lgpl.html>. licenses /why-not-lgpl.html>.

View File

@ -2,7 +2,7 @@ GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.
@ -595,7 +595,7 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http s ://www.gnu.org/licenses/>. this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@ -615,12 +615,11 @@ be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU GPL, see <http more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
s ://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you may into proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General Public library. If this is what you want to do, use the GNU Lesser General Public
License instead of this License. But first, please read <http s ://www.gnu.org/ License instead of this License. But first, please read <https://www.gnu.org/
licenses /why-not-lgpl.html>. licenses /why-not-lgpl.html>.

View File

@ -1,10 +1,8 @@
Historical Permission Notice and Disclaimer Historical Permission Notice and Disclaimer <copyright notice>
<copyright notice>
Permission to use, copy, modify and distribute this software and its documentation Permission to use, copy, modify and distribute this software and its documentation
for any purpose and without fee is hereby granted, provided that the above for any purpose and without fee is hereby granted, provided that the above
copyright notice appear in all copies , and that both that the copyright notice copyright notice appear in all copies, and that both that the copyright notice
and this permission notice appear in supporting documentation , and that the and this permission notice appear in supporting documentation , and that the
name of <copyright holder> <or related entities> not be used in advertising name of <copyright holder> <or related entities> not be used in advertising
or publicity pertaining to distribution of the software without specific, or publicity pertaining to distribution of the software without specific,

View File

@ -1,8 +1,7 @@
ICU License - ICU 1.8.1 and later ICU License - ICU 1.8.1 and later
COPYRIGHT AND PERMISSION NOTICE COPYRIGHT AND PERMISSION NOTICE Copyright (c) 1995-2014 International Business
Machines Corporation and others
Copyright (c) 1995-2014 International Business Machines Corporation and others
All rights reserved. All rights reserved.

View File

@ -1,6 +1,4 @@
ISC License ISC License Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
Copyright (c) 1995-2003 by Internet Software Consortium Copyright (c) 1995-2003 by Internet Software Consortium

View File

@ -64,10 +64,9 @@ you need to acknowledge the use of the ImageMagick software;
Terms and Conditions for Use, Reproduction, and Distribution Terms and Conditions for Use, Reproduction, and Distribution
The legally binding and authoritative terms and conditions for use, reproduction, The legally binding and authoritative terms and conditions for use, reproduction,
and distribution of ImageMagick follow: and distribution of ImageMagick follow: Copyright 1999-2013 ImageMagick Studio
LLC, a non-profit organization dedicated to making software imaging solutions
Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization dedicated freely available.
to making software imaging solutions freely available.
1. Definitions. 1. Definitions.

View File

@ -1,6 +1,4 @@
Info-ZIP License Info-ZIP License Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
For the purposes of this copyright and license, "Info-ZIP" is defined as the For the purposes of this copyright and license, "Info-ZIP" is defined as the
following set of individuals: following set of individuals:

View File

@ -1,6 +1,4 @@
Intel Open Source License Intel Open Source License Copyright (c) 1996-2000 Intel Corporation
Copyright (c) 1996-2000 Intel Corporation
All rights reserved. All rights reserved.

View File

@ -429,7 +429,7 @@ in Exhibit A.
EXHIBIT A - InterBase Public License. EXHIBIT A - InterBase Public License.
" The contents of this file are subject to the Interbase Public License Version "The contents of this file are subject to the Interbase Public License Version
1.0 (the "License"); you may not use this file except in compliance with the 1.0 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.Interbase.com/IPL.html License. You may obtain a copy of the License at http://www.Interbase.com/IPL.html

View File

@ -1,6 +1,4 @@
JSON License JSON License Copyright (c) 2002 JSON.org
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,4 @@
JasPer License Version 2.0 JasPer License Version 2.0 Copyright (c) 2001-2006 Michael David Adams
Copyright (c) 2001-2006 Michael David Adams
Copyright (c) 1999-2000 Image Power, Inc. Copyright (c) 1999-2000 Image Power, Inc.

View File

@ -1,6 +1,6 @@
Licence Art Libre 1.3 (LAL 1.3) Licence Art Libre 1.3 (LAL 1.3)
Préambule : Préambule :
Avec la Licence Art Libre, l'autorisation est donnée de copier, de diffuser Avec la Licence Art Libre, l'autorisation est donnée de copier, de diffuser
et de transformer librement les œuvres dans le respect des droits de l'auteur. et de transformer librement les œuvres dans le respect des droits de l'auteur.
@ -12,44 +12,44 @@ d'expression.
Si, en règle générale, l'application du droit d'auteur conduit à restreindre Si, en règle générale, l'application du droit d'auteur conduit à restreindre
l'accès aux œuvres de l'esprit, la Licence Art Libre, au contraire, le favorise. l'accès aux œuvres de l'esprit, la Licence Art Libre, au contraire, le favorise.
L'intention est d'autoriser l'utilisation des ressources d'une œuvre ; créer L'intention est d'autoriser l'utilisation des ressources d'une œuvre ; créer
de nouvelles conditions de création pour amplifier les possibilités de création. de nouvelles conditions de création pour amplifier les possibilités de création.
La Licence Art Libre permet d'avoir jouissance des œuvres tout en reconnaissant La Licence Art Libre permet d'avoir jouissance des œuvres tout en reconnaissant
les droits et les responsabilités de chacun. les droits et les responsabilités de chacun.
Avec le développement du numérique, l'invention d'internet et des logiciels Avec le développement du numérique, l'invention d'internet et des logiciels
libres, les modalités de création ont évolué : les productions de l'esprit libres, les modalités de création ont évolué : les productions de l'esprit
s'offrent naturellement à la circulation, à l'échange et aux transformations. s'offrent naturellement à la circulation, à l'échange et aux transformations.
Elles se prêtent favorablement à la réalisation d'œuvres communes que chacun Elles se prêtent favorablement à la réalisation d'œuvres communes que chacun
peut augmenter pour l'avantage de tous. peut augmenter pour l'avantage de tous.
C'est la raison essentielle de la Licence Art Libre : promouvoir et protéger C'est la raison essentielle de la Licence Art Libre : promouvoir et protéger
ces productions de l'esprit selon les principes du copyleft : liberté d'usage, ces productions de l'esprit selon les principes du copyleft : liberté d'usage,
de copie, de diffusion, de transformation et interdiction d'appropriation de copie, de diffusion, de transformation et interdiction d'appropriation
exclusive. exclusive.
Définitions : Définitions :
Nous désignons par « œuvre », autant l'œuvre initiale, les œuvres conséquentes, Nous désignons par « œuvre », autant l'œuvre initiale, les œuvres conséquentes,
que l'œuvre commune telles que définies ci-après : que l'œuvre commune telles que définies ci-après :
L'œuvre commune : Il s'agit d'une œuvre qui comprend l'œuvre initiale ainsi L'œuvre commune : Il s'agit d'une œuvre qui comprend l'œuvre initiale ainsi
que toutes les contributions postérieures (les originaux conséquents et les que toutes les contributions postérieures (les originaux conséquents et les
copies). Elle est créée à l'initiative de l'auteur initial qui par cette licence copies). Elle est créée à l'initiative de l'auteur initial qui par cette licence
définit les conditions selon lesquelles les contributions sont faites. définit les conditions selon lesquelles les contributions sont faites.
L'œuvre initiale : C'est-à-dire l'œuvre créée par l'initiateur de l'œuvre L'œuvre initiale : C'est-à-dire l'œuvre créée par l'initiateur de l'œuvre
commune dont les copies vont être modifiées par qui le souhaite. commune dont les copies vont être modifiées par qui le souhaite.
Les œuvres conséquentes : C'est-à-dire les contributions des auteurs qui participent Les œuvres conséquentes : C'est-à-dire les contributions des auteurs qui participent
à la formation de l'œuvre commune en faisant usage des droits de reproduction, à la formation de l'œuvre commune en faisant usage des droits de reproduction,
de diffusion et de modification que leur confère la licence. de diffusion et de modification que leur confère la licence.
Originaux (sources ou ressources de l'œuvre) : Chaque exemplaire daté de l'œuvre Originaux (sources ou ressources de l'œuvre) : Chaque exemplaire daté de l'œuvre
initiale ou conséquente que leurs auteurs présentent comme référence pour initiale ou conséquente que leurs auteurs présentent comme référence pour
toutes actualisations, interprétations, copies ou reproductions ultérieures. toutes actualisations, interprétations, copies ou reproductions ultérieures.
Copie : Toute reproduction d'un original au sens de cette licence. Copie : Toute reproduction d'un original au sens de cette licence.
1- OBJET. 1- OBJET.
@ -70,33 +70,30 @@ personne, quelle que soit la technique employée.
Vous pouvez diffuser librement les copies de ces œuvres, modifiées ou non, Vous pouvez diffuser librement les copies de ces œuvres, modifiées ou non,
quel que soit le support, quel que soit le lieu, à titre onéreux ou gratuit, quel que soit le support, quel que soit le lieu, à titre onéreux ou gratuit,
si vous respectez toutes les conditions suivantes : si vous respectez toutes les conditions suivantes :
1. joindre aux copies cette licence à l'identique ou indiquer précisément 1. joindre aux copies cette licence à l'identique ou indiquer précisément
où se trouve la licence ; où se trouve la licence ;
2. indiquer au destinataire le nom de chaque auteur des originaux, y compris 2. indiquer au destinataire le nom de chaque auteur des originaux, y compris
le vôtre si vous avez modifié l'œuvre ; le vôtre si vous avez modifié l'œuvre ;
3. indiquer au destinataire où il pourrait avoir accès aux originaux (initiaux 3. indiquer au destinataire où il pourrait avoir accès aux originaux (initiaux
et/ou conséquents). et/ou conséquents). Les auteurs des originaux pourront, s'ils le souhaitent,
vous autoriser à diffuser l'original dans les mêmes conditions que les copies.
Les auteurs des originaux pourront, s'ils le souhaitent, vous autoriser à
diffuser l'original dans les mêmes conditions que les copies.
2.3 LA LIBERTÉ DE MODIFIER. 2.3 LA LIBERTÉ DE MODIFIER.
Vous avez la liberté de modifier les copies des originaux (initiaux et conséquents) Vous avez la liberté de modifier les copies des originaux (initiaux et conséquents)
dans le respect des conditions suivantes : dans le respect des conditions suivantes :
1. celles prévues à l'article 2.2 en cas de diffusion de la copie modifiée 1. celles prévues à l'article 2.2 en cas de diffusion de la copie modifiée ;
;
2. indiquer qu'il s'agit d'une œuvre modifiée et, si possible, la nature de 2. indiquer qu'il s'agit d'une œuvre modifiée et, si possible, la nature de
la modification ; la modification ;
3. diffuser cette œuvre conséquente avec la même licence ou avec toute licence 3. diffuser cette œuvre conséquente avec la même licence ou avec toute licence
compatible ; compatible ;
4. Les auteurs des originaux pourront, s'ils le souhaitent, vous autoriser 4. Les auteurs des originaux pourront, s'ils le souhaitent, vous autoriser
à modifier l'original dans les mêmes conditions que les copies. à modifier l'original dans les mêmes conditions que les copies.
@ -104,11 +101,12 @@ compatible ;
3. DROITS CONNEXES. 3. DROITS CONNEXES.
Les actes donnant lieu à des droits d'auteur ou des droits voisins ne doivent Les actes donnant lieu à des droits d'auteur ou des droits voisins ne doivent
pas constituer un obstacle aux libertés conférées par cette licence. C'est pas constituer un obstacle aux libertés conférées par cette licence.
pourquoi, par exemple, les interprétations doivent être soumises à la même
licence ou une licence compatible. De même, l'intégration de l'œuvre à une C'est pourquoi, par exemple, les interprétations doivent être soumises à la
base de données, une compilation ou une anthologie ne doit pas faire obstacle même licence ou une licence compatible. De même, l'intégration de l'œuvre
à la jouissance de l'œuvre telle que définie par cette licence. à une base de données, une compilation ou une anthologie ne doit pas faire
obstacle à la jouissance de l'œuvre telle que définie par cette licence.
4. L' INTÉGRATION DE L'ŒUVRE. 4. L' INTÉGRATION DE L'ŒUVRE.
@ -121,16 +119,16 @@ compatible.
5. CRITÈRES DE COMPATIBILITÉ. 5. CRITÈRES DE COMPATIBILITÉ.
Une licence est compatible avec la LAL si et seulement si : Une licence est compatible avec la LAL si et seulement si :
1. elle accorde l'autorisation de copier, diffuser et modifier des copies 1. elle accorde l'autorisation de copier, diffuser et modifier des copies
de l'œuvre, y compris à des fins lucratives, et sans autres restrictions que de l'œuvre, y compris à des fins lucratives, et sans autres restrictions que
celles qu'impose le respect des autres critères de compatibilité ; celles qu'impose le respect des autres critères de compatibilité ;
2. elle garantit la paternité de l'œuvre et l'accès aux versions antérieures 2. elle garantit la paternité de l'œuvre et l'accès aux versions antérieures
de l'œuvre quand cet accès est possible ; de l'œuvre quand cet accès est possible ;
3. elle reconnaît la LAL également compatible (réciprocité) ; 3. elle reconnaît la LAL également compatible (réciprocité) ;
4. elle impose que les modifications faites sur l'œuvre soient soumises à 4. elle impose que les modifications faites sur l'œuvre soient soumises à
la même licence ou encore à une licence répondant aux critères de compatibilité la même licence ou encore à une licence répondant aux critères de compatibilité

View File

@ -1,8 +1,6 @@
GNU LIBRARY GENERAL PUBLIC LICENSE GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc.
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA

View File

@ -1,8 +1,6 @@
GNU LIBRARY GENERAL PUBLIC LICENSE GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc.
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA

View File

@ -2,7 +2,7 @@ GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.

View File

@ -2,7 +2,7 @@ GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http s ://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed. document, but changing it is not allowed.

View File

@ -1,8 +1,6 @@
LaTeX Project Public License LaTeX Project Public License
LPPL Version 1.0 1999-03-01 LPPL Version 1.0 1999-03-01 Copyright 1999 LaTeX3 Project
Copyright 1999 LaTeX3 Project
Everyone is permitted to copy and distribute verbatim copies of this license Everyone is permitted to copy and distribute verbatim copies of this license
document, but modification is not allowed. document, but modification is not allowed.

View File

@ -2,9 +2,7 @@ The LaTeX Project Public License
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
LPPL Version 1.1 1999-07-10 LPPL Version 1.1 1999-07-10 Copyright 1999 LaTeX3 Project
Copyright 1999 LaTeX3 Project
Everyone is allowed to distribute verbatim copies of this license document, Everyone is allowed to distribute verbatim copies of this license document,
but modification of it is not allowed. but modification of it is not allowed.

View File

@ -2,9 +2,7 @@ The LaTeX Project Public License
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
LPPL Version 1.2 1999-09-03 LPPL Version 1.2 1999-09-03 Copyright 1999 LaTeX3 Project
Copyright 1999 LaTeX3 Project
Everyone is allowed to distribute verbatim copies of this license document, Everyone is allowed to distribute verbatim copies of this license document,
but modification of it is not allowed. but modification of it is not allowed.

View File

@ -2,9 +2,7 @@ The LaTeX Project Public License
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
LPPL Version 1.3a 2004-10-01 LPPL Version 1.3a 2004-10-01 Copyright 1999 2002-04 LaTeX3 Project
Copyright 1999 2002-04 LaTeX3 Project
Everyone is allowed to distribute verbatim copies of this license document, Everyone is allowed to distribute verbatim copies of this license document,
but modification of it is not allowed. but modification of it is not allowed.

View File

@ -2,9 +2,7 @@ The LaTeX Project Public License
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
LPPL Version 1.3c 2008-05-04 LPPL Version 1.3c 2008-05-04 Copyright 1999 2002-2008 LaTeX3 Project
Copyright 1999 2002-2008 LaTeX3 Project
Everyone is allowed to distribute verbatim copies of this license document, Everyone is allowed to distribute verbatim copies of this license document,
but modification of it is not allowed. but modification of it is not allowed.

View File

@ -1,6 +1,4 @@
MIT License MIT License Copyright (c) <year> <copyright holders>
Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,22 +1,17 @@
Copyright 1989, 1991, 1992 by Carnegie Mellon University <copyright notice> By obtaining, using, and/or copying this software and/or
its associated documentation, you agree that you have read, understood, and
will comply with the following terms and conditions:
Derivative Work - 1996, 1998-2000 Copyright 1996, 1998-2000 The Regents of Permission to use, copy, modify, and distribute this software and its associated
the University of California documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appears in all copies, and that both that
copyright notice and this permission notice appear in supporting documentation,
and that the name of the copyright holder not be used in advertising or publicity
pertaining to distribution of the software without specific, written permission.
All Rights Reserved THE COPYRIGHT HOLDER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
Permission to use, copy, modify and distribute this software and its documentation SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
for any purpose and without fee is hereby granted, provided that the above DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM THE LOSS OF USE, DATA OR
copyright notice appears in all copies and that both that copyright notice PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
and this permission notice appear in supporting documentation, and that the ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
name of CMU and The Regents of the University of California not be used in
advertising or publicity pertaining to distribution of the software without
specific written permission.
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL CMU OR THE REGENTS OF THE UNIVERSITY OF CALIFORNIA
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@ -319,7 +319,7 @@ of Covered Code you made available, the revenues you received from utilizing
such rights, and other relevant factors. You agree to work with affected parties such rights, and other relevant factors. You agree to work with affected parties
to distribute responsibility on an equitable basis. EXHIBIT A. to distribute responsibility on an equitable basis. EXHIBIT A.
" The contents of this file are subject to the Mozilla Public License Version "The contents of this file are subject to the Mozilla Public License Version
1.0 (the "License"); you may not use this file except in compliance with the 1.0 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
@ -329,4 +329,4 @@ the specific language governing rights and limitations under the License.
The Original Code is _____ . The Initial Developer of the Original Code is The Original Code is _____ . The Initial Developer of the Original Code is
_____ . Portions created by _____ are Copyright (C) _____ . All Rights Reserved. _____ . Portions created by _____ are Copyright (C) _____ . All Rights Reserved.
Contributor(s): _____ . " Contributor(s): _____ ."

View File

@ -389,7 +389,7 @@ portions of the Covered Code under Your choice of the MPL or the alternative
licenses, if any, specified by the Initial Developer in the file described licenses, if any, specified by the Initial Developer in the file described
in Exhibit A. Exhibit A - Mozilla Public License. in Exhibit A. Exhibit A - Mozilla Public License.
" The contents of this file are subject to the Mozilla Public License Version "The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with the 1.1 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
@ -414,7 +414,7 @@ to allow others to use your version of this file under the MPL, indicate your
decision by deleting the provisions above and replace them with the notice decision by deleting the provisions above and replace them with the notice
and other provisions required by the [___] License. If you do not delete the and other provisions required by the [___] License. If you do not delete the
provisions above, a recipient may use your version of this file under either provisions above, a recipient may use your version of this file under either
the MPL or the [___] License. " the MPL or the [___] License."
NOTE: The text of this Exhibit A may differ slightly from the text of the NOTE: The text of this Exhibit A may differ slightly from the text of the
notices in the Source Code files of the Original Code. You should use the notices in the Source Code files of the Original Code. You should use the

View File

@ -1,6 +1,4 @@
Software License for MTL Software License for MTL Copyright (c) 2007 The Trustees of Indiana University.
Copyright (c) 2007 The Trustees of Indiana University.
2008 Dresden University of Technology and the Trustees of Indiana University. 2008 Dresden University of Technology and the Trustees of Indiana University.

View File

@ -1,8 +1,6 @@
MakeIndex Distribution Notice MakeIndex Distribution Notice
11/11/1989 11/11/1989 Copyright (C) 1989 by Chen & Harrison International Systems, Inc.
Copyright (C) 1989 by Chen & Harrison International Systems, Inc.
Copyright (C) 1988 by Olivetti Research Center Copyright (C) 1988 by Olivetti Research Center

View File

@ -1,8 +1,4 @@
MirOS License The MirOS Licence Copyright [YEAR] [NAME] [EMAIL]
Copyright [YEAR]
[NAME] [EMAIL]
Provided that these terms and disclaimer and all copyright notices are retained Provided that these terms and disclaimer and all copyright notices are retained
or reproduced in an accompanying document, permission is granted to deal in or reproduced in an accompanying document, permission is granted to deal in
@ -15,50 +11,4 @@ intent or gross negligence. In no event may a licensor, author or contributor
be held liable for indirect, direct, other damage, loss, or other issues arising be held liable for indirect, direct, other damage, loss, or other issues arising
in any way out of dealing in the work, even if advised of the possibility in any way out of dealing in the work, even if advised of the possibility
of such damage or existence of a defect, except proven that it results out of such damage or existence of a defect, except proven that it results out
of said person's immediate fault when using the work as intended. I_N_S_T_R_U_C_T_I_O_N_S_:_ of said person's immediate fault when using the work as intended.
To apply the template(1) specify the years of copyright (separated by comma,
not as a range), the legal names of the copyright holders, and the real names
of the authors if different. Avoid adding text.
R_A_T_I_O_N_A_L_E_:_
This licence is apt for any kind of work (such as source code, fonts, documentation,
graphics, sound etc.) and the preferred terms for work added to MirBSD. It
has been drafted as universally usable equivalent of the "historic permission
notice"(2) adapted to Europen law because in some (droit d'auteur) countries
authors cannot disclaim all liabi lities. Compliance to DFSG(3) 1.1 is ensured,
and GPLv2 compatibility is asserted unless advertising clauses are used. The
MirOS Licence is certified to conform to OKD(4) 1.0 and OSD(5) 1.9, and qualifies
as a Free Software(6) and also Free Documentation(7) licence and is included
in some relevant lists(8)(9)(10).
We believe you are not liable for work inserted which is intellectual property
of third parties, if you were not aware of the fact, act appropriately as
soon as you become aware of that problem, seek an amicable solution for all
parties, and never knowingly distribute a work without being authorised to
do so by its licensors.
R_E_F_E_R_E_N_C_E_S_:_
(1) also at http://mirbsd.de/MirOS-Licence
(2) http://www.opensource.org/licenses/historical.php
(3) http://www.debian.org/social_contract#guidelines
(4) http://www.opendefinition.org/1.0
(5) http://www.opensource.org/docs/osd
(6) http://www.gnu.org/philosophy/free-sw.html
(7) http://www.gnu.org/philosophy/free-doc.html
(8) http://www.ifross.de/ifross_html/lizenzcenter.html
(9) http://www.opendefinition.org/licenses
(10) http://opensource.org/licenses/miros.html

View File

@ -23,10 +23,9 @@ copyright notice and historical background appear in all copies and that both
the copyright notice and historical background and this permission notice the copyright notice and historical background and this permission notice
appear in supporting documentation, and that the names of MIT, HIS, BULL or appear in supporting documentation, and that the names of MIT, HIS, BULL or
BULL HN not be used in advertising or publicity pertaining to distribution BULL HN not be used in advertising or publicity pertaining to distribution
of the programs without specific prior written permission. of the programs without specific prior written permission. Copyright 1972
by Massachusetts Institute of Technology and Honeywell Information Systems
Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Inc.
Systems Inc.
Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc.

View File

@ -1,9 +1,8 @@
The Net Boolean Public License The Net Boolean Public License Version 1, 22 August 1998 Copyright 1998, Net
Boolean Incorporated, Redwood City, California, USA All Rights Reserved. Note:
Version 1, 22 August 1998 Copyright 1998, Net Boolean Incorporated, Redwood This license is derived from the "Artistic License" as distributed with the
City, California, USA All Rights Reserved. Note: This license is derived from Perl Programming Language. Its terms are different from those of the "Artistic
the "Artistic License" as distributed with the Perl Programming Language. License."
Its terms are different from those of the "Artistic License."
PREAMBLE PREAMBLE

View File

@ -1,6 +1,5 @@
University of Illinois/NCSA Open Source License University of Illinois/NCSA Open Source License Copyright (c) <Year> <Owner
Organization Name>. All rights reserved.
Copyright (c) <Year> <Owner Organization Name> . All rights reserved.
Developed by: Developed by:

View File

@ -1,6 +1,4 @@
NETHACK GENERAL PUBLIC LICENSE NETHACK GENERAL PUBLIC LICENSE (Copyright 1989 M. Stephenson)
(Copyright 1989 M. Stephenson)
(Based on the BISON general public license, copyright 1988 Richard M. Stallman) (Based on the BISON general public license, copyright 1988 Richard M. Stallman)

View File

@ -1,6 +1,5 @@
NTP License (NTP) NTP License (NTP) Copyright (c) (CopyrightHoldersName) (From 4-digit-year)-(To
4-digit-year)
Copyright (c) (CopyrightHoldersName) (From 4-digit-year)-(To 4-digit-year)
Permission to use, copy, modify, and distribute this software and its documentation Permission to use, copy, modify, and distribute this software and its documentation
for any purpose with or without fee is hereby granted, provided that the above for any purpose with or without fee is hereby granted, provided that the above

View File

@ -1,6 +1,5 @@
NAUMEN Public License NAUMEN Public License This software is Copyright (c) NAUMEN (tm) and Contributors.
All rights reserved.
This software is Copyright (c) NAUMEN (tm) and Contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -1,6 +1,5 @@
---- Part 1: CMU/UCD copyright notice: (BSD like) ----- ---- Part 1: CMU/UCD copyright notice: (BSD like) ----- Copyright 1989, 1991,
1992 by Carnegie Mellon University
Copyright 1989, 1991, 1992 by Carnegie Mellon University
Derivative Work - 1996, 1998-2000 Copyright 1996, 1998-2000 The Regents of Derivative Work - 1996, 1998-2000 Copyright 1996, 1998-2000 The Regents of
the University of California the University of California
@ -79,10 +78,9 @@ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
---- Part 4: Sun Microsystems, Inc. copyright notice (BSD) ----- ---- Part 4: Sun Microsystems, Inc. copyright notice (BSD) ----- Copyright
© 2003 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California
Copyright © 2003 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 95054, U.S.A. All rights reserved.
California 95054, U.S.A. All rights reserved.
Use is subject to license terms below. Use is subject to license terms below.
@ -174,7 +172,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- Part 7: Fabasoft R&D Software GmbH & Co KG copyright notice (BSD) ----- ---- Part 7: Fabasoft R&D Software GmbH & Co KG copyright notice (BSD) -----
Copyright (c) Fabasoft R&D Software GmbH & Co KG, 2003 oss@fabasoft.com Author: Copyright (c) Fabasoft R&D Software GmbH & Co KG, 2003 oss@fabasoft.com Author:
Bernhard Penz Bernhard Penz
@ -203,9 +200,8 @@ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.
---- Part 8: Apple Inc. copyright notice (BSD) ----- ---- Part 8: Apple Inc. copyright notice (BSD) ----- Copyright (c) 2007 Apple
Inc. All rights reserved.
Copyright (c) 2007 Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:

View File

@ -2,9 +2,8 @@ OCLC Research Public License 2.0
Terms & Conditions Of Use Terms & Conditions Of Use
May, 2002 May, 2002 Copyright © 2002. OCLC Online Computer Library Center, Inc. All
Rights Reserved
Copyright © 2002. OCLC Online Computer Library Center, Inc. All Rights Reserved
PLEASE READ THIS DOCUMENT CAREFULLY. BY DOWNLOADING OR USING THE CODE BASE PLEASE READ THIS DOCUMENT CAREFULLY. BY DOWNLOADING OR USING THE CODE BASE
AND/OR DOCUMENTATION ACCOMPANYING THIS LICENSE (THE "License"), YOU AGREE AND/OR DOCUMENTATION ACCOMPANYING THIS LICENSE (THE "License"), YOU AGREE
@ -79,7 +78,7 @@ If you distribute the Program in a form to which the recipient can make Modifica
addition, each source and data file of the Program and any Modification you addition, each source and data file of the Program and any Modification you
distribute must contain the following notice: distribute must contain the following notice:
" Copyright (c) 2000- (insert then current year) OCLC Online Computer Library "Copyright (c) 2000- (insert then current year) OCLC Online Computer Library
Center, Inc. and other contributors . All rights reserved. The contents of Center, Inc. and other contributors . All rights reserved. The contents of
this file, as updated from time to time by the OCLC Office of Research, are this file, as updated from time to time by the OCLC Office of Research, are
subject to OCLC Research Public License Version 2.0 (the "License"); you may subject to OCLC Research Public License Version 2.0 (the "License"); you may
@ -93,7 +92,7 @@ OCLC Research. For more information on OCLC Research, please see http://www.oclc
The Original Code is ______________________________ . The Initial Developer The Original Code is ______________________________ . The Initial Developer
of the Original Code is ________________________ . Portions created by ______________________ of the Original Code is ________________________ . Portions created by ______________________
are Copyright (C) ____________________________ . All Rights Reserved. Contributor(s): are Copyright (C) ____________________________ . All Rights Reserved. Contributor(s):
______________________________________ . " ______________________________________ ."
C. Requirements for a Distribution of Non-modifiable Code C. Requirements for a Distribution of Non-modifiable Code

View File

@ -1,10 +1,9 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 1.1, 25 August 1998 Version 1.1, 25 August 1998 Copyright 1998, The OpenLDAP Foundation. All Rights
Reserved. Note: This license is derived from the "Artistic License" as distributed
Copyright 1998, The OpenLDAP Foundation. All Rights Reserved. Note: This license with the Perl Programming Language. Its terms are different from those of
is derived from the "Artistic License" as distributed with the Perl Programming the "Artistic License."
Language. Its terms are different from those of the "Artistic License."
PREAMBLE PREAMBLE

View File

@ -1,10 +1,9 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 1.2, 1 September 1998 Version 1.2, 1 September 1998 Copyright 1998, The OpenLDAP Foundation. All
Rights Reserved. Note: This license is derived from the "Artistic License"
Copyright 1998, The OpenLDAP Foundation. All Rights Reserved. Note: This license as distributed with the Perl Programming Language. As differences may exist,
is derived from the "Artistic License" as distributed with the Perl Programming the complete license should be read.
Language. As differences may exist, the complete license should be read.
PREAMBLE PREAMBLE

View File

@ -1,11 +1,9 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 1.3, 17 January 1999 Version 1.3, 17 January 1999 Copyright 1998-1999, The OpenLDAP Foundation.
All Rights Reserved. Note: This license is derived from the "Artistic License"
Copyright 1998-1999, The OpenLDAP Foundation. All Rights Reserved. Note: This as distributed with the Perl Programming Language. As significant differences
license is derived from the "Artistic License" as distributed with the Perl exist, the complete license should be read.
Programming Language. As significant differences exist, the complete license
should be read.
PREAMBLE PREAMBLE

View File

@ -1,11 +1,9 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 1.4, 18 January 1999 Version 1.4, 18 January 1999 Copyright 1998-1999, The OpenLDAP Foundation.
All Rights Reserved. Note: This license is derived from the "Artistic License"
Copyright 1998-1999, The OpenLDAP Foundation. All Rights Reserved. Note: This as distributed with the Perl Programming Language. As significant differences
license is derived from the "Artistic License" as distributed with the Perl exist, the complete license should be read.
Programming Language. As significant differences exist, the complete license
should be read.
PREAMBLE PREAMBLE

Some files were not shown because too many files have changed in this diff Show More