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),
@ -243,7 +252,6 @@ func (b *BleveIndexer) Search(keyword string, repoID int64, limit, start int) (*
} }
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
} }
@ -38,7 +38,6 @@ 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

@ -29,7 +29,6 @@ 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"`
} }
@ -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)
if r.IsWiki {
lnk = util.URLJoin("wiki", lnk)
}
mLink := util.URLJoin(r.URLPrefix, lnk)
link = []byte(mLink)
} }
if len(content) > 10 && string(content[0:9]) == "<a href=\"" && bytes.Contains(content[9:], []byte("<img")) { func escapeHTML(w io.Writer, s []byte) {
// Image with link case: markdown `[![]()]()` var start, end int
// If the content is an image, then we change the original href around it for end < len(s) {
// which points to itself to a new address "link" escSeq := htmlEscaper[s[end]]
rightQuote := bytes.Index(content[9:], []byte("\"")) if escSeq != nil {
content = bytes.Replace(content, content[9:9+rightQuote], link, 1) _, _ = w.Write(s[start:end])
out.Write(content) _, _ = w.Write(escSeq)
} else { start = end + 1
r.Renderer.Link(out, link, title, content) }
end++
}
if start < len(s) && end <= len(s) {
_, _ = w.Write(s[start:end])
} }
} }
// List renders markdown bullet or digit lists to HTML // RenderNode is a default renderer of a single node of a syntax tree. For
func (r *Renderer) List(out *bytes.Buffer, text func() bool, flags int) { // block nodes it will be called twice: first time with entering=true, second
marker := out.Len() // time with entering=false, so that it could know when it's working on an open
if out.Len() > 0 { // tag and when on close. It writes the result to w.
out.WriteByte('\n') //
} // 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
if flags&blackfriday.LIST_TYPE_DEFINITION != 0 { // can ask the walker to skip a subtree of this node by returning SkipChildren.
out.WriteString("<dl>") // The typical behavior is to return GoToNext, which asks for the usual
} else if flags&blackfriday.LIST_TYPE_ORDERED != 0 { // traversal to the next node.
out.WriteString("<ol class='ui list'>") func (r *Renderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
} else { switch node.Type {
out.WriteString("<ul class='ui list'>") case blackfriday.Image:
}
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] ")):
text = append([]byte(`<span class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
if prefix != "" {
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
}
}
r.Renderer.ListItem(out, text, flags)
}
// 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 prefix := r.URLPrefix
if r.IsWiki { if r.IsWiki {
prefix = util.URLJoin(prefix, "wiki", "raw") prefix = util.URLJoin(prefix, "wiki", "raw")
} }
prefix = strings.Replace(prefix, "/src/", "/media/", 1) prefix = strings.Replace(prefix, "/src/", "/media/", 1)
link := node.LinkData.Destination
if len(link) > 0 && !markup.IsLink(link) { if len(link) > 0 && !markup.IsLink(link) {
lnk := string(link) lnk := string(link)
lnk = util.URLJoin(prefix, lnk) lnk = util.URLJoin(prefix, lnk)
lnk = strings.Replace(lnk, " ", "+", -1) lnk = strings.Replace(lnk, " ", "+", -1)
link = []byte(lnk) link = []byte(lnk)
} }
node.LinkData.Destination = link
// Put a link around it pointing to itself by default // Render link around image only if parent is not link already
out.WriteString(`<a href="`) if node.Parent != nil && node.Parent.Type != blackfriday.Link {
out.Write(link) if entering {
out.WriteString(`">`) _, _ = w.Write([]byte(`<a href="`))
r.Renderer.Image(out, link, title, alt) escapeHTML(w, link)
out.WriteString("</a>") _, _ = 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
}
}
return r.Renderer.RenderNode(w, node, entering)
} }
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()
} }
// block-level callbacks 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()
}
// BlockCode dummy function to proceed with rendering // RenderNode is the main rendering method. It will be called once for
func (r *MarkdownStripper) BlockCode(out *bytes.Buffer, text []byte, infoString string) { // every leaf node and twice for every non-leaf node (first with
// Not rendered // entering=true, then with entering=false). The method should write its
// rendition of the node to the supplied writer w.
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 r.coallesce = false
return blackfriday.SkipChildren
} }
// BlockQuote dummy function to proceed with rendering
func (r *MarkdownStripper) BlockQuote(out *bytes.Buffer, text []byte) {
// FIXME: perhaps it's better to leave out block quote for this?
r.processString(out, text, false)
}
// BlockHtml dummy function to proceed with rendering
func (r *MarkdownStripper) BlockHtml(out *bytes.Buffer, text []byte) { //nolint
// Not rendered
r.coallesce = false r.coallesce = false
return blackfriday.GoToNext
} }
// Header dummy function to proceed with rendering // RenderHeader is a method that allows the renderer to produce some
func (r *MarkdownStripper) Header(out *bytes.Buffer, text func() bool, level int, id string) { // content preceding the main body of the output document.
text() func (r *MarkdownStripper) RenderHeader(w io.Writer, ast *blackfriday.Node) {
r.coallesce = false
} }
// HRule dummy function to proceed with rendering // RenderFooter is a symmetric counterpart of RenderHeader.
func (r *MarkdownStripper) HRule(out *bytes.Buffer) { func (r *MarkdownStripper) RenderFooter(w io.Writer, ast *blackfriday.Node) {
// Not rendered
r.coallesce = false
} }
// List dummy function to proceed with rendering func (r *MarkdownStripper) doubleSpace(w io.Writer) {
func (r *MarkdownStripper) List(out *bytes.Buffer, text func() bool, flags int) { if !r.empty {
text() _, _ = w.Write([]byte{'\n'})
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,
}
}()
htmlFlags := blackfriday.HTML_USE_XHTML
htmlFlags |= blackfriday.HTML_SKIP_STYLE
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
renderer := &markdown.Renderer{
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
URLPrefix: urlPrefix, URLPrefix: urlPrefix,
IsWiki: isWiki, 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()
var m []int
if issueCloseKeywordsPat != nil {
m = issueCloseKeywordsPat.FindSubmatchIndex(content[:start])
if m != nil { if m != nil {
return XRefActionCloses, &RefSpan{Start: m[2], End: m[3]} return XRefActionCloses, &RefSpan{Start: m[2], End: m[3]}
} }
}
if issueReopenKeywordsPat != nil {
m = issueReopenKeywordsPat.FindSubmatchIndex(content[:start]) m = issueReopenKeywordsPat.FindSubmatchIndex(content[:start])
if m != nil { if m != nil {
return XRefActionReopens, &RefSpan{Start: m[2], End: m[3]} return XRefActionReopens, &RefSpan{Start: m[2], End: m[3]}
} }
}
return XRefActionNone, nil return XRefActionNone, nil
} }

View File

@ -12,9 +12,12 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestFindAllIssueReferences(t *testing.T) { type testFixture struct {
input string
expected []testResult
}
type result struct { type testResult struct {
Index int64 Index int64
Owner string Owner string
Name string Name string
@ -24,149 +27,121 @@ func TestFindAllIssueReferences(t *testing.T) {
ActionLocation *RefSpan ActionLocation *RefSpan
} }
type testFixture struct { func TestFindAllIssueReferences(t *testing.T) {
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

@ -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

@ -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,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,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,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

@ -615,8 +615,7 @@ 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

View File

@ -615,8 +615,7 @@ 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

View File

@ -1,6 +1,4 @@
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

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

@ -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

@ -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

@ -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

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

View File

@ -1,9 +1,7 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 2.0, 7 June 1999 Version 2.0, 7 June 1999 Copyright 1999, The OpenLDAP Foundation, Redwood
City, California, USA. All Rights Reserved.
Copyright 1999, The OpenLDAP Foundation, Redwood City, California, USA. All
Rights Reserved.
Redistribution and use of this software and associated documentation ("Software"), Redistribution and use of this software and associated documentation ("Software"),
with or without modification, are permitted provided that the following conditions with or without modification, are permitted provided that the following conditions

View File

@ -1,9 +1,7 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 2.0.1, 21 December 1999 Version 2.0.1, 21 December 1999 Copyright 1999, The OpenLDAP Foundation, Redwood
City, California, USA. All Rights Reserved.
Copyright 1999, The OpenLDAP Foundation, Redwood City, California, USA. All
Rights Reserved.
Redistribution and use of this software and associated documentation ("Software"), Redistribution and use of this software and associated documentation ("Software"),
with or without modification, are permitted provided that the following conditions with or without modification, are permitted provided that the following conditions

View File

@ -1,9 +1,7 @@
The OpenLDAP Public License The OpenLDAP Public License
Version 2.1, 29 February 2000 Version 2.1, 29 February 2000 Copyright 1999-2000, The OpenLDAP Foundation,
Redwood City, California, USA. All Rights Reserved.
Copyright 1999-2000, The OpenLDAP Foundation, Redwood City, California, USA.
All Rights Reserved.
Redistribution and use of this software and associated documentation ("Software"), Redistribution and use of this software and associated documentation ("Software"),
with or without modification, are permitted provided that the following conditions with or without modification, are permitted provided that the following conditions

View File

@ -1,9 +1,7 @@
OSET Public License OSET Public License (c) 2015 ALL RIGHTS RESERVED VERSION 2.1 THIS LICENSE
DEFINES THE RIGHTS OF USE, REPRODUCTION, DISTRIBUTION, MODIFICATION, AND REDISTRIBUTION
(c) 2015 ALL RIGHTS RESERVED VERSION 2.1 THIS LICENSE DEFINES THE RIGHTS OF OF CERTAIN COVERED SOFTWARE (AS DEFINED BELOW) ORIGINALLY RELEASED BY THE
USE, REPRODUCTION, DISTRIBUTION, MODIFICATION, AND REDISTRIBUTION OF CERTAIN OPEN SOURCE ELECTION TECHNOLOGY FOUNDATION (FORMERLY "THE OSDV FOUNDATION").
COVERED SOFTWARE (AS DEFINED BELOW) ORIGINALLY RELEASED BY THE OPEN SOURCE
ELECTION TECHNOLOGY FOUNDATION (FORMERLY "THE OSDV FOUNDATION").
ANYONE WHO USES, REPRODUCES, DISTRIBUTES, MODIFIES, OR REDISTRIBUTES THE COVERED ANYONE WHO USES, REPRODUCES, DISTRIBUTES, MODIFIES, OR REDISTRIBUTES THE COVERED
SOFTWARE, OR ANY PART THEREOF, IS BY THAT ACTION, ACCEPTING IN FULL THE TERMS SOFTWARE, OR ANY PART THEREOF, IS BY THAT ACTION, ACCEPTING IN FULL THE TERMS

View File

@ -1,6 +1,4 @@
OpenSSL License OpenSSL License Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
Copyright (c) 1998-2008 The OpenSSL 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:
@ -41,9 +39,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This product includes cryptographic software written by Eric Young (eay@cryptsoft.com). This product includes cryptographic software written by Eric Young (eay@cryptsoft.com).
This product includes software written by Tim Hudson (tjh@cryptsoft.com). This product includes software written by Tim Hudson (tjh@cryptsoft.com).
Original SSLeay License Original SSLeay License Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
All rights reserved. All rights reserved.

View File

@ -1,6 +1,5 @@
The PHP License, version 3.0 The PHP License, version 3.0 Copyright (c) 1999 - 2006 The PHP Group. All
rights reserved.
Copyright (c) 1999 - 2006 The PHP Group. 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,
is permitted provided that the following conditions are met: is permitted provided that the following conditions are met:

View File

@ -1,6 +1,5 @@
The PHP License, version 3.01 The PHP License, version 3.01 Copyright (c) 1999 - 2012 The PHP Group. All
rights reserved.
Copyright (c) 1999 - 2012 The PHP Group. 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,
is permitted provided that the following conditions are met: is permitted provided that the following conditions are met:

View File

@ -1,8 +1,7 @@
PostgreSQL Database Management System PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95) (formerly known as Postgres, then as Postgres95) Portions Copyright (c) 1996-2010,
The PostgreSQL Global Development Group
Portions Copyright (c) 1996-2010, The PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California Portions Copyright (c) 1994, The Regents of the University of California

View File

@ -140,10 +140,8 @@ or any third party.
8. By clicking on the "ACCEPT" button where indicated, or by copying, installing 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing
or otherwise using Python 1.6b1, Licensee agrees to be bound by the terms or otherwise using Python 1.6b1, Licensee agrees to be bound by the terms
and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR
PYTHON 0.9.0 THROUGH 1.2 PYTHON 0.9.0 THROUGH 1.2 Copyright (c) 1991 - 1995, Stichting Mathematisch
Centrum Amsterdam, The Netherlands. All rights reserved.
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands.
All rights reserved.
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

View File

@ -1,6 +1,4 @@
THE Q PUBLIC LICENSE version 1.0 THE Q PUBLIC LICENSE version 1.0 Copyright (C) 1999-2005 Trolltech AS, Norway.
Copyright (C) 1999-2005 Trolltech AS, Norway.
Everyone is permitted to copy and distribute this license document. Everyone is permitted to copy and distribute this license document.

View File

@ -1,6 +1,5 @@
Reciprocal Public License, version 1.1 Reciprocal Public License, version 1.1 Copyright (C) 2001-2002 Technical Pursuit
Inc., All Rights Reserved. PREAMBLE
Copyright (C) 2001-2002 Technical Pursuit Inc., All Rights Reserved. PREAMBLE
This Preamble is intended to describe, in plain English, the nature, intent, This Preamble is intended to describe, in plain English, the nature, intent,
and scope of this License. However, this Preamble is not a part of this License. and scope of this License. However, this Preamble is not a part of this License.

View File

@ -301,13 +301,13 @@ NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDIC
DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES,
SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. TO THE EXTENT THAT SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. TO THE EXTENT THAT
ANY EXCLUSION OF DAMAGES ABOVE IS NOT VALID, YOU AGREE THAT IN NO EVENT WILL ANY EXCLUSION OF DAMAGES ABOVE IS NOT VALID, YOU AGREE THAT IN NO EVENT WILL
RSV ' S LIABILITY UNDER OR RELATED TO THIS AGREEMENT EXCEED FIVE THOUSAND RSV'S LIABILITY UNDER OR RELATED TO THIS AGREEMENT EXCEED FIVE THOUSAND DOLLARS
DOLLARS ($5,000). THE GOVERNED CODE IS NOT INTENDED FOR USE IN CONNECTION ($5,000). THE GOVERNED CODE IS NOT INTENDED FOR USE IN CONNECTION WITH ANY
WITH ANY NUCLER, AVIATION, MASS TRANSIT OR MEDICAL APPLICATION OR ANY OTHER NUCLER, AVIATION, MASS TRANSIT OR MEDICAL APPLICATION OR ANY OTHER INHERENTLY
INHERENTLY DANGEROUS APPLICATION THAT COULD RESULT IN DEATH, PERSONAL INJURY, DANGEROUS APPLICATION THAT COULD RESULT IN DEATH, PERSONAL INJURY, CATASTROPHIC
CATASTROPHIC DAMAGE OR MASS DESTRUCTION, AND YOU AGREE THAT NEITHER RSV NOR DAMAGE OR MASS DESTRUCTION, AND YOU AGREE THAT NEITHER RSV NOR ANY CONTRIBUTOR
ANY CONTRIBUTOR SHALL HAVE ANY LIABILITY OF ANY NATURE AS A RESULT OF ANY SHALL HAVE ANY LIABILITY OF ANY NATURE AS A RESULT OF ANY SUCH USE OF THE
SUCH USE OF THE GOVERNED CODE. GOVERNED CODE.
10. U.S. Government End Users. 10. U.S. Government End Users.

View File

@ -222,11 +222,10 @@ INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANT
SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
Original Code. The Original Code is: [ name of software , version number , Original Code. The Original Code is: [ name of software , version number ,
and release date ] , developed by Silicon Graphics, Inc. The Original Code and release date], developed by Silicon Graphics, Inc. The Original Code is
is Copyright (c) [ dates of first publication, as appearing in the Notice Copyright (c) [ dates of first publication, as appearing in the Notice in
in the Original Code ] Silicon Graphics, Inc. Copyright in any portions created the Original Code] Silicon Graphics, Inc. Copyright in any portions created
by third parties is as indicated elsewhere herein. All Rights Reserved. by third parties is as indicated elsewhere herein. All Rights Reserved.
Additional Notice Provisions: [ such additional provisions, if any, as appear Additional Notice Provisions: [ such additional provisions, if any, as appear
in the Notice in the Original Code under the heading "Additional Notice Provisions" in the Notice in the Original Code under the heading "Additional Notice Provisions"]
]

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