mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-03 08:02:36 +09:00
Compare commits
61 Commits
v1.25.0-de
...
v1.12.0-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9749c35656 | ||
|
|
fc15e59475 | ||
|
|
78f0b5b92b | ||
|
|
20951c5c21 | ||
|
|
99f7ec8f45 | ||
|
|
a076cb2a4c | ||
|
|
530ae650f3 | ||
|
|
821570c0b0 | ||
|
|
287e2c781b | ||
|
|
921a5c0b62 | ||
|
|
0ad4083cba | ||
|
|
99058de553 | ||
|
|
fb155b8fa3 | ||
|
|
7dd9506d06 | ||
|
|
f428d40822 | ||
|
|
7339018c5e | ||
|
|
a34826b19f | ||
|
|
70739c32a9 | ||
|
|
249e22bb98 | ||
|
|
d78c31c216 | ||
|
|
795b6865af | ||
|
|
0e44fab5d6 | ||
|
|
6ad0d0a1b9 | ||
|
|
d9db28a25a | ||
|
|
5911e129a8 | ||
|
|
42f0769e30 | ||
|
|
0c40b0badd | ||
|
|
762c0463f4 | ||
|
|
bf1dbd7c56 | ||
|
|
600bb545f3 | ||
|
|
5331af1854 | ||
|
|
eb5ea5f67a | ||
|
|
5e3dd3fafe | ||
|
|
339f5bb397 | ||
|
|
1ae5435e41 | ||
|
|
ca61046f9f | ||
|
|
29368309ce | ||
|
|
a777f8ae75 | ||
|
|
80853a2238 | ||
|
|
ce958f45cd | ||
|
|
3b1e114ede | ||
|
|
573a9c6228 | ||
|
|
d131d53cbb | ||
|
|
2a6e6bf0f1 | ||
|
|
655def5141 | ||
|
|
2042cf2cce | ||
|
|
7b438b3566 | ||
|
|
8bde2e9813 | ||
|
|
8525a48581 | ||
|
|
034492384b | ||
|
|
c83bc55b52 | ||
|
|
09cc6392f6 | ||
|
|
b67eafbc21 | ||
|
|
c1ba480a7a | ||
|
|
1197512b2b | ||
|
|
1547ce5669 | ||
|
|
1aa6176bd8 | ||
|
|
2289e59bd7 | ||
|
|
6e75bc013e | ||
|
|
087719cb8d | ||
|
|
bbd9bebcc3 |
@@ -105,12 +105,6 @@ services:
|
||||
from_secret: gitlab_read_token
|
||||
depends_on:
|
||||
- build
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: mysql8
|
||||
pull: default
|
||||
|
||||
@@ -25,7 +25,7 @@ globals:
|
||||
Tribute: false
|
||||
|
||||
overrides:
|
||||
- files: ["web_src/**/*.worker.js"]
|
||||
- files: ["web_src/**/*.worker.js", "web_src/js/serviceworker.js"]
|
||||
env:
|
||||
worker: true
|
||||
rules:
|
||||
@@ -48,6 +48,7 @@ rules:
|
||||
no-cond-assign: [2, except-parens]
|
||||
no-console: [1, {allow: [info, warn, error]}]
|
||||
no-continue: [0]
|
||||
no-empty: [2, {allowEmptyCatch: true}]
|
||||
no-eq-null: [2]
|
||||
no-mixed-operators: [0]
|
||||
no-multi-assign: [0]
|
||||
@@ -57,6 +58,7 @@ rules:
|
||||
no-restricted-syntax: [0]
|
||||
no-return-await: [0]
|
||||
no-shadow: [0]
|
||||
no-underscore-dangle: [0]
|
||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
|
||||
no-use-before-define: [0]
|
||||
no-var: [2]
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -76,6 +76,7 @@ coverage.all
|
||||
/node_modules
|
||||
/yarn.lock
|
||||
/public/js
|
||||
/public/serviceworker.js
|
||||
/public/css
|
||||
/public/fonts
|
||||
/public/fomantic
|
||||
|
||||
355
CHANGELOG.md
355
CHANGELOG.md
@@ -4,6 +4,361 @@ 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
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.12.0-rc2](https://github.com/go-gitea/gitea/releases/tag/v1.12.0-rc2) - 2020-06-08
|
||||
|
||||
* BUGFIXES
|
||||
* In File Create/Update API return 404 if Branch does not exist (#11791) (#11795)
|
||||
* Fix doer of rename repo (#11789) (#11794)
|
||||
* Initialize SimpleMDE when making a code comment (#11749) (#11785)
|
||||
* Fix timezone on issue deadline (#11697) (#11784)
|
||||
* Fix to allow comment poster to edit or delete his own comments (#11671) (#11774)
|
||||
* Show full 500 error in API when Gitea in dev mode (#11641) (#11753)
|
||||
* Add missing templates for Matrix system webhooks (#11729) (#11748)
|
||||
* Fix verification of subkeys of default gpg key (#11713) (#11747)
|
||||
* Fix styling for commiter on diff view (#11715) (#11744)
|
||||
* Properly truncate system notices (#11714) (#11742)
|
||||
* Handle expected errors in FileCreate & FileUpdate API (#11643) (#11718)
|
||||
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11682)
|
||||
* Update emoji regex (#11584) (#11679)
|
||||
* Doctor check & fix db consistency (#11111) (#11676)
|
||||
* Default MSSQL port 0 to allow automatic detection by default (#11642) (#11673)
|
||||
* Exclude generated files from language statistics (#11653) (#11670)
|
||||
* Use -1 to disable key algorithm type in ssh.minimum_key_sizes (#11635) (#11662)
|
||||
* Return json on 500 error from API (#11574) (#11659)
|
||||
* When must change password only show Signout (#11600) (#11637)
|
||||
* Backport various styling fixes (#11619)
|
||||
* Fix wrong milestone in webhook message (#11596) (#11611)
|
||||
* Fix serviceworker output file and misc improvements (#11562) (#11610)
|
||||
* When initialising repositories ensure that the user doing the creation is the initializer (#11601) (#11608)
|
||||
* Prevent empty query parameter being set on dashboard (#11561) (#11604)
|
||||
* Fix images in wiki edit preview (#11546) (#11602)
|
||||
* Allow different HardBreaks settings for documents and comments (#11515) (#11599)
|
||||
* Prevent (caught) panic on login (#11590) (#11597)
|
||||
* Prevent transferring repos to invisible orgs (#11517) (#11549)
|
||||
* Move serviceworker to workbox and fix SSE interference (#11538) (#11547)
|
||||
* API PullReviewComment HTMLPullURL should return the HTMLURL (#11501) (#11533)
|
||||
* Fix repo-list private and total count bugs (#11500) (#11532)
|
||||
* Fix form action template substitutions on admin pages (backport #11519) (#11531)
|
||||
* Fix a bug where the reaction emoji doesn't disappear. (#11489) (#11530)
|
||||
* TrimSpace when reading InternalToken from a file (#11502) (#11524)
|
||||
* Fix selected line color in arc-green (#11492) (#11520)
|
||||
* Make localstorage read ssh or https correctly (#11483) (#11490)
|
||||
* ENHANCEMENTS
|
||||
* Make tabular menu styling consistent for arc-green (#11570) (#11798)
|
||||
* Add option to API to update PullRequest base branch (#11666) (#11796)
|
||||
* Increase maximum SQLite variables count to 32766 (#11696) (#11783)
|
||||
* Update emoji dataset with skin tone variants (#11678) (#11763)
|
||||
* Add logging to long migrations (#11647) (#11691)
|
||||
* Change language statistics to save size instead of percentage (#11681) (#11690)
|
||||
* Fix alignment for commits on dashboard (#11595) (#11680)
|
||||
* Handle expected errors in AddGPGkey API (#11644) (#11661)
|
||||
* Close EventSource before unloading the page (#11539) (#11557)
|
||||
* Ensure emoji render with regular font-weight (#11541) (#11545)
|
||||
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11542)
|
||||
* Tweak reaction buttons (#11516)
|
||||
* Use more toned colors for selected line (#11493) (#11511)
|
||||
|
||||
## [1.12.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.12.0-rc1) - 2020-05-18
|
||||
|
||||
* BREAKING
|
||||
* When using API CreateRelease set created_unix to the tag commit time (#11218)
|
||||
* Enable ENABLE_HARD_LINE_BREAK by default for rendering markdown (#11162)
|
||||
* Fix sanitizer config - multiple rules (#11133)
|
||||
* Remove check on username when using AccessToken authentication for the API (#11015)
|
||||
* Return 404 from Contents API when items don't exist (#10323)
|
||||
* Notification API should always return a JSON object with the current count of notifications (#10059)
|
||||
* Remove migration support from versions earlier than 1.6.0 (#10026)
|
||||
* FEATURES
|
||||
* Improve config logging when WrappedQueue times out (#11174)
|
||||
* Add branch delete to API (#11112)
|
||||
* Use markdown frontmatter to provide Table of contents, language and frontmatter rendering (#11047)
|
||||
* Add a way to mark Conversation (code comment) resolved (#11037)
|
||||
* Handle yaml frontmatter in markdown (#11016)
|
||||
* Cache PullRequest Divergence (#10914)
|
||||
* Make `gitea admin auth list` formatting configurable (#10844)
|
||||
* Add Matrix webhook (#10831)
|
||||
* Add Organization Wide Labels (#10814)
|
||||
* Allow to set protected file patterns for files that can not be changed under no conditions (#10806)
|
||||
* Option to set default branch at repository creation (#10803)
|
||||
* Add request review from specific reviewers feature in pull request (#10756)
|
||||
* Add NextCloud oauth (#10562)
|
||||
* System-wide webhooks (#10546)
|
||||
* Relax sanitization as per https://github.com/jch/html-pipeline (#10527)
|
||||
* Use media links for img in post-process (#10515)
|
||||
* Add API endpoints to manage OAuth2 Application (list/create/delete) (#10437)
|
||||
* Render READMEs in docs/ .gitea or .github from root (#10361)
|
||||
* Add feishu webhook support (#10229)
|
||||
* Cache last commit to accelerate the repository directory page visit (#10069)
|
||||
* Implement basic app.ini and path checks to doctor cmd (#10064)
|
||||
* Make WorkerPools and Queues flushable (#10001)
|
||||
* Implement "embedded" command to extract static resources (#9982)
|
||||
* Add API endpoint for repo transfer (#9947)
|
||||
* Make archive prefixing configurable with a global setting (#9943)
|
||||
* Add Unique Queue infrastructure and move TestPullRequests to this (#9856)
|
||||
* Issue/PR Context Popups (#9822)
|
||||
* Add "Update Branch" button to Pull Requests (#9784)
|
||||
* Add require signed commit for protected branch (#9708)
|
||||
* Mark PR reviews as stale at push and allow to dismiss stale approvals (#9532)
|
||||
* Add API notification endpoints (#9488)
|
||||
* Issue search support elasticsearch (#9428)
|
||||
* Add API branch protection endpoint (#9311)
|
||||
* Add a new command doctor to check if some wrong configurations on gitea instance (#9095)
|
||||
* Add support for migrating from Gitlab (#9084)
|
||||
* Add support for database schema in PostgreSQL (#8819)
|
||||
* Add setting to set default and global disabled repository units. (#8788)
|
||||
* Language statistics bar for repositories (#8037)
|
||||
* Restricted users (#6274)
|
||||
* BUGFIXES
|
||||
* Check branch protection on IsUserAllowedToUpdate (#11448)
|
||||
* Fix margin on attached segment headers when they are separated by other element (#11425)
|
||||
* Fix webhook template when validation errors occur (#11421)
|
||||
* Fix NPE in template due to missing signing key on commit page (#11392)
|
||||
* Restore active background to Register button on Register page (#11390)
|
||||
* Fix hook failure due to relative LFS_CONTENT_PATH (#11362)
|
||||
* Correctly set the organization num repos (#11339)
|
||||
* Prevent 500 with badly formed task list (#11328)
|
||||
* Allow compare page to look up base, head, own-fork, forkbase-of-head (#11327)
|
||||
* Handle panics that percolate up to the graceful module (#11291)
|
||||
* Don't allow registration via the web form, when AllowOnlyExternalRegistration is True (#11248)
|
||||
* Patch fomantic-ui to workaround build issue (#11244)
|
||||
* Prevent panic during wrappedConn close at hammertime (#11219)
|
||||
* On logout force redirect to start page (#11202)
|
||||
* Fix creation of Organization repos by Users with max created personal repos (#11183)
|
||||
* Add option to increase provided OAuth2 token maximum size (#11180)
|
||||
* Log the indexer path on failure (#11172)
|
||||
* Ensure that relative paths in edit preview work (#11143)
|
||||
* Make API EditIssue and EditPullRequest issue notifications (#11123)
|
||||
* Send 404 immediately for known public requests (#11117)
|
||||
* Remove nil inserts in models (#11096)
|
||||
* Add GetReviews() to RetryDownloader (#11093)
|
||||
* Remove nonexistent serviceworker entries (#11091)
|
||||
* Simplify and fix GetApprovalCounts (#11086)
|
||||
* Fix wiki revision template and simplify some tmpl conditions (#11080)
|
||||
* Make branch parameter optional for /api/v1/repos/{owner}/{repo}/contents/{filepath} (#11067)
|
||||
* Align review-item svg octicons (#11065)
|
||||
* Automatically remove Watches, Assignments, etc if user loses access due to being removed as collaborator or from a team (#10997)
|
||||
* Users should not be able to prohibit their own login (#10970)
|
||||
* Fix scrollbar issues in dropdowns (#10897)
|
||||
* Change the order of issues.closed_by to list opening user first (#10876)
|
||||
* Allow site admin to check /api/v1/orgs endpoints (#10867)
|
||||
* Avoid logging []byte in queue failures - convert to string first (#10865)
|
||||
* Use ErrKeyUnableToVerify if fail to calc fingerprint in ssh-keygen (#10863)
|
||||
* Fix assignees double load bug (#10856)
|
||||
* Handle push rejection in branch and upload (#10854)
|
||||
* In authorized_keys use double-quote for windows compatibility (#10841)
|
||||
* Fix milestone template (#10824)
|
||||
* log.Fatal on failure to listen to SSH port (#10795)
|
||||
* Fix forked repo has no icon and language stat. (#10791)
|
||||
* Fix tag/release deletion (#10663)
|
||||
* Fix webhook migration (#10641)
|
||||
* Migration for deleting orphaned dependencies (#10617)
|
||||
* Add migration to fix the old broken merge-bases (#10604)
|
||||
* Update templates for Go 1.14 (#10596)
|
||||
* Remove unnecessary parentheses in wiki/view template (#10583)
|
||||
* Change default value of DefaultCommandExecutionTimeout to match docs (#10581)
|
||||
* Handle panic in indexer initialisation better (#10534)
|
||||
* Set correct content_type value for Gogs/Gitea webhooks (#9504) (#10456)
|
||||
* Fixed wrong AppSubUrl in multiple templates (#10447)
|
||||
* Fix profile page CSS (#10406)
|
||||
* Inject SVG sprite via ajax (#10320)
|
||||
* Fix migration information update bug when linked github account (#10310)
|
||||
* Allow admin to check org membership by API for other users (#10201)
|
||||
* Fix topics dropdown (#10167)
|
||||
* Ensure DeleteUser is not allowed to Delete Orgs and visa versa (#10134)
|
||||
* Fix IsErrPullClosed (#10093)
|
||||
* Accept punctuation after simple+cross repository issue references (#10091)
|
||||
* On merge of already closed PR redirect back to the pulls page (#10010)
|
||||
* Fix crowdin update script (#9969)
|
||||
* Fix pull view when head repository or head branch missed and close related pull requests when delete head repository or head branch (#9927)
|
||||
* Add option to prevent LDAP from deactivating everything on empty search (#9879)
|
||||
* Fix admin handling at merge of PR (#9749)
|
||||
* err_admin_name_pattern_not_allowed String Clarification (#9731)
|
||||
* Fix wrong original git service type on a migrated repository (#9693)
|
||||
* Fix ref links in issue overviews for tags (#8742)
|
||||
* ENHANCEMENTS
|
||||
* Increase width for authors on commit view (#11441)
|
||||
* Hide archived repos by default in repo-list (#11440)
|
||||
* Better styling for code review comment textarea (#11428)
|
||||
* Support view individual commit for wiki pages (#11415)
|
||||
* Fix yellow background on active elements in code review (#11414)
|
||||
* Better styling for code review comment form (#11413)
|
||||
* Change install description on homepage (#11395)
|
||||
* Ensure search action button is coalesced to adjacent input (#11385)
|
||||
* Switch code editor to Monaco (#11366)
|
||||
* Add paging and archive/private repository filtering to dashboard list (#11321)
|
||||
* Changed image of openid-connect logo for better look on arc-green theme (#11312)
|
||||
* Load Repo Topics on blame view too (#11307)
|
||||
* Change the style in admin notice content view from `<p>` to `<pre>` (#11301)
|
||||
* Allow log.xxx.default to set logging settings for the default logger only (#11292)
|
||||
* Automatically attempt auto recovery of broken disk queues (Update lunny/levelqueue to 0.3.0) (#11285)
|
||||
* Make sendmail a Process and have default timeout (#11256)
|
||||
* Check value of skip-repository flag in dump command (#11254)
|
||||
* Fix submit review form (#11252)
|
||||
* Allow unauthenticated users to compare (#11240)
|
||||
* Add EventSource support (#11235)
|
||||
* Refactor Milestone related (#11225)
|
||||
* Add pull review API endpoints (#11224)
|
||||
* Add a 'this' to issue close/reopened messages (#11204)
|
||||
* When migrating from Gitlab map Approvals to approving Reviews (#11147)
|
||||
* Improve representation of attachments in issues (#11141)
|
||||
* Protect default branch against deletion (#11115)
|
||||
* Add X-Total-Count on /repos/{owner]/{repo}/pulls API endpoint (#11113)
|
||||
* Fix status label on branches list vertical alignment (#11109)
|
||||
* Add single release page and latest redirect (#11102)
|
||||
* Add missing commit states to PR checks template (#11085)
|
||||
* Change icon on title for merged PR to git-merge (#11064)
|
||||
* Add MergePull comment type instead of close for merge PR (#11058)
|
||||
* Upgrade jQuery to 3.5.0, remove jQuery-Migrate, fix deprecations (#11055)
|
||||
* Consolidate author name across timeline (#11053)
|
||||
* Refactor UpdateOAuth2Application (#11034)
|
||||
* Support unicode emojis and remove emojify.js (#11032)
|
||||
* Add git hook "warning" to admin panel (#11030)
|
||||
* Add flash notify for email preference setting success (#11027)
|
||||
* Remove package code.gitea.io/gitea/modules/git import out of models (#11025)
|
||||
* Match arc-green code tag color to code blocks (#11023)
|
||||
* Move syntax highlighting to web worker (#11017)
|
||||
* Prevent merge of outdated PRs on protected branches (#11012)
|
||||
* Add Get/Update for api/v1/user/applications/oauth2 (#11008)
|
||||
* Upgrade to most recent bluemonday (#11007)
|
||||
* Tweak code tags in markdown (#11000)
|
||||
* Reject duplicate AccessToken names (#10994)
|
||||
* Fix Ctrl-Enter shortcut for issues (#10986)
|
||||
* Provide `OwnerName` field for README template (#10981)
|
||||
* Prettify Timeline (#10972)
|
||||
* Add issue subscription check to API (#10967)
|
||||
* Use AJAX for notifications table (#10961)
|
||||
* Adjust label padding (#10957)
|
||||
* Avoiding directory execution on hook (#10954) (#10955)
|
||||
* Migrate ActivityHeatmap to Vue SFC (#10953)
|
||||
* Change merge strategy: do not check write access if user in merge white list (#10951)
|
||||
* Enable GO111MODULE=on globally in Makefile (#10939)
|
||||
* API endpoint to get single commit via SHA and Ref (#10915)
|
||||
* Add accordion to release list and hide non-latest (#10910)
|
||||
* Split dashboard elements into separate template files (#10885)
|
||||
* Add more message on sidebar menus (#10872)
|
||||
* Set MySQL rowtype to dynamic for new tables (#10833)
|
||||
* Completely fix task-list checkbox styling (#10798)
|
||||
* Hide gear icon for user who can't use them on sidebar (#10750)
|
||||
* Refactor Cron and merge dashboard tasks (#10745)
|
||||
* Change review status icons on pr view style to github style (#10737)
|
||||
* Make pagination optional for API list notification endpoints (#10714)
|
||||
* Fix tab indentation in code view (#10671)
|
||||
* Fix task-list checkbox styling (#10668)
|
||||
* Multiple LFS improvements (#10667)
|
||||
* Make PR message on pushes configurable (#10664)
|
||||
* Move dropzone.js to npm/webpack (#10645)
|
||||
* Ensure Update button is enabled even when CI has failed (#10640)
|
||||
* Add restricted user filter to LDAP authentication (#10600)
|
||||
* Add Yandex OAuth2 provider (#8335) (#10564)
|
||||
* Make avatar lookup occur at image request (#10540)
|
||||
* Prevent accidential selection of language stats bar (#10537)
|
||||
* Add fluid-icon (#10491)
|
||||
* Inform participants on UI too (#10473)
|
||||
* Build with go 1.14 (and raise minimum go version to 1.12) (#10467)
|
||||
* Add max-file-size to LFS (#10463)
|
||||
* Enable paggination for ListRepoTags API (#10454)
|
||||
* Update JS dependencies (#10450)
|
||||
* Show the username as a fallback on feeds if full name is blank (#10438)
|
||||
* Various dark theme fixes (#10416)
|
||||
* Display pull request head branch even the branch deleted or repository deleted (#10413)
|
||||
* Prevent Firefox from using apple-touch-icon (#10402)
|
||||
* Fix input[type=file] on dark theme (#10382)
|
||||
* Improve mobile review-box sizing (#10297)
|
||||
* Notification: queue ui.go notification-service (#10281)
|
||||
* Add detected file language to code search (#10256)
|
||||
* Index code and stats only for non-empty repositories (#10251)
|
||||
* Add Approval Counts to pulls list (#10238)
|
||||
* Limit label list height on edit issue page (#10216)
|
||||
* Improve 404 error message (#10214)
|
||||
* Tweak locale to respect singular conflicting file message in PR list (#10177)
|
||||
* Fix commit view (#10169)
|
||||
* Reorganize frontend files and tooling (#10168)
|
||||
* Allow emoji on popup label (#10166)
|
||||
* ListIssues add filter for milestones API (#10148)
|
||||
* Show if a PR has conflicting files on the PR lists (#10130)
|
||||
* Fix inconsistent label color format in API (#10129)
|
||||
* Show download count info in release list (#10124)
|
||||
* Add Octicon SVG spritemap (#10107)
|
||||
* Update aria-fixed semantic-dropdown to fomantic master (#10096)
|
||||
* Fix apple-touch-icon, regenerate images (#10065)(#10006)
|
||||
* Style blockquote for default issue mail template (#10024)
|
||||
* More expansions in template repositories (#10021)
|
||||
* Allow list collaborators for users with Read access to repo (#9995)
|
||||
* Add explicit dimensions to navbar avatar (#9986)
|
||||
* Remove loadCSS and preload woff2 icon fonts (#9976)
|
||||
* Fix commit view JS features, reimplement folding (#9968)
|
||||
* Fix review avatar image (#9962)
|
||||
* Improve notification pager (#9821)
|
||||
* Move jquery and jquery-migrate to npm/webpack (#9813)
|
||||
* Change font to Roboto to support more charsets (#9803)
|
||||
* Move mailer to use a queue (#9789)
|
||||
* Issue search on my related repositories (#9758)
|
||||
* Add "before" query to ListIssueComments and ListRepoIssueComments API (#9685)
|
||||
* Move tracked time api convert to convert package (#9665)
|
||||
* Improve PR info in default merge message (#9635)
|
||||
* Granular webhook events (#9626)
|
||||
* Add Reviewed-on in commit message (#9623)
|
||||
* Add top author stats to activity page (#9615)
|
||||
* Allow repo admin to merge PR regardless of review status (#9611)
|
||||
* Migrate reactions when migrating repository from github (#9599)
|
||||
* API orgEditTeam make Fields optional (#9556)
|
||||
* Move create/fork repository from models to modules/repository (#9489)
|
||||
* Migrate reviews when migrating repository from github (#9463)
|
||||
* Times API add filters (#9373)
|
||||
* Move push commits from models to modules/repository (#9370)
|
||||
* Add API endpoint to check notifications [Extend #9488] (#9595)
|
||||
* Add GET /orgs API endpoint (#9560)
|
||||
* API add/generalize pagination (#9452)
|
||||
* Make create org repo API call same as github (#9186)
|
||||
* BUILD
|
||||
* Turn off go modules for xgo and gxz (#10963)
|
||||
* Add gitea-vet (#10948)
|
||||
* Rename scripts to build and add revive command as a new build tool command (#10942)
|
||||
* Add 'make lint', restructure 'compliance' pipeline (#10861)
|
||||
* Move JS build dependencies to 'dependencies' (#10763)
|
||||
* Use whitelist to find go files, run find only once (#10594)
|
||||
* Move vue and vue-calendar-heatmap to npm/webpack (#10188)
|
||||
* Move jquery.are-you-sure to npm/webpack (#10063)
|
||||
* Move highlight.js to npm/webpack (#10011)
|
||||
* Generate Bindata if TAGS="bindata" and not up-to-date (#10004)
|
||||
* Move CSS build to webpack (#9983)
|
||||
* Move fomantic target, update 'make help' (#9945)
|
||||
* Add css extraction and minification to webpack (#9944)
|
||||
* Misc webpack tweaks (#9924)
|
||||
* Make node_modules a order-only prerequisite (#9923)
|
||||
* Update documentation for the go module era (#9751)
|
||||
* Move swagger-ui to webpack/npm and update it to 3.24.3 (#9714)
|
||||
* Use npm to manage fomantic and only build needed components (#9561)
|
||||
* MISC
|
||||
* Add gnupg to Dockerfile (#11365)
|
||||
* Update snapcraft.yaml for core18 and latest features (#11300)
|
||||
* Update JS dependencies, min Node.js version 10.13 (#11246)
|
||||
* Change default charset for MySQL on install to utf8mb4 (#10989)
|
||||
* Return issue subscription status from API subscribe (#10966)
|
||||
* Fix queue log param (#10733)
|
||||
* Add warning when using relative path to app.ini (#10104)
|
||||
|
||||
## [1.11.6](https://github.com/go-gitea/gitea/releases/tag/v1.11.6) - 2020-05-30
|
||||
|
||||
* SECURITY
|
||||
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11683)
|
||||
* Use session for retrieving org teams (#11438) (#11439)
|
||||
* BUGFIXES
|
||||
* Return json on 500 error from API (#11574) (#11660)
|
||||
* Fix wrong milestone in webhook message (#11596) (#11612)
|
||||
* Prevent (caught) panic on login (#11590) (#11598)
|
||||
* Fix commit page js error (#11527)
|
||||
* Use media links for img in post-process (#10515) (#11504)
|
||||
* Ensure public repositories in private organizations are visible and fix admin organizations list (#11465) (#11475)
|
||||
* Set correct Content-Type value for Gogs/Gitea webhooks (#9504) (#10456) (#11461)
|
||||
* Allow all members of private orgs to see public repos (#11442) (#11459)
|
||||
* Whenever the ctx.Session is updated, release it to save it before sending the redirect (#11456) (#11457)
|
||||
* Forcibly clean and destroy the session on logout (#11447) (#11451)
|
||||
* Fix /api/v1/orgs/* endpoints by changing parameter to :org from :orgname (#11381)
|
||||
* Add tracked time fix to doctor (part of #11111) (#11138)
|
||||
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11544)
|
||||
* Remove unnecessary parentheses in wiki/revision.tmpl to allow 1.11 to build on go1.14 (#11481)
|
||||
|
||||
## [1.11.5](https://github.com/go-gitea/gitea/releases/tag/v1.11.5) - 2020-05-09
|
||||
|
||||
* BUGFIXES
|
||||
|
||||
@@ -9,6 +9,7 @@ ENV GOPROXY ${GOPROXY:-direct}
|
||||
ARG GITEA_VERSION
|
||||
ARG TAGS="sqlite sqlite_unlock_notify"
|
||||
ENV TAGS "bindata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
#Build deps
|
||||
RUN apk --no-cache add build-base git nodejs npm
|
||||
|
||||
20
Makefile
20
Makefile
@@ -33,6 +33,9 @@ MIN_NODE_VERSION := 010013000
|
||||
ifeq ($(HAS_GO), GO)
|
||||
GOPATH ?= $(shell $(GO) env GOPATH)
|
||||
export PATH := $(GOPATH)/bin:$(PATH)
|
||||
|
||||
CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766
|
||||
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
|
||||
endif
|
||||
|
||||
|
||||
@@ -88,7 +91,7 @@ GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(fi
|
||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
|
||||
WEBPACK_CONFIGS := webpack.config.js
|
||||
WEBPACK_DEST := public/js/index.js public/css/index.css
|
||||
WEBPACK_DEST_DIRS := public/js public/css public/fonts
|
||||
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/serviceworker.js
|
||||
|
||||
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
|
||||
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
|
||||
@@ -194,7 +197,7 @@ node-check:
|
||||
|
||||
.PHONY: clean-all
|
||||
clean-all: clean
|
||||
rm -rf $(WEBPACK_DEST_DIRS) $(FOMANTIC_DEST_DIR)
|
||||
rm -rf $(WEBPACK_DEST_ENTRIES) $(FOMANTIC_DEST_DIR)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@@ -295,6 +298,7 @@ lint-frontend: node_modules
|
||||
|
||||
.PHONY: watch-frontend
|
||||
watch-frontend: node_modules
|
||||
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||
NODE_ENV=development npx webpack --hide-modules --display-entrypoints=false --watch --progress
|
||||
|
||||
.PHONY: test
|
||||
@@ -498,7 +502,7 @@ check: test
|
||||
|
||||
.PHONY: install $(TAGS_PREREQ)
|
||||
install: $(wildcard *.go)
|
||||
$(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
|
||||
|
||||
.PHONY: build
|
||||
build: frontend backend
|
||||
@@ -514,7 +518,7 @@ generate: $(TAGS_PREREQ)
|
||||
CC= GOOS= GOARCH= $(GO) generate -mod=vendor -tags '$(TAGS)' $(GO_PACKAGES)
|
||||
|
||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
$(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
|
||||
.PHONY: release
|
||||
release: frontend generate release-windows release-linux release-darwin release-copy release-compress release-sources release-check
|
||||
@@ -527,7 +531,7 @@ release-windows: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
||||
fi
|
||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
@@ -537,7 +541,7 @@ release-linux: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
||||
fi
|
||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
@@ -547,7 +551,7 @@ release-darwin: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
||||
fi
|
||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
@@ -598,7 +602,7 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules
|
||||
webpack: $(WEBPACK_DEST)
|
||||
|
||||
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
|
||||
rm -rf $(WEBPACK_DEST_DIRS)
|
||||
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||
npx webpack --hide-modules --display-entrypoints=false
|
||||
@touch $(WEBPACK_DEST)
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
65
build/generate-emoji.go
vendored
65
build/generate-emoji.go
vendored
@@ -19,6 +19,7 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -39,6 +40,7 @@ type Emoji struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Aliases []string `json:"aliases"`
|
||||
UnicodeVersion string `json:"unicode_version,omitempty"`
|
||||
SkinTones bool `json:"skin_tones,omitempty"`
|
||||
}
|
||||
|
||||
// Don't include some fields in JSON
|
||||
@@ -47,6 +49,7 @@ func (e Emoji) MarshalJSON() ([]byte, error) {
|
||||
x := emoji(e)
|
||||
x.UnicodeVersion = ""
|
||||
x.Description = ""
|
||||
x.SkinTones = false
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
@@ -75,6 +78,7 @@ var replacer = strings.NewReplacer(
|
||||
", Description:", ", ",
|
||||
", Aliases:", ", ",
|
||||
", UnicodeVersion:", ", ",
|
||||
", SkinTones:", ", ",
|
||||
)
|
||||
|
||||
var emojiRE = regexp.MustCompile(`\{Emoji:"([^"]*)"`)
|
||||
@@ -102,18 +106,20 @@ func generate() ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var re = regexp.MustCompile(`keycap|registered|copyright`)
|
||||
tmp := data[:0]
|
||||
var skinTones = make(map[string]string)
|
||||
|
||||
// filter out emoji that require greater than max unicode version
|
||||
skinTones["\U0001f3fb"] = "Light Skin Tone"
|
||||
skinTones["\U0001f3fc"] = "Medium-Light Skin Tone"
|
||||
skinTones["\U0001f3fd"] = "Medium Skin Tone"
|
||||
skinTones["\U0001f3fe"] = "Medium-Dark Skin Tone"
|
||||
skinTones["\U0001f3ff"] = "Dark Skin Tone"
|
||||
|
||||
var tmp Gemoji
|
||||
|
||||
//filter out emoji that require greater than max unicode version
|
||||
for i := range data {
|
||||
val, _ := strconv.ParseFloat(data[i].UnicodeVersion, 64)
|
||||
if int(val) <= maxUnicodeVersion {
|
||||
// remove these keycaps for now they really complicate matching since
|
||||
// they include normal letters in them
|
||||
if re.MatchString(data[i].Description) {
|
||||
continue
|
||||
}
|
||||
tmp = append(tmp, data[i])
|
||||
}
|
||||
}
|
||||
@@ -123,7 +129,6 @@ func generate() ([]byte, error) {
|
||||
return data[i].Aliases[0] < data[j].Aliases[0]
|
||||
})
|
||||
|
||||
aliasPairs := make([]string, 0)
|
||||
aliasMap := make(map[string]int, len(data))
|
||||
|
||||
for i, e := range data {
|
||||
@@ -135,7 +140,6 @@ func generate() ([]byte, error) {
|
||||
continue
|
||||
}
|
||||
aliasMap[a] = i
|
||||
aliasPairs = append(aliasPairs, ":"+a+":", e.Emoji)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +153,43 @@ func generate() ([]byte, error) {
|
||||
data[i].Aliases = append(data[i].Aliases, "laugh")
|
||||
}
|
||||
|
||||
// write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet)
|
||||
file, _ := json.Marshal(data)
|
||||
_ = ioutil.WriteFile("assets/emoji.json", file, 0644)
|
||||
|
||||
// Add skin tones to emoji that support it
|
||||
var (
|
||||
s []string
|
||||
newEmoji string
|
||||
newDescription string
|
||||
newData Emoji
|
||||
)
|
||||
|
||||
for i := range data {
|
||||
if data[i].SkinTones {
|
||||
for k, v := range skinTones {
|
||||
s = strings.Split(data[i].Emoji, "")
|
||||
|
||||
if utf8.RuneCountInString(data[i].Emoji) == 1 {
|
||||
s = append(s, k)
|
||||
} else {
|
||||
// insert into slice after first element because all emoji that support skin tones
|
||||
// have that modifer placed at this spot
|
||||
s = append(s, "")
|
||||
copy(s[2:], s[1:])
|
||||
s[1] = k
|
||||
}
|
||||
|
||||
newEmoji = strings.Join(s, "")
|
||||
newDescription = data[i].Description + ": " + v
|
||||
newAlias := data[i].Aliases[0] + "_" + strings.ReplaceAll(v, " ", "_")
|
||||
|
||||
newData = Emoji{newEmoji, newDescription, []string{newAlias}, "12.0", false}
|
||||
data = append(data, newData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add header
|
||||
str := replacer.Replace(fmt.Sprintf(hdr, gemojiURL, data))
|
||||
|
||||
@@ -162,10 +203,6 @@ func generate() ([]byte, error) {
|
||||
return "{" + strconv.QuoteToASCII(s)
|
||||
})
|
||||
|
||||
// write a JSON file to use with tribute
|
||||
file, _ := json.Marshal(data)
|
||||
_ = ioutil.WriteFile("assets/emoji.json", file, 0644)
|
||||
|
||||
// format
|
||||
return format.Source([]byte(str))
|
||||
}
|
||||
|
||||
@@ -85,10 +85,16 @@ var checklist = []check{
|
||||
},
|
||||
{
|
||||
title: "Check Database Version",
|
||||
name: "check-db",
|
||||
name: "check-db-version",
|
||||
isDefault: true,
|
||||
f: runDoctorCheckDBVersion,
|
||||
abortIfFailed: true,
|
||||
abortIfFailed: false,
|
||||
},
|
||||
{
|
||||
title: "Check consistency of database",
|
||||
name: "check-db-consistency",
|
||||
isDefault: false,
|
||||
f: runDoctorCheckDBConsistency,
|
||||
},
|
||||
{
|
||||
title: "Check if OpenSSH authorized_keys file is up-to-date",
|
||||
@@ -495,3 +501,80 @@ func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
||||
}
|
||||
return []string{fmt.Sprintf("ScriptType %s is on the current PATH at %s", setting.ScriptType, path)}, nil
|
||||
}
|
||||
|
||||
func runDoctorCheckDBConsistency(ctx *cli.Context) ([]string, error) {
|
||||
var results []string
|
||||
|
||||
// make sure DB version is uptodate
|
||||
if err := models.NewEngine(context.Background(), migrations.EnsureUpToDate); err != nil {
|
||||
return nil, fmt.Errorf("model version on the database does not match the current Gitea version. Model consistency will not be checked until the database is upgraded")
|
||||
}
|
||||
|
||||
//find labels without existing repo or org
|
||||
count, err := models.CountOrphanedLabels()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
if ctx.Bool("fix") {
|
||||
if err = models.DeleteOrphanedLabels(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, fmt.Sprintf("%d labels without existing repository/organisation deleted", count))
|
||||
} else {
|
||||
results = append(results, fmt.Sprintf("%d labels without existing repository/organisation", count))
|
||||
}
|
||||
}
|
||||
|
||||
//find issues without existing repository
|
||||
count, err = models.CountOrphanedIssues()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
if ctx.Bool("fix") {
|
||||
if err = models.DeleteOrphanedIssues(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, fmt.Sprintf("%d issues without existing repository deleted", count))
|
||||
} else {
|
||||
results = append(results, fmt.Sprintf("%d issues without existing repository", count))
|
||||
}
|
||||
}
|
||||
|
||||
//find pulls without existing issues
|
||||
count, err = models.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
if ctx.Bool("fix") {
|
||||
if err = models.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, fmt.Sprintf("%d pull requests without existing issue deleted", count))
|
||||
} else {
|
||||
results = append(results, fmt.Sprintf("%d pull requests without existing issue", count))
|
||||
}
|
||||
}
|
||||
|
||||
//find tracked times without existing issues/pulls
|
||||
count, err = models.CountOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
if ctx.Bool("fix") {
|
||||
if err = models.DeleteOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, fmt.Sprintf("%d tracked times without existing issue deleted", count))
|
||||
} else {
|
||||
results = append(results, fmt.Sprintf("%d tracked times without existing issue", count))
|
||||
}
|
||||
}
|
||||
|
||||
//ToDo: function to recalc all counters
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/modules/generate"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@@ -59,7 +61,12 @@ func runGenerateInternalToken(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", internalToken)
|
||||
fmt.Printf("%s", internalToken)
|
||||
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,7 +76,12 @@ func runGenerateLfsJwtSecret(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", JWTSecretBase64)
|
||||
fmt.Printf("%s", JWTSecretBase64)
|
||||
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -79,6 +91,11 @@ func runGenerateSecretKey(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", secretKey)
|
||||
fmt.Printf("%s", secretKey)
|
||||
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -216,7 +216,10 @@ EVENT_SOURCE_UPDATE_TIME = 10s
|
||||
; Render soft line breaks as hard line breaks, which means a single newline character between
|
||||
; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not
|
||||
; necessary to force a line break.
|
||||
ENABLE_HARD_LINE_BREAK = true
|
||||
; Render soft line breaks as hard line breaks for comments
|
||||
ENABLE_HARD_LINE_BREAK_IN_COMMENTS = true
|
||||
; Render soft line breaks as hard line breaks for markdown documents
|
||||
ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS = false
|
||||
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
|
||||
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
|
||||
; URLs starting with http and https are always displayed, whatever is put in this entry.
|
||||
@@ -934,8 +937,8 @@ JWT_SECRET=Bk0yK7Y9g_p56v86KaHqjSbxvNvu3SbKoOdOt2ZcXvU
|
||||
MAX_TOKEN_LENGTH=32767
|
||||
|
||||
[i18n]
|
||||
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
|
||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
|
||||
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
|
||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
|
||||
|
||||
; Used for datetimepicker
|
||||
[i18n.datelang]
|
||||
@@ -952,6 +955,7 @@ uk-UA = uk
|
||||
ja-JP = ja
|
||||
es-ES = es
|
||||
pt-BR = pt-BR
|
||||
pt-PT = pt
|
||||
pl-PL = pl
|
||||
bg-BG = bg
|
||||
it-IT = it
|
||||
|
||||
2
docker/Makefile
vendored
2
docker/Makefile
vendored
@@ -11,4 +11,4 @@ docker:
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build:
|
||||
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" webhippie/golang:edge make clean build
|
||||
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" CGO_EXTRA_CFLAGS="$(CGO_EXTRA_CFLAGS)" webhippie/golang:edge make clean build
|
||||
|
||||
@@ -312,3 +312,50 @@ languages:
|
||||
url: https://discourse.gitea.io/
|
||||
weight: 80
|
||||
pre: group
|
||||
|
||||
pt-pt:
|
||||
weight: 6
|
||||
languageName: Português de Portugal
|
||||
menu:
|
||||
page:
|
||||
- name: Página inicial
|
||||
url: https://gitea.io/pt-pt/
|
||||
weight: 10
|
||||
pre: home
|
||||
- name: Documentação
|
||||
url: /pt-pt/
|
||||
weight: 20
|
||||
pre: question
|
||||
post: active
|
||||
- name: API
|
||||
url: https://try.gitea.io/api/swagger
|
||||
weight: 45
|
||||
pre: plug
|
||||
- name: Blog
|
||||
url: https://blog.gitea.io/
|
||||
weight: 30
|
||||
pre: rss
|
||||
- name: Código-fonte
|
||||
url: https://code.gitea.io/
|
||||
weight: 40
|
||||
pre: code
|
||||
- name: Tradução
|
||||
url: https://crowdin.com/project/gitea
|
||||
weight: 41
|
||||
pre: language
|
||||
- name: Descarregamentos
|
||||
url: https://dl.gitea.io/
|
||||
weight: 50
|
||||
pre: download
|
||||
- name: GitHub
|
||||
url: https://github.com/go-gitea/
|
||||
weight: 60
|
||||
pre: github
|
||||
- name: Discussão no Discord
|
||||
url: https://discord.gg/Gitea
|
||||
weight: 70
|
||||
pre: comment
|
||||
- name: Fórum
|
||||
url: https://discourse.gitea.io/
|
||||
weight: 80
|
||||
pre: group
|
||||
|
||||
@@ -152,7 +152,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
|
||||
## Markdown (`markdown`)
|
||||
|
||||
- `ENABLE_HARD_LINE_BREAK`: **true**: Render soft line breaks as hard line breaks, which
|
||||
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
|
||||
means a single newline character between paragraphs will cause a line break and adding
|
||||
trailing whitespace to paragraphs is not necessary to force a line break.
|
||||
- `ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS`: **false**: Render soft line breaks as hard line breaks in documents, which
|
||||
means a single newline character between paragraphs will cause a line break and adding
|
||||
trailing whitespace to paragraphs is not necessary to force a line break.
|
||||
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
|
||||
@@ -602,8 +605,8 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false`
|
||||
|
||||
## i18n (`i18n`)
|
||||
|
||||
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
|
||||
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
|
||||
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
|
||||
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
|
||||
|
||||
### i18n - Datepicker Language (`i18n.datelang`)
|
||||
Maps locales to the languages used by the datepicker plugin
|
||||
@@ -620,6 +623,7 @@ Maps locales to the languages used by the datepicker plugin
|
||||
- `ja-JP`: **ja**
|
||||
- `es-ES`: **es**
|
||||
- `pt-BR`: **pt-BR**
|
||||
- `pt-PT`: **pt**
|
||||
- `pl-PL`: **pl**
|
||||
- `bg-BG`: **bg**
|
||||
- `it-IT`: **it**
|
||||
|
||||
2
go.mod
2
go.mod
@@ -37,7 +37,7 @@ require (
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||
github.com/gliderlabs/ssh v0.2.2
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
|
||||
github.com/go-enry/go-enry/v2 v2.3.0
|
||||
github.com/go-enry/go-enry/v2 v2.5.2
|
||||
github.com/go-git/go-billy/v5 v5.0.0
|
||||
github.com/go-git/go-git/v5 v5.0.0
|
||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@@ -193,10 +193,10 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a h1:FQqo
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-enry/go-enry/v2 v2.3.0 h1:o8KwgY6uSplysrIpj+Y42J/xGPp90ogVpxE2Z3s8Unk=
|
||||
github.com/go-enry/go-enry/v2 v2.3.0/go.mod h1:+xFJwbqWi15bvqFHb2ELUWVRKFQtwB61+sDrkvvxxGI=
|
||||
github.com/go-enry/go-oniguruma v1.2.0 h1:oBO9XC1IDT9+AoWW5oFsa/7gFeOPacEqDbyXZKWXuDs=
|
||||
github.com/go-enry/go-oniguruma v1.2.0/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-enry/go-enry/v2 v2.5.2 h1:3f3PFAO6JitWkPi1GQ5/m6Xu4gNL1U5soJ8QaYqJ0YQ=
|
||||
github.com/go-enry/go-enry/v2 v2.5.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||
@@ -616,8 +616,6 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
|
||||
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/toqueteos/trie v1.0.0 h1:8i6pXxNUXNRAqP246iibb7w/pSFquNTQ+uNfriG7vlk=
|
||||
github.com/toqueteos/trie v1.0.0/go.mod h1:Ywk48QhEqhU1+DwhMkJ2x7eeGxDHiGkAdc9+0DYcbsM=
|
||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||
@@ -876,8 +874,6 @@ gopkg.in/testfixtures.v2 v2.5.0 h1:N08B7l2GzFQenyYbzqthDnKAA+cmb17iAZhhFxr7JHw=
|
||||
gopkg.in/testfixtures.v2 v2.5.0/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/toqueteos/substring.v1 v1.0.2 h1:urLqCeMm6x/eTuQa1oZerNw8N1KNOIp5hD5kGL7lFsE=
|
||||
gopkg.in/toqueteos/substring.v1 v1.0.2/go.mod h1:Eb2Z1UYehlVK8LYW2WBVR2rwbujsz3aX8XDrM1vbNew=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestGPGKeys(t *testing.T) {
|
||||
results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
|
||||
},
|
||||
{name: "LoggedAsUser2", makeRequest: session.MakeRequest, token: token,
|
||||
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusInternalServerError, http.StatusInternalServerError, http.StatusCreated, http.StatusCreated}},
|
||||
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusUnprocessableEntity, http.StatusNotFound, http.StatusCreated, http.StatusCreated}},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestAPIMergePullWIP(t *testing.T) {
|
||||
session.MakeRequest(t, req, http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
func TestAPICreatePullSuccess1(t *testing.T) {
|
||||
func TestAPICreatePullSuccess(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
||||
// repo10 have code, pulls units.
|
||||
@@ -78,7 +78,7 @@ func TestAPICreatePullSuccess1(t *testing.T) {
|
||||
session.MakeRequest(t, req, 201)
|
||||
}
|
||||
|
||||
func TestAPICreatePullSuccess2(t *testing.T) {
|
||||
func TestAPIEditPull(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
||||
owner10 := models.AssertExistsAndLoadBean(t, &models.User{ID: repo10.OwnerID}).(*models.User)
|
||||
@@ -90,6 +90,21 @@ func TestAPICreatePullSuccess2(t *testing.T) {
|
||||
Base: "master",
|
||||
Title: "create a success pr",
|
||||
})
|
||||
pull := new(api.PullRequest)
|
||||
resp := session.MakeRequest(t, req, 201)
|
||||
DecodeJSON(t, resp, pull)
|
||||
assert.EqualValues(t, "master", pull.Base.Name)
|
||||
|
||||
session.MakeRequest(t, req, 201)
|
||||
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{
|
||||
Base: "feature/1",
|
||||
Title: "edit a this pr",
|
||||
})
|
||||
resp = session.MakeRequest(t, req, 201)
|
||||
DecodeJSON(t, resp, pull)
|
||||
assert.EqualValues(t, "feature/1", pull.Base.Name)
|
||||
|
||||
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{
|
||||
Base: "not-exist",
|
||||
})
|
||||
session.MakeRequest(t, req, 404)
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ func TestAPICreateFile(t *testing.T) {
|
||||
treePath = "README.md"
|
||||
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
||||
req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
|
||||
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
|
||||
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
expectedAPIError := context.APIError{
|
||||
Message: "repository file already exists [path: " + treePath + "]",
|
||||
URL: setting.API.SwaggerURL,
|
||||
|
||||
@@ -208,7 +208,7 @@ func TestAPIUpdateFile(t *testing.T) {
|
||||
updateFileOptions.SHA = "badsha"
|
||||
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
||||
req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
|
||||
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
|
||||
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
expectedAPIError := context.APIError{
|
||||
Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
|
||||
URL: setting.API.SwaggerURL,
|
||||
|
||||
@@ -76,6 +76,53 @@ nARUPZ9SqaUmRm+KGsSyoYnvN9apiDk5KVQoyfrmweNN7DCIIcoh/B9Ax8nmouKz
|
||||
yBB2fjCM/bJNtN/AsgYbZIScuYK/xqTkwNtbe5WdCyD/QJOHTsPJzx59hgSVo6gf
|
||||
Fe8VBnxHtrY8gPSUU3gkhYLvLzyVX+YLNzRcffobd8gJbfumwFJUkz91oGvYz7xg
|
||||
XN2qmsgBNCbTIzWZMpRDMAbY+n2QFImGf+EJZlMdj6gOrIYq8N4+nMW1FwJivsOb
|
||||
muqySyjZnD2AYjEA6OYPXfCVhaB5fTfhQXbIrZbgsEh4ob/eIdM=
|
||||
=oSDR
|
||||
muqySyjZnD2AYjEA6OYPXfCVhaB5fTfhQXbIrZbgsEh4ob/eIdOdBVgEXta5egEM
|
||||
AMYlmZ47NqBMBeaN0o/ahYMe8eIMaroWkufMfC9VRBSMAkpbDl34oNp0cflmnMYo
|
||||
AFAl8ucRMFTiUnjiWpo27q14tjSyDVsn/CqwbnrgJgCFNV/MGsYsToEkb4JwDIRC
|
||||
bky+1BvqvI8RMlO3MlwzrlIaMrlQfx5NtUb9TyO7S4xZTz864+Ty5p3HhRwbdZMe
|
||||
Ko8sfXFhCcCHFXosI0mX83EyzsrXlbkGRawId7jvrdOAUg/cYP8f/XmV6z1NHHH9
|
||||
cvz+3oLOGuVxUdG0KuS/jigHrLWdRuKM3xfEeesp870yZU3AbyFdoHnGXROJePTl
|
||||
FV8j2P5Ahf/yuVhjdyJSKdZC2h6+HtLG9RiGgLviLLYhtlZG2H6pYyKY5Ud3php+
|
||||
qw1aYL1xtdxrHYkQlAa0vLY/mwpuPfMke9I+rtnrwlLRMCstdiN34ybZ4sRD+gL1
|
||||
w5VIZ/aM6/Gsczd3s/T8psIi09TKPfEU2gWLMGvlDsgz+aSDdVP7XYQpNglaEPet
|
||||
PwARAQABAAv8CHg6+hnV2pblTwGTlTU7V8DO3gwMfn/QhQ/8ju66G5a7J6p/ZreQ
|
||||
nfCJnqYq4AgoW0SuqVSBbbTENF6YjixNmiSlb9iHMZ+ilms24xG0Y3lOMBYYCY3Y
|
||||
nTSNf6nXyconz31TW7jLmTdG9hpykKEKO9WFgt5UpgWe+2CAgtUoBDZyaLrVBZ2h
|
||||
te99WmziDbPQZeZPm7UQ0aX0iRBclxy4+dxjcnrcmi1mdQAM/glgs2sHbEjN7JnV
|
||||
dTOvUSN7/8ixj6I719Wx6MN6jE+BNd0ytZOun6tcDl0vamfT5fBpqbQoJMib2ggo
|
||||
+FGg9VFnzEMLqyI47LfOKUjCIhwVsxS4q9HXa2FtpO8UfRMPjDKgDZQzRTRJScrP
|
||||
s1NJ9HiM/eCHS1YjRmgroo60HygxkoLVCHp+Rz/hi0tG/ptv4q6mdnm8Mwb5JJtV
|
||||
48EvmZoNTWl9xOez1wmQn6caVHipc0qDqn/veoe8N5wdc+3hoMEXbSXqU+kx2KUa
|
||||
cVxCCVoUeURhBgDUGWtx34j1y17zE92BYhtVJTCU89dDe4wOEqGPyCGvRtgTmZ+1
|
||||
KwWr66pij91MV9mlY+7Ue2QHUSmgav2EFGIjVes956p4/F/CJ6qaYoekirMSnmX5
|
||||
jhRt4p6RW7m4omha3LAQ+gN4Fqa4acZUywENBvv1x3v+IWbjGJGn3eBnRrP3o9P+
|
||||
QUAtyMifiRm0ZN8J767o+bzUVmscXrkh7Qml47lQfDToyRI1UZZQmP2izpwHcwbZ
|
||||
NtfkgRUdeEq4GJUGAO8o4Oebbt0ALZ54E2LHhk8xi4ofKkFBDCkUFjcqS3bJJNck
|
||||
rkhfqEkMLETNhPbiC4TRNiunI5PXOinwNPkKI8P/hfp4S49WdIvnARazCoxjZNtl
|
||||
0Cbo+F1wtOH9FZaaWzNlU2lCQ2JJ3MCpLHz+nEmdYWOIWGQu2/s7smLODVEFbYKR
|
||||
50VWVRL7mB83v1XdfMFvExdQ7i5MOX4hFvmwi/WJIKClJfhNwTrHp6Jrm9jA66RL
|
||||
+dNyPKfwcFcYrqt1gwYAruZzP7QgTYVL+cmvGtCaHY4KoR8hanbpqR4YbzzyEXwS
|
||||
ll2FUCaVSokuRAdH3+/CHF9bqog3Zvn6HYcCS/A/rHVGIU9a+7s5IbRe0Ysc2FAN
|
||||
Nm9AsC5YnuyoAjW3cJGaZLYxp2WOZcMEXZeLPFYrNz22R1nRoxnUIPRpsKICXcK0
|
||||
aC4rSMk479jc/8WprWx4d45EVG+6Gsh1AT8LVhDL9yHFrh50ss2jCe1Fnftet6DI
|
||||
V5zHcxBx4sCs91aPxxe12UiJA2wEGAEKACAWIQQ4G/p4KVUOUEVu5g5R68KXFICq
|
||||
DwUCXta5egIbAgHACRBR68KXFICqD8D0IAQZAQoAHRYhBKAm5ShdO9gmF/o8jan0
|
||||
RkmWoKbKBQJe1rl6AAoJEKn0RkmWoKbKacUL/3YYKmiVvcr5LYFzMdwdahkla+6m
|
||||
hEEkL0l3dJNuU97Ou71tA1ieF0fjbVRSWjXKsntKwhyPoXjaZEZwMmv7iZ8BXV+b
|
||||
oO/EG5sg2/6iukJFXZqGnQwMdLVo1jPoXDteZU1qYiCoxLHhGhHL7ivtD1ygEi6w
|
||||
/cMbbOEB5Le1vOWIwqazs8dDcAYyy1PKthRl0ygvh8CpqPwy+AK3uLm0TVwetQAp
|
||||
taux0bDYWCb5Aft1r1nlV44gU4RiC131TDo+TKd754+UuI+UHk1D+LjTmZxRX2S6
|
||||
fXgoMXzrWmthGPdqvVOgKWm7Ef18hmaBECvPnp/tUJeDVVe02KrYQi8Bf2kxveSd
|
||||
8T0N/ExcydU9HgzTL8MuyPI+yp086elQzKJu6vb9tpgxCcglQZrUNT9Uy82pzTRY
|
||||
z9MmhnCDI2SD5L/CW5PsNpPTPy7s3f9DOV0G5Vka4LTSBOCK64NvAGBmRf8rFjJU
|
||||
lPtRPhC7h6uHdUIx3Q550Xogvq5sQm8UBCsbG8OJDADT3FJSIulR9Sh96OsES3sc
|
||||
H09juN4KcbpS03MAeUFwXqw3jBMhDoGKlsjX17Jf31qh/nI/XjigS3XWyj1BLSMG
|
||||
rJfH0NyYoGDCnff37tf+8lD9km9TlnV4Qjd9ujYbDRsefhaSjLVcy/gqdxZEuNBC
|
||||
BWmGwsmLI3nyZ4KDtNsa5JUHUNNZLBN20hvmE41Eszmz4Yg9Ho9DxKiFKvzUULMc
|
||||
bnMHaVHseHHq6+NVUnN1SAcOA0ygjnEid8D57RtdBCD90LXjLB7vlR+HaSMZYOnr
|
||||
DtseivHvqqy4+rxhwV2S3avnls9vRwE4bV6GCiqhoBnWIZRrARLZc2OTBIya82vS
|
||||
BIS1eyhjif1mE7Lqhs6aPD+eqQK2mBtQ/sidN8P/IfKfVF5siXfFbuGZLz5nRIho
|
||||
Yp1z7oO3OZ09lpUk0G1h+ouIFF6goDP48M/AKtbvs9OWk3QKxnOUZD8sRncq95x6
|
||||
m4q1MVb+aJyxwBqDRGaFY+3TVArB1b+kG1JsAvV5dag=
|
||||
=511T
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
@@ -194,7 +194,7 @@ func TestCantMergeWorkInProgress(t *testing.T) {
|
||||
req := NewRequest(t, "GET", resp.Header().Get("Location"))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
text := strings.TrimSpace(htmlDoc.doc.Find(".attached.header > .text.grey").Last().Text())
|
||||
text := strings.TrimSpace(htmlDoc.doc.Find(".attached.merge-section.no-header > .text.grey").Last().Text())
|
||||
assert.NotEmpty(t, text, "Can't find WIP text")
|
||||
|
||||
// remove <strong /> from lang
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// consistencyCheckable a type that can be tested for database consistency
|
||||
@@ -167,3 +168,118 @@ func (action *Action) checkForConsistency(t *testing.T) {
|
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: action.RepoID}).(*Repository)
|
||||
assert.Equal(t, repo.IsPrivate, action.IsPrivate, "action: %+v", action)
|
||||
}
|
||||
|
||||
// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore
|
||||
func CountOrphanedLabels() (int64, error) {
|
||||
noref, err := x.Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
norepo, err := x.Table("label").
|
||||
Join("LEFT", "repository", "label.repo_id=repository.id").
|
||||
Where(builder.IsNull{"repository.id"}).And(builder.Gt{"label.repo_id": 0}).
|
||||
Count("id")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
noorg, err := x.Table("label").
|
||||
Join("LEFT", "`user`", "label.org_id=`user`.id").
|
||||
Where(builder.IsNull{"`user`.id"}).And(builder.Gt{"label.org_id": 0}).
|
||||
Count("id")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return noref + norepo + noorg, nil
|
||||
}
|
||||
|
||||
// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore
|
||||
func DeleteOrphanedLabels() error {
|
||||
// delete labels with no reference
|
||||
if _, err := x.Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete labels with none existing repos
|
||||
if _, err := x.In("id", builder.Select("label.id").From("label").
|
||||
Join("LEFT", "repository", "label.repo_id=repository.id").
|
||||
Where(builder.IsNull{"repository.id"}).And(builder.Gt{"label.repo_id": 0})).
|
||||
Delete(Label{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete labels with none existing orgs
|
||||
if _, err := x.In("id", builder.Select("label.id").From("label").
|
||||
Join("LEFT", "`user`", "label.org_id=`user`.id").
|
||||
Where(builder.IsNull{"`user`.id"}).And(builder.Gt{"label.org_id": 0})).
|
||||
Delete(Label{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CountOrphanedIssues count issues without a repo
|
||||
func CountOrphanedIssues() (int64, error) {
|
||||
return x.Table("issue").
|
||||
Join("LEFT", "repository", "issue.repo_id=repository.id").
|
||||
Where(builder.IsNull{"repository.id"}).
|
||||
Count("id")
|
||||
}
|
||||
|
||||
// DeleteOrphanedIssues delete issues without a repo
|
||||
func DeleteOrphanedIssues() error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ids []int64
|
||||
|
||||
if err := sess.Table("issue").Distinct("issue.repo_id").
|
||||
Join("LEFT", "repository", "issue.repo_id=repository.id").
|
||||
Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id").
|
||||
Find(&ids); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var attachmentPaths []string
|
||||
for i := range ids {
|
||||
paths, err := deleteIssuesByRepoID(sess, ids[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
attachmentPaths = append(attachmentPaths, paths...)
|
||||
}
|
||||
|
||||
if err := sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove issue attachment files.
|
||||
for i := range attachmentPaths {
|
||||
removeAllWithNotice(x, "Delete issue attachment", attachmentPaths[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CountOrphanedObjects count subjects with have no existing refobject anymore
|
||||
func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
|
||||
return x.Table("`"+subject+"`").
|
||||
Join("LEFT", refobject, joinCond).
|
||||
Where(builder.IsNull{"`" + refobject + "`.id"}).
|
||||
Count("id")
|
||||
}
|
||||
|
||||
// DeleteOrphanedObjects delete subjects with have no existing refobject anymore
|
||||
func DeleteOrphanedObjects(subject, refobject, joinCond string) error {
|
||||
_, err := x.In("id", builder.Select("`"+subject+"`.id").
|
||||
From("`"+subject+"`").
|
||||
Join("LEFT", "`"+refobject+"`", joinCond).
|
||||
Where(builder.IsNull{"`" + refobject + "`.id"})).
|
||||
Delete("`" + subject + "`")
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
|
||||
for i, k := range e.Subkeys {
|
||||
subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, expiry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, ErrGPGKeyParsing{ParseError: err}
|
||||
}
|
||||
subkeys[i] = subs
|
||||
}
|
||||
@@ -741,6 +741,21 @@ func verifyWithGPGSettings(gpgSettings *git.GPGSettings, sig *packet.Signature,
|
||||
CanSign: pubkey.CanSign(),
|
||||
KeyID: pubkey.KeyIdString(),
|
||||
}
|
||||
for _, subKey := range ekey.Subkeys {
|
||||
content, err := base64EncPubKey(subKey.PublicKey)
|
||||
if err != nil {
|
||||
return &CommitVerification{
|
||||
CommittingUser: committer,
|
||||
Verified: false,
|
||||
Reason: "gpg.error.generate_hash",
|
||||
}
|
||||
}
|
||||
k.SubsKey = append(k.SubsKey, &GPGKey{
|
||||
Content: content,
|
||||
CanSign: subKey.PublicKey.CanSign(),
|
||||
KeyID: subKey.PublicKey.KeyIdString(),
|
||||
})
|
||||
}
|
||||
if commitVerification := hashAndVerifyWithSubKeys(sig, payload, k, committer, &User{
|
||||
Name: gpgSettings.Name,
|
||||
Email: gpgSettings.Email,
|
||||
|
||||
@@ -76,7 +76,6 @@ var (
|
||||
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
|
||||
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
|
||||
const issueMaxDupIndexAttempts = 3
|
||||
const maxIssueIDs = 950
|
||||
|
||||
func init() {
|
||||
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
||||
@@ -249,7 +248,7 @@ func (issue *Issue) loadReactions(e Engine) (err error) {
|
||||
}
|
||||
|
||||
func (issue *Issue) loadMilestone(e Engine) (err error) {
|
||||
if issue.Milestone == nil && issue.MilestoneID > 0 {
|
||||
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
|
||||
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
|
||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
||||
@@ -1114,9 +1113,6 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
|
||||
}
|
||||
|
||||
if len(opts.IssueIDs) > 0 {
|
||||
if len(opts.IssueIDs) > maxIssueIDs {
|
||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
||||
}
|
||||
sess.In("issue.id", opts.IssueIDs)
|
||||
}
|
||||
|
||||
@@ -1360,9 +1356,6 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
|
||||
Where("issue.repo_id = ?", opts.RepoID)
|
||||
|
||||
if len(opts.IssueIDs) > 0 {
|
||||
if len(opts.IssueIDs) > maxIssueIDs {
|
||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
||||
}
|
||||
sess.In("issue.id", opts.IssueIDs)
|
||||
}
|
||||
|
||||
@@ -1446,9 +1439,6 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
|
||||
cond = cond.And(builder.In("issue.repo_id", opts.RepoIDs))
|
||||
}
|
||||
if len(opts.IssueIDs) > 0 {
|
||||
if len(opts.IssueIDs) > maxIssueIDs {
|
||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
||||
}
|
||||
cond = cond.And(builder.In("issue.id", opts.IssueIDs))
|
||||
}
|
||||
|
||||
@@ -1916,3 +1906,70 @@ func UpdateReactionsMigrationsByType(gitServiceType structs.GitServiceType, orig
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func deleteIssuesByRepoID(sess Engine, repoID int64) (attachmentPaths []string, err error) {
|
||||
deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID})
|
||||
|
||||
// Delete comments and attachments
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Comment{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Dependencies for issues in this repository
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueDependency{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Delete dependencies for issues in other repositories
|
||||
if _, err = sess.In("dependency_id", deleteCond).
|
||||
Delete(&IssueDependency{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueUser{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Reaction{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueWatch{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Stopwatch{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&TrackedTime{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var attachments []*Attachment
|
||||
if err = sess.In("issue_id", deleteCond).
|
||||
Find(&attachments); err != nil {
|
||||
return
|
||||
}
|
||||
for j := range attachments {
|
||||
attachmentPaths = append(attachmentPaths, attachments[j].LocalPath())
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Attachment{}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -212,6 +212,8 @@ var migrations = []Migration{
|
||||
NewMigration("Add ResolveDoerID to Comment table", addResolveDoerIDCommentColumn),
|
||||
// v139 -> v140
|
||||
NewMigration("prepend refs/heads/ to issue refs", prependRefsHeadsToIssueRefs),
|
||||
// v140 -> v141
|
||||
NewMigration("Save detected language file size to database instead of percent", fixLanguageStatsToSaveSize),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
||||
@@ -8,8 +8,10 @@ import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -26,8 +28,19 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
|
||||
LowerName string `xorm:"UNIQUE NOT NULL"`
|
||||
Avatar string
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
count, err := x.Count(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("%d User Avatar(s) to migrate ...", count)
|
||||
|
||||
deleteList := make(map[string]struct{})
|
||||
start := 0
|
||||
migrated := 0
|
||||
for {
|
||||
if err := sess.Begin(); err != nil {
|
||||
return fmt.Errorf("session.Begin: %v", err)
|
||||
@@ -73,6 +86,19 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
|
||||
}
|
||||
|
||||
deleteList[filepath.Join(setting.AvatarUploadPath, oldAvatar)] = struct{}{}
|
||||
migrated++
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Info(
|
||||
"%d/%d (%2.0f%%) User Avatar(s) migrated (%d old avatars to be deleted) in %d batches. %d Remaining ...",
|
||||
migrated,
|
||||
count,
|
||||
float64(migrated)/float64(count)*100,
|
||||
len(deleteList),
|
||||
int(math.Ceil(float64(migrated)/float64(50))),
|
||||
count-int64(migrated))
|
||||
default:
|
||||
}
|
||||
}
|
||||
if err := sess.Commit(); err != nil {
|
||||
_ = sess.Rollback()
|
||||
@@ -80,11 +106,28 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
|
||||
}
|
||||
}
|
||||
|
||||
deleteCount := len(deleteList)
|
||||
log.Info("Deleting %d old avatars ...", deleteCount)
|
||||
i := 0
|
||||
for file := range deleteList {
|
||||
if err := os.Remove(file); err != nil {
|
||||
log.Warn("os.Remove: %v", err)
|
||||
}
|
||||
i++
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Info(
|
||||
"%d/%d (%2.0f%%) Old User Avatar(s) deleted. %d Remaining ...",
|
||||
i,
|
||||
deleteCount,
|
||||
float64(i)/float64(deleteCount)*100,
|
||||
deleteCount-i)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Completed migrating %d User Avatar(s) and deleting %d Old Avatars", count, deleteCount)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -43,17 +45,27 @@ func fixMergeBase(x *xorm.Engine) error {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
count, err := x.Count(new(PullRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("%d Pull Request(s) to migrate ...", count)
|
||||
|
||||
i := 0
|
||||
start := 0
|
||||
for {
|
||||
prs := make([]PullRequest, 0, 50)
|
||||
if err := x.Limit(limit, i).Asc("id").Find(&prs); err != nil {
|
||||
if err := x.Limit(limit, start).Asc("id").Find(&prs); err != nil {
|
||||
return fmt.Errorf("Find: %v", err)
|
||||
}
|
||||
if len(prs) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
i += len(prs)
|
||||
start += 50
|
||||
for _, pr := range prs {
|
||||
baseRepo := &Repository{ID: pr.BaseRepoID}
|
||||
has, err := x.Table("repository").Get(baseRepo)
|
||||
@@ -102,8 +114,14 @@ func fixMergeBase(x *xorm.Engine) error {
|
||||
}
|
||||
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
|
||||
x.ID(pr.ID).Cols("merge_base").Update(pr)
|
||||
i++
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Info("%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...", i, count, float64(i)/float64(count)*100, int(math.Ceil(float64(i)/float64(limit))), count-int64(i))
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(i)/float64(limit))))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@ package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -43,17 +45,26 @@ func refixMergeBase(x *xorm.Engine) error {
|
||||
limit = 50
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
count, err := x.Where("has_merged = ?", true).Count(new(PullRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("%d Merged Pull Request(s) to migrate ...", count)
|
||||
|
||||
i := 0
|
||||
start := 0
|
||||
for {
|
||||
prs := make([]PullRequest, 0, 50)
|
||||
if err := x.Limit(limit, i).Asc("id").Where("has_merged = ?", true).Find(&prs); err != nil {
|
||||
if err := x.Limit(limit, start).Asc("id").Where("has_merged = ?", true).Find(&prs); err != nil {
|
||||
return fmt.Errorf("Find: %v", err)
|
||||
}
|
||||
if len(prs) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
i += len(prs)
|
||||
start += 50
|
||||
for _, pr := range prs {
|
||||
baseRepo := &Repository{ID: pr.BaseRepoID}
|
||||
has, err := x.Table("repository").Get(baseRepo)
|
||||
@@ -90,7 +101,15 @@ func refixMergeBase(x *xorm.Engine) error {
|
||||
}
|
||||
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
|
||||
x.ID(pr.ID).Cols("merge_base").Update(pr)
|
||||
i++
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Info("%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...", i, count, float64(i)/float64(count)*100, int(math.Ceil(float64(i)/float64(limit))), count-int64(i))
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(i)/float64(limit))))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,25 +6,60 @@ package migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addCommitDivergenceToPulls(x *xorm.Engine) error {
|
||||
type Repository struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OwnerID int64 `xorm:"UNIQUE(s) index"`
|
||||
OwnerName string
|
||||
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Name string `xorm:"INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
type PullRequest struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
|
||||
CommitsAhead int
|
||||
CommitsBehind int
|
||||
|
||||
BaseRepoID int64 `xorm:"INDEX"`
|
||||
BaseBranch string
|
||||
|
||||
HasMerged bool `xorm:"INDEX"`
|
||||
MergedCommitID string `xorm:"VARCHAR(40)"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(models.PullRequest)); err != nil {
|
||||
return fmt.Errorf("Sync2: %v", err)
|
||||
}
|
||||
|
||||
var last int
|
||||
last := 0
|
||||
migrated := 0
|
||||
|
||||
batchSize := setting.Database.IterateBufferSize
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
count, err := sess.Where("has_merged = ?", false).Count(new(PullRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("%d Unmerged Pull Request(s) to migrate ...", count)
|
||||
|
||||
for {
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
@@ -37,27 +72,53 @@ func addCommitDivergenceToPulls(x *xorm.Engine) error {
|
||||
if len(results) == 0 {
|
||||
break
|
||||
}
|
||||
last += len(results)
|
||||
last += batchSize
|
||||
|
||||
for _, pr := range results {
|
||||
divergence, err := pull_service.GetDiverging(pr)
|
||||
baseRepo := &Repository{ID: pr.BaseRepoID}
|
||||
has, err := x.Table("repository").Get(baseRepo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to get base repo %d %v", pr.BaseRepoID, err)
|
||||
}
|
||||
if !has {
|
||||
log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID)
|
||||
continue
|
||||
}
|
||||
userPath := filepath.Join(setting.RepoRootPath, strings.ToLower(baseRepo.OwnerName))
|
||||
repoPath := filepath.Join(userPath, strings.ToLower(baseRepo.Name)+".git")
|
||||
|
||||
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
|
||||
|
||||
divergence, err := git.GetDivergingCommits(repoPath, pr.BaseBranch, gitRefName)
|
||||
if err != nil {
|
||||
log.Warn("Could not recalculate Divergence for pull: %d", pr.ID)
|
||||
pr.CommitsAhead = 0
|
||||
pr.CommitsBehind = 0
|
||||
}
|
||||
if divergence != nil {
|
||||
pr.CommitsAhead = divergence.Ahead
|
||||
pr.CommitsBehind = divergence.Behind
|
||||
}
|
||||
pr.CommitsAhead = divergence.Ahead
|
||||
pr.CommitsBehind = divergence.Behind
|
||||
|
||||
if _, err = sess.ID(pr.ID).Cols("commits_ahead", "commits_behind").Update(pr); err != nil {
|
||||
return fmt.Errorf("Update Cols: %v", err)
|
||||
}
|
||||
migrated++
|
||||
}
|
||||
|
||||
if err := sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Info(
|
||||
"%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...",
|
||||
migrated,
|
||||
count,
|
||||
float64(migrated)/float64(count)*100,
|
||||
int(math.Ceil(float64(migrated)/float64(batchSize))),
|
||||
count-int64(migrated))
|
||||
default:
|
||||
}
|
||||
}
|
||||
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(migrated)/float64(batchSize))))
|
||||
return nil
|
||||
}
|
||||
|
||||
56
models/migrations/v140.go
Normal file
56
models/migrations/v140.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2020 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 migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func fixLanguageStatsToSaveSize(x *xorm.Engine) error {
|
||||
// LanguageStat see models/repo_language_stats.go
|
||||
type LanguageStat struct {
|
||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
// RepoIndexerType specifies the repository indexer type
|
||||
type RepoIndexerType int
|
||||
|
||||
const (
|
||||
// RepoIndexerTypeCode code indexer
|
||||
RepoIndexerTypeCode RepoIndexerType = iota // 0
|
||||
// RepoIndexerTypeStats repository stats indexer
|
||||
RepoIndexerTypeStats // 1
|
||||
)
|
||||
|
||||
// RepoIndexerStatus see models/repo_indexer.go
|
||||
type RepoIndexerStatus struct {
|
||||
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(LanguageStat)); err != nil {
|
||||
return fmt.Errorf("Sync2: %v", err)
|
||||
}
|
||||
|
||||
x.Delete(&RepoIndexerStatus{IndexerType: RepoIndexerTypeStats})
|
||||
|
||||
// Delete language stat statuses
|
||||
truncExpr := "TRUNCATE TABLE"
|
||||
if setting.Database.UseSQLite3 {
|
||||
truncExpr = "DELETE FROM"
|
||||
}
|
||||
|
||||
// Delete language stats
|
||||
if _, err := x.Exec(fmt.Sprintf("%s language_stat", truncExpr)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
return dropTableColumns(sess, "language_stat", "percentage")
|
||||
}
|
||||
@@ -182,6 +182,10 @@ func SetEngine() (err error) {
|
||||
}
|
||||
|
||||
// NewEngine initializes a new xorm.Engine
|
||||
// This function must never call .Sync2() if the provided migration function fails.
|
||||
// When called from the "doctor" command, the migration function is a version check
|
||||
// that prevents the doctor from fixing anything in the database if the migration level
|
||||
// is different from the expected value.
|
||||
func NewEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) {
|
||||
if err = SetEngine(); err != nil {
|
||||
return err
|
||||
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/unknwon/com"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -174,9 +173,10 @@ type Repository struct {
|
||||
*Mirror `xorm:"-"`
|
||||
Status RepositoryStatus `xorm:"NOT NULL DEFAULT 0"`
|
||||
|
||||
RenderingMetas map[string]string `xorm:"-"`
|
||||
Units []*RepoUnit `xorm:"-"`
|
||||
PrimaryLanguage *LanguageStat `xorm:"-"`
|
||||
RenderingMetas map[string]string `xorm:"-"`
|
||||
DocumentRenderingMetas map[string]string `xorm:"-"`
|
||||
Units []*RepoUnit `xorm:"-"`
|
||||
PrimaryLanguage *LanguageStat `xorm:"-"`
|
||||
|
||||
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
||||
ForkID int64 `xorm:"INDEX"`
|
||||
@@ -534,11 +534,12 @@ func (repo *Repository) mustOwner(e Engine) *User {
|
||||
|
||||
// ComposeMetas composes a map of metas for properly rendering issue links and external issue trackers.
|
||||
func (repo *Repository) ComposeMetas() map[string]string {
|
||||
if repo.RenderingMetas == nil {
|
||||
if len(repo.RenderingMetas) == 0 {
|
||||
metas := map[string]string{
|
||||
"user": repo.OwnerName,
|
||||
"repo": repo.Name,
|
||||
"repoPath": repo.RepoPath(),
|
||||
"mode": "comment",
|
||||
}
|
||||
|
||||
unit, err := repo.GetUnit(UnitTypeExternalTracker)
|
||||
@@ -570,6 +571,19 @@ func (repo *Repository) ComposeMetas() map[string]string {
|
||||
return repo.RenderingMetas
|
||||
}
|
||||
|
||||
// ComposeDocumentMetas composes a map of metas for properly rendering documents
|
||||
func (repo *Repository) ComposeDocumentMetas() map[string]string {
|
||||
if len(repo.DocumentRenderingMetas) == 0 {
|
||||
metas := map[string]string{}
|
||||
for k, v := range repo.ComposeMetas() {
|
||||
metas[k] = v
|
||||
}
|
||||
metas["mode"] = "document"
|
||||
repo.DocumentRenderingMetas = metas
|
||||
}
|
||||
return repo.DocumentRenderingMetas
|
||||
}
|
||||
|
||||
// DeleteWiki removes the actual and local copy of repository wiki.
|
||||
func (repo *Repository) DeleteWiki() error {
|
||||
return repo.deleteWiki(x)
|
||||
@@ -1575,67 +1589,9 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
||||
return fmt.Errorf("deleteBeans: %v", err)
|
||||
}
|
||||
|
||||
deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repoID})
|
||||
// Delete comments and attachments
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Comment{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Dependencies for issues in this repository
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueDependency{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete dependencies for issues in other repositories
|
||||
if _, err = sess.In("dependency_id", deleteCond).
|
||||
Delete(&IssueDependency{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueUser{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Reaction{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&IssueWatch{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Stopwatch{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&TrackedTime{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
attachments = attachments[:0]
|
||||
if err = sess.Join("INNER", "issue", "issue.id = attachment.issue_id").
|
||||
Where("issue.repo_id = ?", repoID).
|
||||
Find(&attachments); err != nil {
|
||||
return err
|
||||
}
|
||||
attachmentPaths := make([]string, 0, len(attachments))
|
||||
for j := range attachments {
|
||||
attachmentPaths = append(attachmentPaths, attachments[j].LocalPath())
|
||||
}
|
||||
|
||||
if _, err = sess.In("issue_id", deleteCond).
|
||||
Delete(&Attachment{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
|
||||
// Delete Issues and related objects
|
||||
var attachmentPaths []string
|
||||
if attachmentPaths, err = deleteIssuesByRepoID(sess, repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ type LanguageStat struct {
|
||||
CommitID string
|
||||
IsPrimary bool
|
||||
Language string `xorm:"VARCHAR(30) UNIQUE(s) INDEX NOT NULL"`
|
||||
Percentage float32 `xorm:"NUMERIC(5,2) NOT NULL DEFAULT 0"`
|
||||
Percentage float32 `xorm:"-"`
|
||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
Color string `xorm:"-"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
|
||||
}
|
||||
@@ -34,12 +35,36 @@ func (stats LanguageStatList) loadAttributes() {
|
||||
}
|
||||
}
|
||||
|
||||
func (stats LanguageStatList) getLanguagePercentages() map[string]float32 {
|
||||
langPerc := make(map[string]float32)
|
||||
var otherPerc float32 = 100
|
||||
var total int64
|
||||
|
||||
for _, stat := range stats {
|
||||
total += stat.Size
|
||||
}
|
||||
if total > 0 {
|
||||
for _, stat := range stats {
|
||||
perc := float32(math.Round(float64(stat.Size)/float64(total)*1000) / 10)
|
||||
if perc <= 0.1 {
|
||||
continue
|
||||
}
|
||||
otherPerc -= perc
|
||||
langPerc[stat.Language] = perc
|
||||
}
|
||||
otherPerc = float32(math.Round(float64(otherPerc)*10) / 10)
|
||||
}
|
||||
if otherPerc > 0 {
|
||||
langPerc["other"] = otherPerc
|
||||
}
|
||||
return langPerc
|
||||
}
|
||||
|
||||
func (repo *Repository) getLanguageStats(e Engine) (LanguageStatList, error) {
|
||||
stats := make(LanguageStatList, 0, 6)
|
||||
if err := e.Where("`repo_id` = ?", repo.ID).Desc("`percentage`").Find(&stats); err != nil {
|
||||
if err := e.Where("`repo_id` = ?", repo.ID).Desc("`size`").Find(&stats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stats.loadAttributes()
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
@@ -54,13 +79,18 @@ func (repo *Repository) GetTopLanguageStats(limit int) (LanguageStatList, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
perc := stats.getLanguagePercentages()
|
||||
topstats := make(LanguageStatList, 0, limit)
|
||||
var other float32
|
||||
for i := range stats {
|
||||
if stats[i].Language == "other" || len(topstats) >= limit {
|
||||
other += stats[i].Percentage
|
||||
if _, ok := perc[stats[i].Language]; !ok {
|
||||
continue
|
||||
}
|
||||
if stats[i].Language == "other" || len(topstats) >= limit {
|
||||
other += perc[stats[i].Language]
|
||||
continue
|
||||
}
|
||||
stats[i].Percentage = perc[stats[i].Language]
|
||||
topstats = append(topstats, stats[i])
|
||||
}
|
||||
if other > 0 {
|
||||
@@ -71,11 +101,12 @@ func (repo *Repository) GetTopLanguageStats(limit int) (LanguageStatList, error)
|
||||
Percentage: float32(math.Round(float64(other)*10) / 10),
|
||||
})
|
||||
}
|
||||
topstats.loadAttributes()
|
||||
return topstats, nil
|
||||
}
|
||||
|
||||
// UpdateLanguageStats updates the language statistics for repository
|
||||
func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]float32) error {
|
||||
func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]int64) error {
|
||||
sess := x.NewSession()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
@@ -87,15 +118,15 @@ func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]fl
|
||||
return err
|
||||
}
|
||||
var topLang string
|
||||
var p float32
|
||||
for lang, perc := range stats {
|
||||
if perc > p {
|
||||
p = perc
|
||||
var s int64
|
||||
for lang, size := range stats {
|
||||
if size > s {
|
||||
s = size
|
||||
topLang = strings.ToLower(lang)
|
||||
}
|
||||
}
|
||||
|
||||
for lang, perc := range stats {
|
||||
for lang, size := range stats {
|
||||
upd := false
|
||||
llang := strings.ToLower(lang)
|
||||
for _, s := range oldstats {
|
||||
@@ -103,8 +134,8 @@ func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]fl
|
||||
if strings.ToLower(s.Language) == llang {
|
||||
s.CommitID = commitID
|
||||
s.IsPrimary = llang == topLang
|
||||
s.Percentage = perc
|
||||
if _, err := sess.ID(s.ID).Cols("`commit_id`", "`percentage`", "`is_primary`").Update(s); err != nil {
|
||||
s.Size = size
|
||||
if _, err := sess.ID(s.ID).Cols("`commit_id`", "`size`", "`is_primary`").Update(s); err != nil {
|
||||
return err
|
||||
}
|
||||
upd = true
|
||||
@@ -114,11 +145,11 @@ func (repo *Repository) UpdateLanguageStats(commitID string, stats map[string]fl
|
||||
// Insert new language
|
||||
if !upd {
|
||||
if _, err := sess.Insert(&LanguageStat{
|
||||
RepoID: repo.ID,
|
||||
CommitID: commitID,
|
||||
IsPrimary: llang == topLang,
|
||||
Language: lang,
|
||||
Percentage: perc,
|
||||
RepoID: repo.ID,
|
||||
CommitID: commitID,
|
||||
IsPrimary: llang == topLang,
|
||||
Language: lang,
|
||||
Size: size,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -153,7 +184,7 @@ func CopyLanguageStat(originalRepo, destRepo *Repository) error {
|
||||
return err
|
||||
}
|
||||
RepoLang := make(LanguageStatList, 0, 6)
|
||||
if err := sess.Where("`repo_id` = ?", originalRepo.ID).Desc("`percentage`").Find(&RepoLang); err != nil {
|
||||
if err := sess.Where("`repo_id` = ?", originalRepo.ID).Desc("`size`").Find(&RepoLang); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(RepoLang) > 0 {
|
||||
|
||||
@@ -140,10 +140,13 @@ type SearchRepoOptions struct {
|
||||
PriorityOwnerID int64
|
||||
OrderBy SearchOrderBy
|
||||
Private bool // Include private repositories in results
|
||||
OnlyPrivate bool // Include only private repositories in results
|
||||
StarredByID int64
|
||||
AllPublic bool // Include also all public repositories of users and public organisations
|
||||
AllLimited bool // Include also all public repositories of limited organisations
|
||||
// None -> include public and private
|
||||
// True -> include just private
|
||||
// False -> incude just public
|
||||
IsPrivate util.OptionalBool
|
||||
// None -> include collaborative AND non-collaborative
|
||||
// True -> include just collaborative
|
||||
// False -> incude just non-collaborative
|
||||
@@ -221,15 +224,8 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
|
||||
))))
|
||||
}
|
||||
|
||||
if opts.OnlyPrivate {
|
||||
cond = cond.And(
|
||||
builder.Or(
|
||||
builder.Eq{"is_private": true},
|
||||
builder.In("owner_id", builder.Select("id").From("`user`").Where(
|
||||
builder.And(
|
||||
builder.Eq{"type": UserTypeOrganization},
|
||||
builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}),
|
||||
)))))
|
||||
if opts.IsPrivate != util.OptionalBoolNone {
|
||||
cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.IsTrue()})
|
||||
}
|
||||
|
||||
if opts.Template != util.OptionalBoolNone {
|
||||
@@ -249,14 +245,35 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
|
||||
}
|
||||
|
||||
if opts.Collaborate != util.OptionalBoolFalse {
|
||||
// A Collaboration is:
|
||||
collaborateCond := builder.And(
|
||||
// 1. Repository we don't own
|
||||
builder.Neq{"owner_id": opts.OwnerID},
|
||||
// 2. But we can see because of:
|
||||
builder.Or(
|
||||
builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID),
|
||||
builder.In("id", builder.Select("`team_repo`.repo_id").
|
||||
// A. We have access
|
||||
builder.In("`repository`.id",
|
||||
builder.Select("`access`.repo_id").
|
||||
From("access").
|
||||
Where(builder.Eq{"`access`.user_id": opts.OwnerID})),
|
||||
// B. We are in a team for
|
||||
builder.In("`repository`.id", builder.Select("`team_repo`.repo_id").
|
||||
From("team_repo").
|
||||
Where(builder.Eq{"`team_user`.uid": opts.OwnerID}).
|
||||
Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id"))),
|
||||
builder.Neq{"owner_id": opts.OwnerID})
|
||||
Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id")),
|
||||
// C. Public repositories in private organizations that we are member of
|
||||
builder.And(
|
||||
builder.Eq{"`repository`.is_private": false},
|
||||
builder.In("`repository`.owner_id",
|
||||
builder.Select("`org_user`.org_id").
|
||||
From("org_user").
|
||||
Join("INNER", "`user`", "`user`.id = `org_user`.org_id").
|
||||
Where(builder.Eq{
|
||||
"`org_user`.uid": opts.OwnerID,
|
||||
"`user`.type": UserTypeOrganization,
|
||||
"`user`.visibility": structs.VisibleTypePrivate,
|
||||
})))),
|
||||
)
|
||||
if !opts.Private {
|
||||
collaborateCond = collaborateCond.And(builder.Expr("owner_id NOT IN (SELECT org_id FROM org_user WHERE org_user.uid = ? AND org_user.is_public = ?)", opts.OwnerID, false))
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/go-enry/go-enry/v2"
|
||||
)
|
||||
|
||||
// GetCodeLanguageWithCallback detects code language based on file name and content using callback
|
||||
func GetCodeLanguageWithCallback(filename string, contentFunc func() ([]byte, error)) string {
|
||||
// GetCodeLanguage detects code language based on file name and content
|
||||
func GetCodeLanguage(filename string, content []byte) string {
|
||||
if language, ok := enry.GetLanguageByExtension(filename); ok {
|
||||
return language
|
||||
}
|
||||
@@ -20,17 +20,9 @@ func GetCodeLanguageWithCallback(filename string, contentFunc func() ([]byte, er
|
||||
return language
|
||||
}
|
||||
|
||||
content, err := contentFunc()
|
||||
if err != nil {
|
||||
if len(content) == 0 {
|
||||
return enry.OtherLanguage
|
||||
}
|
||||
|
||||
return enry.GetLanguage(filepath.Base(filename), content)
|
||||
}
|
||||
|
||||
// GetCodeLanguage detects code language based on file name and content
|
||||
func GetCodeLanguage(filename string, content []byte) string {
|
||||
return GetCodeLanguageWithCallback(filename, func() ([]byte, error) {
|
||||
return content, nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
@@ -64,18 +65,22 @@ type APINotFound struct{}
|
||||
// swagger:response redirect
|
||||
type APIRedirect struct{}
|
||||
|
||||
// Error responses error message to client with given message.
|
||||
// Error responds with an error message to client with given obj as the message.
|
||||
// If status is 500, also it prints error to log.
|
||||
func (ctx *APIContext) Error(status int, title string, obj interface{}) {
|
||||
var message string
|
||||
if err, ok := obj.(error); ok {
|
||||
message = err.Error()
|
||||
} else {
|
||||
message = obj.(string)
|
||||
message = fmt.Sprintf("%s", obj)
|
||||
}
|
||||
|
||||
if status == 500 {
|
||||
log.Error("%s: %s", title, message)
|
||||
if status == http.StatusInternalServerError {
|
||||
log.ErrorWithSkip(1, "%s: %s", title, message)
|
||||
|
||||
if macaron.Env == macaron.PROD {
|
||||
message = ""
|
||||
}
|
||||
}
|
||||
|
||||
ctx.JSON(status, APIError{
|
||||
@@ -84,6 +89,22 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) {
|
||||
})
|
||||
}
|
||||
|
||||
// InternalServerError responds with an error message to the client with the error as a message
|
||||
// and the file and line of the caller.
|
||||
func (ctx *APIContext) InternalServerError(err error) {
|
||||
log.ErrorWithSkip(1, "InternalServerError: %v", err)
|
||||
|
||||
var message string
|
||||
if macaron.Env != macaron.PROD {
|
||||
message = err.Error()
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusInternalServerError, APIError{
|
||||
Message: message,
|
||||
URL: setting.API.SwaggerURL,
|
||||
})
|
||||
}
|
||||
|
||||
func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string {
|
||||
page := NewPagination(total, pageSize, curPage, 0)
|
||||
paginater := page.Paginater
|
||||
|
||||
@@ -49,7 +49,9 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
if ctx.Req.URL.Path != "/user/settings/change_password" {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
|
||||
ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL)
|
||||
if ctx.Req.URL.Path != "/user/events" {
|
||||
ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL)
|
||||
}
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func ToPullReviewCommentList(review *models.Review, doer *models.User) ([]*api.P
|
||||
OrigCommitID: comment.OldRef,
|
||||
DiffHunk: patch2diff(comment.Patch),
|
||||
HTMLURL: comment.HTMLURL(),
|
||||
HTMLPullURL: review.Issue.APIURL(),
|
||||
HTMLPullURL: review.Issue.HTMLURL(),
|
||||
}
|
||||
|
||||
if comment.Line < 0 {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package emoji
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@@ -19,6 +20,7 @@ type Emoji struct {
|
||||
Description string
|
||||
Aliases []string
|
||||
UnicodeVersion string
|
||||
SkinTones bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -48,6 +50,12 @@ func loadMap() {
|
||||
// process emoji codes and aliases
|
||||
codePairs := make([]string, 0)
|
||||
aliasPairs := make([]string, 0)
|
||||
|
||||
// sort from largest to small so we match combined emoji first
|
||||
sort.Slice(GemojiData, func(i, j int) bool {
|
||||
return len(GemojiData[i].Emoji) > len(GemojiData[j].Emoji)
|
||||
})
|
||||
|
||||
for i, e := range GemojiData {
|
||||
if e.Emoji == "" || len(e.Aliases) == 0 {
|
||||
continue
|
||||
@@ -72,6 +80,7 @@ func loadMap() {
|
||||
codeReplacer = strings.NewReplacer(codePairs...)
|
||||
aliasReplacer = strings.NewReplacer(aliasPairs...)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// FromCode retrieves the emoji data based on the provided unicode code (ie,
|
||||
@@ -117,3 +126,22 @@ func ReplaceAliases(s string) string {
|
||||
loadMap()
|
||||
return aliasReplacer.Replace(s)
|
||||
}
|
||||
|
||||
// FindEmojiSubmatchIndex returns index pair of longest emoji in a string
|
||||
func FindEmojiSubmatchIndex(s string) []int {
|
||||
loadMap()
|
||||
|
||||
//see if there are any emoji in string before looking for position of specific ones
|
||||
//no performance difference when there is a match but 10x faster when there are not
|
||||
if s == ReplaceCodes(s) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for j := range GemojiData {
|
||||
i := strings.Index(s, GemojiData[j].Emoji)
|
||||
if i != -1 {
|
||||
return []int{i, i + len(GemojiData[j].Emoji)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
|
||||
"code.gitea.io/gitea/modules/analyze"
|
||||
|
||||
@@ -20,8 +19,22 @@ import (
|
||||
|
||||
const fileSizeLimit int64 = 16 * 1024 * 1024
|
||||
|
||||
// specialLanguages defines list of languages that are excluded from the calculation
|
||||
// unless they are the only language present in repository. Only languages which under
|
||||
// normal circumstances are not considered to be code should be listed here.
|
||||
var specialLanguages = []string{
|
||||
"XML",
|
||||
"JSON",
|
||||
"TOML",
|
||||
"YAML",
|
||||
"INI",
|
||||
"SVG",
|
||||
"Text",
|
||||
"Markdown",
|
||||
}
|
||||
|
||||
// GetLanguageStats calculates language stats for git repository at specified commit
|
||||
func (repo *Repository) GetLanguageStats(commitID string) (map[string]float32, error) {
|
||||
func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) {
|
||||
r, err := git.PlainOpen(repo.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -43,24 +56,32 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]float32, e
|
||||
}
|
||||
|
||||
sizes := make(map[string]int64)
|
||||
var total int64
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
if enry.IsVendor(f.Name) || enry.IsDotFile(f.Name) ||
|
||||
if f.Size == 0 || enry.IsVendor(f.Name) || enry.IsDotFile(f.Name) ||
|
||||
enry.IsDocumentation(f.Name) || enry.IsConfiguration(f.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If content can not be read just do detection by filename
|
||||
content, _ := readFile(f, fileSizeLimit)
|
||||
if enry.IsGenerated(f.Name, content) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Use .gitattributes file for linguist overrides
|
||||
|
||||
language := analyze.GetCodeLanguageWithCallback(f.Name, func() ([]byte, error) {
|
||||
return readFile(f, fileSizeLimit)
|
||||
})
|
||||
language := analyze.GetCodeLanguage(f.Name, content)
|
||||
if language == enry.OtherLanguage || language == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// group languages, such as Pug -> HTML; SCSS -> CSS
|
||||
group := enry.GetLanguageGroup(language)
|
||||
if group != "" {
|
||||
language = group
|
||||
}
|
||||
|
||||
sizes[language] += f.Size
|
||||
total += f.Size
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -68,21 +89,14 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]float32, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats := make(map[string]float32)
|
||||
var otherPerc float32 = 100
|
||||
for language, size := range sizes {
|
||||
perc := float32(math.Round(float64(size)/float64(total)*1000) / 10)
|
||||
if perc <= 0.1 {
|
||||
continue
|
||||
// filter special languages unless they are the only language
|
||||
if len(sizes) > 1 {
|
||||
for _, language := range specialLanguages {
|
||||
delete(sizes, language)
|
||||
}
|
||||
otherPerc -= perc
|
||||
stats[language] = perc
|
||||
}
|
||||
otherPerc = float32(math.Round(float64(otherPerc)*10) / 10)
|
||||
if otherPerc > 0 {
|
||||
stats["other"] = otherPerc
|
||||
}
|
||||
return stats, nil
|
||||
|
||||
return sizes, nil
|
||||
}
|
||||
|
||||
func readFile(f *object.File, limit int64) ([]byte, error) {
|
||||
|
||||
@@ -34,9 +34,10 @@ func TestRepoStatsIndex(t *testing.T) {
|
||||
|
||||
repo, err := models.GetRepositoryByID(1)
|
||||
assert.NoError(t, err)
|
||||
status, err := repo.GetIndexerStatus(models.RepoIndexerTypeStats)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", status.CommitSha)
|
||||
langs, err := repo.GetTopLanguageStats(5)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, langs, 1)
|
||||
assert.Equal(t, "other", langs[0].Language)
|
||||
assert.Equal(t, float32(100), langs[0].Percentage)
|
||||
assert.Empty(t, langs)
|
||||
}
|
||||
|
||||
@@ -65,10 +65,6 @@ var (
|
||||
|
||||
// EmojiShortCodeRegex find emoji by alias like :smile:
|
||||
EmojiShortCodeRegex = regexp.MustCompile(`\:[\w\+\-]+\:{1}`)
|
||||
|
||||
// find emoji literal: search all emoji hex range as many times as they appear as
|
||||
// some emojis (skin color etc..) are just two or more chained together
|
||||
emojiRegex = regexp.MustCompile(`[\x{1F000}-\x{1FFFF}|\x{2000}-\x{32ff}|\x{fe4e5}-\x{fe4ee}|\x{200D}|\x{FE0F}|\x{e0000}-\x{e007f}]+`)
|
||||
)
|
||||
|
||||
// CSS class for action keywords (e.g. "closes: #1")
|
||||
@@ -922,8 +918,7 @@ func emojiShortCodeProcessor(ctx *postProcessCtx, node *html.Node) {
|
||||
|
||||
// emoji processor to match emoji and add emoji class
|
||||
func emojiProcessor(ctx *postProcessCtx, node *html.Node) {
|
||||
m := emojiRegex.FindStringSubmatchIndex(node.Data)
|
||||
|
||||
m := emoji.FindEmojiSubmatchIndex(node.Data)
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -263,7 +263,9 @@ func TestRender_emoji(t *testing.T) {
|
||||
test(
|
||||
"Some text with :smile: in the middle",
|
||||
`<p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span> in the middle</p>`)
|
||||
|
||||
test(
|
||||
"Some text with 😄😄 2 emoji next to each other",
|
||||
`<p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span><span class="emoji" aria-label="grinning face with smiling eyes">😄</span> 2 emoji next to each other</p>`)
|
||||
// should match nothing
|
||||
test(
|
||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
|
||||
@@ -151,6 +151,16 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
|
||||
v.AppendChild(v, newChild)
|
||||
}
|
||||
}
|
||||
case *ast.Text:
|
||||
if v.SoftLineBreak() && !v.HardLineBreak() {
|
||||
renderMetas := pc.Get(renderMetasKey).(map[string]string)
|
||||
mode := renderMetas["mode"]
|
||||
if mode != "document" {
|
||||
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInComments)
|
||||
} else {
|
||||
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.WalkContinue, nil
|
||||
})
|
||||
|
||||
@@ -29,17 +29,19 @@ var once = sync.Once{}
|
||||
|
||||
var urlPrefixKey = parser.NewContextKey()
|
||||
var isWikiKey = parser.NewContextKey()
|
||||
var renderMetasKey = parser.NewContextKey()
|
||||
|
||||
// NewGiteaParseContext creates a parser.Context with the gitea context set
|
||||
func NewGiteaParseContext(urlPrefix string, isWiki bool) parser.Context {
|
||||
func NewGiteaParseContext(urlPrefix string, metas map[string]string, isWiki bool) parser.Context {
|
||||
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
|
||||
pc.Set(urlPrefixKey, urlPrefix)
|
||||
pc.Set(isWikiKey, isWiki)
|
||||
pc.Set(renderMetasKey, metas)
|
||||
return pc
|
||||
}
|
||||
|
||||
// RenderRaw renders Markdown to HTML without handling special links.
|
||||
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
|
||||
// render renders Markdown to HTML without handling special links.
|
||||
func render(body []byte, urlPrefix string, metas map[string]string, wikiMarkdown bool) []byte {
|
||||
once.Do(func() {
|
||||
converter = goldmark.New(
|
||||
goldmark.WithExtensions(extension.Table,
|
||||
@@ -75,12 +77,9 @@ func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
|
||||
),
|
||||
)
|
||||
|
||||
if setting.Markdown.EnableHardLineBreak {
|
||||
converter.Renderer().AddOptions(html.WithHardWraps())
|
||||
}
|
||||
})
|
||||
|
||||
pc := NewGiteaParseContext(urlPrefix, wikiMarkdown)
|
||||
pc := NewGiteaParseContext(urlPrefix, metas, wikiMarkdown)
|
||||
var buf bytes.Buffer
|
||||
if err := converter.Convert(giteautil.NormalizeEOL(body), &buf, parser.WithContext(pc)); err != nil {
|
||||
log.Error("Unable to render: %v", err)
|
||||
@@ -112,7 +111,7 @@ func (Parser) Extensions() []string {
|
||||
|
||||
// Render implements markup.Parser
|
||||
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
|
||||
return RenderRaw(rawBytes, urlPrefix, isWiki)
|
||||
return render(rawBytes, urlPrefix, metas, isWiki)
|
||||
}
|
||||
|
||||
// Render renders Markdown to HTML with all specific handling stuff.
|
||||
@@ -120,6 +119,11 @@ func Render(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
return markup.Render("a.md", rawBytes, urlPrefix, metas)
|
||||
}
|
||||
|
||||
// RenderRaw renders Markdown to HTML without handling special links.
|
||||
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
|
||||
return render(body, urlPrefix, map[string]string{}, wikiMarkdown)
|
||||
}
|
||||
|
||||
// RenderString renders Markdown to HTML with special links and returns string type.
|
||||
func RenderString(raw, urlPrefix string, metas map[string]string) string {
|
||||
return markup.RenderString("a.md", raw, urlPrefix, metas)
|
||||
|
||||
@@ -47,7 +47,7 @@ func CreateRepository(doer, u *models.User, opts models.CreateRepoOptions) (_ *m
|
||||
// No need for init mirror.
|
||||
if !opts.IsMirror {
|
||||
repoPath := models.RepoPath(u.Name, repo.Name)
|
||||
if err = initRepository(ctx, repoPath, u, repo, opts); err != nil {
|
||||
if err = initRepository(ctx, repoPath, doer, repo, opts); err != nil {
|
||||
if err2 := os.RemoveAll(repoPath); err2 != nil {
|
||||
log.Error("initRepository: %v", err)
|
||||
return fmt.Errorf(
|
||||
|
||||
@@ -107,10 +107,11 @@ func init() {
|
||||
|
||||
// VirtualStore represents a virtual session store implementation.
|
||||
type VirtualStore struct {
|
||||
p *VirtualSessionProvider
|
||||
sid string
|
||||
lock sync.RWMutex
|
||||
data map[interface{}]interface{}
|
||||
p *VirtualSessionProvider
|
||||
sid string
|
||||
lock sync.RWMutex
|
||||
data map[interface{}]interface{}
|
||||
released bool
|
||||
}
|
||||
|
||||
// NewVirtualStore creates and returns a virtual session store.
|
||||
@@ -164,7 +165,7 @@ func (s *VirtualStore) Release() error {
|
||||
// Now ensure that we don't exist!
|
||||
realProvider := s.p.provider
|
||||
|
||||
if realProvider.Exist(s.sid) {
|
||||
if !s.released && realProvider.Exist(s.sid) {
|
||||
// This is an error!
|
||||
return fmt.Errorf("new sid '%s' already exists", s.sid)
|
||||
}
|
||||
@@ -172,12 +173,19 @@ func (s *VirtualStore) Release() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := realStore.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
for key, value := range s.data {
|
||||
if err := realStore.Set(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return realStore.Release()
|
||||
err = realStore.Release()
|
||||
if err == nil {
|
||||
s.released = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, db
|
||||
|
||||
// ParseMSSQLHostPort splits the host into host and port
|
||||
func ParseMSSQLHostPort(info string) (string, string) {
|
||||
host, port := "127.0.0.1", "1433"
|
||||
host, port := "127.0.0.1", "0"
|
||||
if strings.Contains(info, ":") {
|
||||
host = strings.Split(info, ":")[0]
|
||||
port = strings.Split(info, ":")[1]
|
||||
|
||||
@@ -256,12 +256,14 @@ var (
|
||||
|
||||
// Markdown settings
|
||||
Markdown = struct {
|
||||
EnableHardLineBreak bool
|
||||
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
|
||||
FileExtensions []string
|
||||
EnableHardLineBreakInComments bool
|
||||
EnableHardLineBreakInDocuments bool
|
||||
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
|
||||
FileExtensions []string
|
||||
}{
|
||||
EnableHardLineBreak: true,
|
||||
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
|
||||
EnableHardLineBreakInComments: true,
|
||||
EnableHardLineBreakInDocuments: false,
|
||||
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
|
||||
}
|
||||
|
||||
// Admin settings
|
||||
@@ -728,6 +730,8 @@ func NewContext() {
|
||||
for _, key := range minimumKeySizes {
|
||||
if key.MustInt() != -1 {
|
||||
SSH.MinimumKeySizes[strings.ToLower(key.Name())] = key.MustInt()
|
||||
} else {
|
||||
delete(SSH.MinimumKeySizes, strings.ToLower(key.Name()))
|
||||
}
|
||||
}
|
||||
SSH.AuthorizedKeysBackup = sec.Key("SSH_AUTHORIZED_KEYS_BACKUP").MustBool(true)
|
||||
@@ -999,15 +1003,15 @@ func NewContext() {
|
||||
if len(Langs) == 0 {
|
||||
Langs = []string{
|
||||
"en-US", "zh-CN", "zh-HK", "zh-TW", "de-DE", "fr-FR", "nl-NL", "lv-LV",
|
||||
"ru-RU", "uk-UA", "ja-JP", "es-ES", "pt-BR", "pl-PL", "bg-BG", "it-IT",
|
||||
"fi-FI", "tr-TR", "cs-CZ", "sr-SP", "sv-SE", "ko-KR"}
|
||||
"ru-RU", "uk-UA", "ja-JP", "es-ES", "pt-BR", "pt-PT", "pl-PL", "bg-BG",
|
||||
"it-IT", "fi-FI", "tr-TR", "cs-CZ", "sr-SP", "sv-SE", "ko-KR"}
|
||||
}
|
||||
Names = Cfg.Section("i18n").Key("NAMES").Strings(",")
|
||||
if len(Names) == 0 {
|
||||
Names = []string{"English", "简体中文", "繁體中文(香港)", "繁體中文(台灣)", "Deutsch",
|
||||
"français", "Nederlands", "latviešu", "русский", "Українська", "日本語",
|
||||
"español", "português do Brasil", "polski", "български", "italiano",
|
||||
"suomi", "Türkçe", "čeština", "српски", "svenska", "한국어"}
|
||||
"español", "português do Brasil", "Português de Portugal", "polski", "български",
|
||||
"italiano", "suomi", "Türkçe", "čeština", "српски", "svenska", "한국어"}
|
||||
}
|
||||
dateLangs = Cfg.Section("i18n.datelang").KeysHash()
|
||||
|
||||
@@ -1069,7 +1073,7 @@ func loadInternalToken(sec *ini.Section) string {
|
||||
return token
|
||||
}
|
||||
|
||||
return string(buf)
|
||||
return strings.TrimSpace(string(buf))
|
||||
default:
|
||||
log.Fatal("Unsupported URI-Scheme %q (INTERNAL_TOKEN_URI = %q)", tempURI.Scheme, uri)
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ type CreatePullRequestOption struct {
|
||||
type EditPullRequestOption struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
Base string `json:"base"`
|
||||
Assignee string `json:"assignee"`
|
||||
Assignees []string `json:"assignees"`
|
||||
Milestone int64 `json:"milestone"`
|
||||
|
||||
@@ -48,18 +48,6 @@ func JSONRenderer() macaron.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
// JSRenderer implements the macaron handler for serving JS templates.
|
||||
func JSRenderer() macaron.Handler {
|
||||
return macaron.Renderer(macaron.RenderOptions{
|
||||
Funcs: NewFuncMap(),
|
||||
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||
AppendDirectories: []string{
|
||||
path.Join(setting.CustomPath, "templates"),
|
||||
},
|
||||
HTMLContentType: "application/javascript",
|
||||
})
|
||||
}
|
||||
|
||||
// Mailer provides the templates required for sending notification mails.
|
||||
func Mailer() (*texttmpl.Template, *template.Template) {
|
||||
for _, funcs := range NewTextFuncMap() {
|
||||
|
||||
@@ -132,15 +132,6 @@ func JSONRenderer() macaron.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
// JSRenderer implements the macaron handler for serving JS templates.
|
||||
func JSRenderer() macaron.Handler {
|
||||
return macaron.Renderer(macaron.RenderOptions{
|
||||
Funcs: NewFuncMap(),
|
||||
TemplateFileSystem: NewTemplateFileSystem(),
|
||||
HTMLContentType: "application/javascript",
|
||||
})
|
||||
}
|
||||
|
||||
// Mailer provides the templates required for sending notification mails.
|
||||
func Mailer() (*texttmpl.Template, *template.Template) {
|
||||
for _, funcs := range NewTextFuncMap() {
|
||||
|
||||
@@ -75,6 +75,11 @@ func (ts TimeStamp) FormatShort() string {
|
||||
return ts.Format("Jan 02, 2006")
|
||||
}
|
||||
|
||||
// FormatDate formats a date in YYYY-MM-DD server time zone
|
||||
func (ts TimeStamp) FormatDate() string {
|
||||
return time.Unix(int64(ts), 0).String()[:10]
|
||||
}
|
||||
|
||||
// IsZero is zero time
|
||||
func (ts TimeStamp) IsZero() bool {
|
||||
return ts.AsTimeInLocation(time.Local).IsZero()
|
||||
|
||||
@@ -25,6 +25,7 @@ Damaris Padieu <damizx AT hotmail DOT fr>
|
||||
Daniel Speichert <daniel AT speichert DOT pl>
|
||||
David Yzaguirre <dvdyzag AT gmail DOT com>
|
||||
Dmitriy Nogay <me AT catwhocode DOT ga>
|
||||
Emanuel Angelo <emanuel DOT angelo AT gmail DOT com>
|
||||
Enrico Testori hypertesto AT gmail DOT com
|
||||
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
|
||||
Gabriel Dugny <gabriel DOT dugny AT gmail DOT com>
|
||||
|
||||
@@ -1647,6 +1647,7 @@ diff.review.placeholder = Review comment
|
||||
diff.review.comment = Comment
|
||||
diff.review.approve = Approve
|
||||
diff.review.reject = Request changes
|
||||
diff.committed_by = committed by
|
||||
|
||||
releases.desc = Track project versions and downloads.
|
||||
release.releases = Releases
|
||||
@@ -1872,7 +1873,6 @@ dashboard.resync_all_sshkeys.desc = (Not needed for the built-in SSH server.)
|
||||
dashboard.resync_all_hooks = Resynchronize pre-receive, update and post-receive hooks of all repositories.
|
||||
dashboard.reinit_missing_repos = Reinitialize all missing Git repositories for which records exist
|
||||
dashboard.sync_external_users = Synchronize external user data
|
||||
dashboard.git_fsck = Execute health checks on all repositories
|
||||
dashboard.server_uptime = Server Uptime
|
||||
dashboard.current_goroutine = Current Goroutines
|
||||
dashboard.current_memory_usage = Current Memory Usage
|
||||
|
||||
22
package-lock.json
generated
22
package-lock.json
generated
@@ -14852,6 +14852,28 @@
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
|
||||
"integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
|
||||
},
|
||||
"workbox-core": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.3.tgz",
|
||||
"integrity": "sha512-TFSIPxxciX9sFaj0FDiohBeIKpwMcCyNduydi9i3LChItcndDS6TJpErxybv8aBWeCMraXt33TWtF6kKuIObNw=="
|
||||
},
|
||||
"workbox-routing": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.3.tgz",
|
||||
"integrity": "sha512-F+sAp9Iy3lVl3BEG+pzXWVq4AftzjiFpHDaZ4Kf4vLoBoKQE0hIHet4zE5DpHqYdyw+Udhp4wrfHamX6PN6z1Q==",
|
||||
"requires": {
|
||||
"workbox-core": "^5.1.3"
|
||||
}
|
||||
},
|
||||
"workbox-strategies": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.3.tgz",
|
||||
"integrity": "sha512-wiXHfmOKnWABeIVW+/ye0e00+2CcS5y7SIj2f9zcdy2ZLEbcOf7B+yOl5OrWpBGlTUwRjIYhV++ZqiKm3Dc+8w==",
|
||||
"requires": {
|
||||
"workbox-core": "^5.1.3",
|
||||
"workbox-routing": "^5.1.3"
|
||||
}
|
||||
},
|
||||
"worker-farm": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
"webpack": "4.43.0",
|
||||
"webpack-cli": "3.3.11",
|
||||
"webpack-fix-style-only-entries": "0.4.0",
|
||||
"workbox-routing": "5.1.3",
|
||||
"workbox-strategies": "5.1.3",
|
||||
"worker-loader": "2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -48,10 +48,12 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
|
||||
}
|
||||
|
||||
switch form.Mode {
|
||||
case "comment":
|
||||
fallthrough
|
||||
case "gfm":
|
||||
md := []byte(form.Text)
|
||||
urlPrefix := form.Context
|
||||
var meta map[string]string
|
||||
meta := map[string]string{}
|
||||
if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
|
||||
// check if urlPrefix is already set to a URL
|
||||
linkRegex, _ := xurls.StrictMatchingScheme("https?://")
|
||||
@@ -61,7 +63,15 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
|
||||
}
|
||||
}
|
||||
if ctx.Repo != nil && ctx.Repo.Repository != nil {
|
||||
meta = ctx.Repo.Repository.ComposeMetas()
|
||||
// "gfm" = Github Flavored Markdown - set this to render as a document
|
||||
if form.Mode == "gfm" {
|
||||
meta = ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
} else {
|
||||
meta = ctx.Repo.Repository.ComposeMetas()
|
||||
}
|
||||
}
|
||||
if form.Mode == "gfm" {
|
||||
meta["mode"] = "document"
|
||||
}
|
||||
if form.Wiki {
|
||||
_, err := ctx.Write([]byte(markdown.RenderWiki(md, urlPrefix, meta)))
|
||||
|
||||
@@ -94,7 +94,7 @@ Here are some links to the most important topics. You can find the full list of
|
||||
<p><strong>Wine Staging</strong> on website <a href="http://wine-staging.com" rel="nofollow">wine-staging.com</a>.</p>
|
||||
<h2 id="user-content-quick-links">Quick Links</h2>
|
||||
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
|
||||
<p><a href="` + AppSubURL + `wiki/Configuration" rel="nofollow">Configuration</a><br/>
|
||||
<p><a href="` + AppSubURL + `wiki/Configuration" rel="nofollow">Configuration</a>
|
||||
<a href="` + AppSubURL + `wiki/raw/images/icon-bug.png" rel="nofollow"><img src="` + AppSubURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
|
||||
`,
|
||||
// Guard wiki sidebar: special syntax
|
||||
|
||||
@@ -7,6 +7,7 @@ package repo
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -198,6 +199,16 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
|
||||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/FileResponse"
|
||||
// "403":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
// "$ref": "#/responses/error"
|
||||
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
|
||||
}
|
||||
|
||||
if apiOpts.BranchName == "" {
|
||||
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
@@ -235,7 +246,7 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
|
||||
}
|
||||
|
||||
if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateFile", err)
|
||||
handleCreateOrUpdateFileError(ctx, err)
|
||||
} else {
|
||||
ctx.JSON(http.StatusCreated, fileResponse)
|
||||
}
|
||||
@@ -274,6 +285,16 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/FileResponse"
|
||||
// "403":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
// "$ref": "#/responses/error"
|
||||
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
|
||||
}
|
||||
|
||||
if apiOpts.BranchName == "" {
|
||||
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
@@ -313,12 +334,30 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
|
||||
}
|
||||
|
||||
if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
|
||||
handleCreateOrUpdateFileError(ctx, err)
|
||||
} else {
|
||||
ctx.JSON(http.StatusOK, fileResponse)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
|
||||
if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
|
||||
ctx.Error(http.StatusForbidden, "Access", err)
|
||||
return
|
||||
}
|
||||
if models.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
|
||||
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
|
||||
return
|
||||
}
|
||||
if git.IsErrBranchNotExist(err) {
|
||||
ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
|
||||
}
|
||||
|
||||
// Called from both CreateFile or UpdateFile to handle both
|
||||
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
|
||||
if !canWriteFiles(ctx.Repo) {
|
||||
|
||||
@@ -691,7 +691,7 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
|
||||
var deadline time.Time
|
||||
if form.Deadline != nil && !form.Deadline.IsZero() {
|
||||
deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
|
||||
23, 59, 59, 0, form.Deadline.Location())
|
||||
23, 59, 59, 0, time.Local)
|
||||
deadlineUnix = timeutil.TimeStamp(deadline.Unix())
|
||||
}
|
||||
|
||||
|
||||
@@ -382,6 +382,8 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
||||
// "$ref": "#/responses/PullRequest"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "409":
|
||||
// "$ref": "#/responses/error"
|
||||
// "412":
|
||||
// "$ref": "#/responses/error"
|
||||
// "422":
|
||||
@@ -508,6 +510,30 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
||||
notification.NotifyIssueChangeStatus(ctx.User, issue, statusChangeComment, issue.IsClosed)
|
||||
}
|
||||
|
||||
// change pull target branch
|
||||
if len(form.Base) != 0 && form.Base != pr.BaseBranch {
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(form.Base) {
|
||||
ctx.Error(http.StatusNotFound, "NewBaseBranchNotExist", fmt.Errorf("new base '%s' not exist", form.Base))
|
||||
return
|
||||
}
|
||||
if err := pull_service.ChangeTargetBranch(pr, ctx.User, form.Base); err != nil {
|
||||
if models.IsErrPullRequestAlreadyExists(err) {
|
||||
ctx.Error(http.StatusConflict, "IsErrPullRequestAlreadyExists", err)
|
||||
return
|
||||
} else if models.IsErrIssueIsClosed(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err)
|
||||
return
|
||||
} else if models.IsErrPullRequestHasMerged(err) {
|
||||
ctx.Error(http.StatusConflict, "IsErrPullRequestHasMerged", err)
|
||||
return
|
||||
} else {
|
||||
ctx.InternalServerError(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
notification.NotifyPullRequestChangeTargetBranch(ctx.User, pr, form.Base)
|
||||
}
|
||||
|
||||
// Refetch from database
|
||||
pr, err = models.GetPullRequestByIndex(ctx.Repo.Repository.ID, pr.Index)
|
||||
if err != nil {
|
||||
|
||||
@@ -78,9 +78,9 @@ func Search(ctx *context.APIContext) {
|
||||
// in: query
|
||||
// description: include private repositories this user has access to (defaults to true)
|
||||
// type: boolean
|
||||
// - name: onlyPrivate
|
||||
// - name: is_private
|
||||
// in: query
|
||||
// description: only include private repositories this user has access to (defaults to false)
|
||||
// description: show only pubic, private or all repositories (defaults to all)
|
||||
// type: boolean
|
||||
// - name: template
|
||||
// in: query
|
||||
@@ -133,7 +133,6 @@ func Search(ctx *context.APIContext) {
|
||||
TopicOnly: ctx.QueryBool("topic"),
|
||||
Collaborate: util.OptionalBoolNone,
|
||||
Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")),
|
||||
OnlyPrivate: ctx.IsSigned && ctx.QueryBool("onlyPrivate"),
|
||||
Template: util.OptionalBoolNone,
|
||||
StarredByID: ctx.QueryInt64("starredBy"),
|
||||
IncludeDescription: ctx.QueryBool("includeDesc"),
|
||||
@@ -169,6 +168,10 @@ func Search(ctx *context.APIContext) {
|
||||
opts.Archived = util.OptionalBoolOf(ctx.QueryBool("archived"))
|
||||
}
|
||||
|
||||
if ctx.Query("is_private") != "" {
|
||||
opts.IsPrivate = util.OptionalBoolOf(ctx.QueryBool("is_private"))
|
||||
}
|
||||
|
||||
var sortMode = ctx.Query("sort")
|
||||
if len(sortMode) > 0 {
|
||||
var sortOrder = ctx.Query("order")
|
||||
|
||||
@@ -144,6 +144,8 @@ func CreateGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption) {
|
||||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/GPGKey"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
// "$ref": "#/responses/validationError"
|
||||
|
||||
@@ -169,6 +171,8 @@ func DeleteGPGKey(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
if err := models.DeleteGPGKey(ctx.User, ctx.ParamsInt64(":id")); err != nil {
|
||||
if models.IsErrGPGKeyAccessDenied(err) {
|
||||
@@ -186,9 +190,13 @@ func DeleteGPGKey(ctx *context.APIContext) {
|
||||
func HandleAddGPGKeyError(ctx *context.APIContext, err error) {
|
||||
switch {
|
||||
case models.IsErrGPGKeyAccessDenied(err):
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", "You do not have access to this GPG key")
|
||||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyAccessDenied", "You do not have access to this GPG key")
|
||||
case models.IsErrGPGKeyIDAlreadyUsed(err):
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", "A key with the same id already exists")
|
||||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyIDAlreadyUsed", "A key with the same id already exists")
|
||||
case models.IsErrGPGKeyParsing(err):
|
||||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyParsing", err)
|
||||
case models.IsErrGPGNoEmailFound(err):
|
||||
ctx.Error(http.StatusNotFound, "GPGNoEmailFound", err)
|
||||
default:
|
||||
ctx.Error(http.StatusInternalServerError, "AddGPGKey", err)
|
||||
}
|
||||
|
||||
@@ -194,7 +194,6 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN
|
||||
if opts.Page <= 1 {
|
||||
opts.Page = 1
|
||||
}
|
||||
opts.Actor = ctx.User
|
||||
|
||||
var (
|
||||
users []*models.User
|
||||
@@ -252,6 +251,7 @@ func ExploreUsers(ctx *context.Context) {
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
RenderUserSearch(ctx, &models.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Type: models.UserTypeIndividual,
|
||||
ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum},
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
@@ -272,6 +272,7 @@ func ExploreOrganizations(ctx *context.Context) {
|
||||
}
|
||||
|
||||
RenderUserSearch(ctx, &models.SearchUserOptions{
|
||||
Actor: ctx.User,
|
||||
Type: models.UserTypeOrganization,
|
||||
ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum},
|
||||
Visible: visibleTypes,
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
)
|
||||
@@ -135,6 +136,16 @@ func HTTP(ctx *context.Context) {
|
||||
environ []string
|
||||
)
|
||||
|
||||
// don't allow anonymous pulls if organization is not public
|
||||
if isPublicPull {
|
||||
if err := repo.GetOwner(); err != nil {
|
||||
ctx.ServerError("GetOwner", err)
|
||||
return
|
||||
}
|
||||
|
||||
askAuth = askAuth || (repo.Owner.Visibility != structs.VisibleTypePublic)
|
||||
}
|
||||
|
||||
// check access
|
||||
if askAuth {
|
||||
authUsername = ctx.Req.Header.Get(setting.ReverseProxyAuthUser)
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
"code.gitea.io/gitea/routers/utils"
|
||||
@@ -75,7 +76,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
ctx.Repo.GitRepo = nil
|
||||
}
|
||||
if err := repo_service.ChangeRepositoryName(ctx.Repo.Owner, repo, newRepoName); err != nil {
|
||||
if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil {
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
switch {
|
||||
case models.IsErrRepoAlreadyExist(err):
|
||||
@@ -379,6 +380,14 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
||||
return
|
||||
}
|
||||
|
||||
if newOwner.Type == models.UserTypeOrganization {
|
||||
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !ctx.User.IsUserPartOfOrg(newOwner.ID) {
|
||||
// The user shouldn't know about this organization
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), tplSettingsOptions, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Close the GitRepo if open
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
|
||||
@@ -319,7 +319,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||
if markupType := markup.Type(readmeFile.name); markupType != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = string(markupType)
|
||||
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeMetas()))
|
||||
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeDocumentMetas()))
|
||||
} else {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
ctx.Data["FileContent"] = strings.Replace(
|
||||
@@ -459,7 +459,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
if markupType := markup.Type(blob.Name()); markupType != "" {
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = markupType
|
||||
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
||||
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
|
||||
} else if readmeExist {
|
||||
ctx.Data["IsRenderedHTML"] = true
|
||||
ctx.Data["FileContent"] = strings.Replace(
|
||||
@@ -538,7 +538,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||
buf = append(buf, d...)
|
||||
ctx.Data["IsMarkup"] = true
|
||||
ctx.Data["MarkupType"] = markupType
|
||||
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
||||
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
metas := ctx.Repo.Repository.ComposeMetas()
|
||||
metas := ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
ctx.Data["content"] = markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
|
||||
ctx.Data["sidebarPresent"] = sidebarContent != nil
|
||||
ctx.Data["sidebarContent"] = markdown.RenderWiki(sidebarContent, ctx.Repo.RepoLink, metas)
|
||||
|
||||
@@ -1048,10 +1048,6 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
ctx.HTML(200, "pwa/manifest_json")
|
||||
})
|
||||
|
||||
m.Get("/serviceworker.js", templates.JSRenderer(), func(ctx *context.Context) {
|
||||
ctx.HTML(200, "pwa/serviceworker_js")
|
||||
})
|
||||
|
||||
// prometheus metrics endpoint
|
||||
if setting.Metrics.Enabled {
|
||||
c := metrics.NewCollector()
|
||||
|
||||
@@ -1489,6 +1489,7 @@ func ResetPasswdPost(ctx *context.Context) {
|
||||
func MustChangePassword(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/settings/change_password"
|
||||
ctx.Data["MustChangePassword"] = true
|
||||
ctx.HTML(200, tplMustChangePassword)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{{.i18n.Tr "admin.dashboard.operations"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<form method="post" action="{{.AppSubUrl}}/admin">
|
||||
<form method="post" action="{{AppSubUrl}}/admin">
|
||||
{{.CsrfTokenHtml}}
|
||||
<table class="ui very basic table">
|
||||
<tbody>
|
||||
@@ -53,8 +53,8 @@
|
||||
<td><button type="submit" class="ui green button" name="op" value="sync_external_users">{{svg "octicon-triangle-right" 16}} {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.git_fsck"}}</td>
|
||||
<td><button type="submit" class="ui green button" name="op" value="git_fsck">{{svg "octicon-triangle-right" 16}} {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
|
||||
<td>{{.i18n.Tr "admin.dashboard.repo_health_check"}}</td>
|
||||
<td><button type="submit" class="ui green button" name="op" value="repo_health_check">{{svg "octicon-triangle-right" 16}} {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_generated_repository_avatars"}}</td>
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
|
||||
{{else if eq .HookType "feishu"}}
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/feishu.png">
|
||||
{{else if eq .HookType "matrix"}}
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/matrix.svg">
|
||||
{{end}}
|
||||
</div>
|
||||
</h4>
|
||||
@@ -38,6 +40,7 @@
|
||||
{{template "repo/settings/webhook/telegram" .}}
|
||||
{{template "repo/settings/webhook/msteams" .}}
|
||||
{{template "repo/settings/webhook/feishu" .}}
|
||||
{{template "repo/settings/webhook/matrix" .}}
|
||||
</div>
|
||||
|
||||
{{template "repo/settings/webhook/history" .}}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{{.i18n.Tr "admin.monitor.cron"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<form method="post" action="{{.AppSubUrl}}/admin">
|
||||
<form method="post" action="{{AppSubUrl}}/admin">
|
||||
{{.CsrfTokenHtml}}
|
||||
<table class="ui very basic striped table">
|
||||
<thead>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{{.i18n.Tr "admin.notices.system_notice_list"}} ({{.i18n.Tr "admin.total" .Total}})
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<table class="ui very basic select selectable table">
|
||||
<table id="notice-table" class="ui very basic select selectable table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
@@ -28,9 +28,9 @@
|
||||
</td>
|
||||
<td>{{.ID}}</td>
|
||||
<td>{{$.i18n.Tr .TrStr}}</td>
|
||||
<td>{{SubStr .Description 0 120}}...</td>
|
||||
<td><span class="poping up" data-content="{{.CreatedUnix.AsTime}}" data-variation="inverted tiny">{{.CreatedUnix.FormatShort}}</span></td>
|
||||
<td><a href="#"><i class="browser icon view-detail" data-content="{{.Description}}"></i></a></td>
|
||||
<td class="view-detail"><span class="notice-description text truncate">{{.Description}}</span></td>
|
||||
<td><span class="notice-created-time poping up" data-content="{{.CreatedUnix.AsTime}}" data-variation="inverted tiny">{{.CreatedUnix.FormatShort}}</span></td>
|
||||
<td><a href="#"><i class="browser icon view-detail"></i></a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
@@ -73,10 +73,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui modal" id="detail-modal">
|
||||
<div class="ui modal admin" id="detail-modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">{{$.i18n.Tr "admin.notices.view_detail_header"}}</div>
|
||||
<div class="content">
|
||||
<div class="sub header"></div>
|
||||
<pre></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,30 +6,6 @@
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>{{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}} </title>
|
||||
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
|
||||
{{if UseServiceWorker}}
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js').then(function(registration) {
|
||||
// Registration was successful
|
||||
console.info('ServiceWorker registration successful with scope: ', registration.scope);
|
||||
}, function(err) {
|
||||
// registration failed :(
|
||||
console.info('ServiceWorker registration failed: ', err);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{{else}}
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.getRegistrations().then(function(registrations) {
|
||||
registrations.forEach(function(registration) {
|
||||
registration.unregister();
|
||||
console.info('ServiceWorker unregistered');
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
<meta name="theme-color" content="{{ThemeColorMetaTag}}">
|
||||
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}" />
|
||||
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}" />
|
||||
@@ -84,8 +60,10 @@
|
||||
</script>
|
||||
<script>
|
||||
window.config = {
|
||||
AppVer: '{{AppVer}}',
|
||||
AppSubUrl: '{{AppSubUrl}}',
|
||||
StaticUrlPrefix: '{{StaticUrlPrefix}}',
|
||||
UseServiceWorker: {{UseServiceWorker}},
|
||||
csrf: '{{.CsrfToken}}',
|
||||
HighlightJS: {{if .RequireHighlightJS}}true{{else}}false{{end}},
|
||||
Minicolors: {{if .RequireMinicolors}}true{{else}}false{{end}},
|
||||
@@ -114,8 +92,6 @@
|
||||
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/gitea-safari.svg" color="#609926">
|
||||
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
|
||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
|
||||
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
|
||||
{{if .RequireSimpleMDE}}
|
||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
|
||||
{{end}}
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .IsSigned}}
|
||||
{{if and .IsSigned .MustChangePassword}}
|
||||
{{/* No links */}}
|
||||
{{else if .IsSigned}}
|
||||
<a class="item {{if .PageIsDashboard}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "dashboard"}}</a>
|
||||
{{if not .UnitIssuesGlobalDisabled}}
|
||||
<a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
|
||||
@@ -40,7 +42,30 @@
|
||||
</div>
|
||||
*/}}
|
||||
|
||||
{{if .IsSigned}}
|
||||
|
||||
{{if and .IsSigned .MustChangePassword}}
|
||||
<div class="right stackable menu">
|
||||
<div class="ui dropdown jump item poping up" tabindex="-1" data-content="{{.i18n.Tr "user_profile_and_more"}}" data-variation="tiny inverted">
|
||||
<span class="text">
|
||||
<img class="ui tiny avatar image" width="24" height="24" src="{{.SignedUser.RelAvatarLink}}">
|
||||
<span class="sr-only">{{.i18n.Tr "user_profile_and_more"}}</span>
|
||||
<span class="mobile-only">{{.SignedUser.Name}}</span>
|
||||
<span class="fitted not-mobile" tabindex="-1">{{svg "octicon-triangle-down" 16}}</span>
|
||||
</span>
|
||||
<div class="menu user-menu" tabindex="-1">
|
||||
<div class="ui header">
|
||||
{{.i18n.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
<a class="item link-action" href data-url="{{AppSubUrl}}/user/logout" data-redirect="{{AppSubUrl}}/">
|
||||
{{svg "octicon-sign-out" 16}}
|
||||
{{.i18n.Tr "sign_out"}}<!-- Sign Out -->
|
||||
</a>
|
||||
</div><!-- end content avatar menu -->
|
||||
</div><!-- end dropdown avatar menu -->
|
||||
</div>
|
||||
{{else if .IsSigned}}
|
||||
<div class="right stackable menu">
|
||||
<a href="{{AppSubUrl}}/notifications" class="item poping up" data-content='{{.i18n.Tr "notifications"}}' data-variation="tiny inverted">
|
||||
<span class="text">
|
||||
@@ -121,9 +146,7 @@
|
||||
</div><!-- end content avatar menu -->
|
||||
</div><!-- end dropdown avatar menu -->
|
||||
</div><!-- end signed user right menu -->
|
||||
|
||||
{{else}}
|
||||
|
||||
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a>
|
||||
<div class="right stackable menu">
|
||||
{{if .ShowRegistrationButton}}
|
||||
@@ -135,6 +158,5 @@
|
||||
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}}
|
||||
</a>
|
||||
</div><!-- end anonymous right menu -->
|
||||
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
|
||||
{{else if eq .HookType "feishu"}}
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/feishu.png">
|
||||
{{else if eq .HookType "matrix"}}
|
||||
<img class="img-13" src="{{StaticUrlPrefix}}/img/matrix.svg">
|
||||
{{end}}
|
||||
</div>
|
||||
</h4>
|
||||
@@ -37,6 +39,7 @@
|
||||
{{template "repo/settings/webhook/telegram" .}}
|
||||
{{template "repo/settings/webhook/msteams" .}}
|
||||
{{template "repo/settings/webhook/feishu" .}}
|
||||
{{template "repo/settings/webhook/matrix" .}}
|
||||
</div>
|
||||
|
||||
{{template "repo/settings/webhook/history" .}}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
var STATIC_CACHE = 'static-cache-v1';
|
||||
var urlsToCache = [
|
||||
// js
|
||||
'{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/clipboard.js',
|
||||
'{{StaticUrlPrefix}}/js/gitgraph.js',
|
||||
'{{StaticUrlPrefix}}/js/highlight.js',
|
||||
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/swagger.js?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/js/dropzone.js',
|
||||
'{{StaticUrlPrefix}}/js/datetimepicker.js',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js',
|
||||
|
||||
// css
|
||||
'{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/css/swagger.css?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/css/dropzone.css',
|
||||
'{{StaticUrlPrefix}}/css/datetimepicker.css',
|
||||
'{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}',
|
||||
'{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css',
|
||||
'{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css',
|
||||
{{if .IsSigned }}
|
||||
{{ if ne .SignedUser.Theme "gitea" }}
|
||||
'{{StaticUrlPrefix}}/css/theme-{{.SignedUser.Theme}}.css?v={{MD5 AppVer}}',
|
||||
{{end}}
|
||||
{{else if ne DefaultTheme "gitea"}}
|
||||
'{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css?v={{MD5 AppVer}}',
|
||||
{{end}}
|
||||
|
||||
// img
|
||||
'{{StaticUrlPrefix}}/img/gitea-sm.png',
|
||||
'{{StaticUrlPrefix}}/img/gitea-lg.png',
|
||||
|
||||
// svg
|
||||
'{{StaticUrlPrefix}}/img/svg/icons.svg',
|
||||
|
||||
// fonts
|
||||
'{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2',
|
||||
'{{StaticUrlPrefix}}/vendor/assets/roboto-fonts/roboto-v20-latin-ext_cyrillic-ext_latin_greek_vietnamese_cyrillic_greek-ext-regular.woff2',
|
||||
'{{StaticUrlPrefix}}/vendor/assets/roboto-fonts/roboto-v20-latin-ext_cyrillic-ext_latin_greek_vietnamese_cyrillic_greek-ext-italic.woff2',
|
||||
'{{StaticUrlPrefix}}/vendor/assets/roboto-fonts/roboto-v20-latin-ext_cyrillic-ext_latin_greek_vietnamese_cyrillic_greek-ext-700.woff2',
|
||||
'{{StaticUrlPrefix}}/vendor/assets/roboto-fonts/roboto-v20-latin-ext_cyrillic-ext_latin_greek_vietnamese_cyrillic_greek-ext-700italic.woff2',
|
||||
|
||||
// monaco
|
||||
'{{StaticUrlPrefix}}/css/monaco.css',
|
||||
'{{StaticUrlPrefix}}/fonts/codicon.ttf',
|
||||
'{{StaticUrlPrefix}}/js/monaco-css.worker.js',
|
||||
'{{StaticUrlPrefix}}/js/monaco-editor.worker.js',
|
||||
'{{StaticUrlPrefix}}/js/monaco-html.worker.js',
|
||||
'{{StaticUrlPrefix}}/js/monaco-json.worker.js',
|
||||
'{{StaticUrlPrefix}}/js/monaco.js',
|
||||
'{{StaticUrlPrefix}}/js/monaco-ts.worker.js'
|
||||
];
|
||||
|
||||
self.addEventListener('install', function (event) {
|
||||
// Perform install steps
|
||||
event.waitUntil(
|
||||
caches.open(STATIC_CACHE)
|
||||
.then(function (cache) {
|
||||
return cache.addAll(urlsToCache);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function (event) {
|
||||
event.respondWith(
|
||||
caches.match(event.request)
|
||||
.then(function (response) {
|
||||
// Cache hit - return response
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
return fetch(event.request);
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<div class="ui attached info segment {{$class}}">
|
||||
<div class="ui stackable grid">
|
||||
<div class="ten wide column">
|
||||
<div class="nine wide column">
|
||||
{{if .Author}}
|
||||
<img class="ui avatar image" src="{{.Author.RelAvatarLink}}" />
|
||||
{{if .Author.FullName}}
|
||||
@@ -43,19 +43,22 @@
|
||||
<img class="ui avatar image" src="{{AvatarLink .Commit.Author.Email}}" />
|
||||
<strong>{{.Commit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
{{if or (ne .Commit.Committer.Name .Commit.Author.Name) (ne .Commit.Committer.Email .Commit.Author.Email)}}
|
||||
<span> </span>
|
||||
{{if ne .Verification.CommittingUser.ID 0}}
|
||||
<img class="ui avatar image" src="{{.Verification.CommittingUser.RelAvatarLink}}" />
|
||||
<a href="{{.Verification.CommittingUser.HomeLink}}"><strong>{{.Commit.Committer.Name}}</strong> <{{.Commit.Committer.Email}}></a>
|
||||
{{else}}
|
||||
<img class="ui avatar image" src="{{AvatarLink .Commit.Committer.Email}}" />
|
||||
<strong>{{.Commit.Committer.Name}}</strong>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<span class="text grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span>
|
||||
{{if or (ne .Commit.Committer.Name .Commit.Author.Name) (ne .Commit.Committer.Email .Commit.Author.Email)}}
|
||||
<div class="committed-by">
|
||||
<span class="text grey">{{svg "octicon-git-commit" 16}}{{.i18n.Tr "repo.diff.committed_by"}}</span>
|
||||
{{if ne .Verification.CommittingUser.ID 0}}
|
||||
<img class="ui avatar image" src="{{.Verification.CommittingUser.RelAvatarLink}}" />
|
||||
<a href="{{.Verification.CommittingUser.HomeLink}}"><strong>{{.Commit.Committer.Name}}</strong> <{{.Commit.Committer.Email}}></a>
|
||||
{{else}}
|
||||
<img class="ui avatar image" src="{{AvatarLink .Commit.Committer.Email}}" />
|
||||
<strong>{{.Commit.Committer.Name}}</strong>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
<div class="six wide right aligned column">
|
||||
<div class="seven wide right aligned column">
|
||||
<div class="ui horizontal list">
|
||||
{{if .Parents}}
|
||||
<div class="item">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{{if $.hidden}}
|
||||
<button class="comment-form-reply ui green labeled icon tiny button"><i class="reply icon"></i> {{$.root.i18n.Tr "repo.diff.comment.reply"}}</button>
|
||||
{{end}}
|
||||
<form class="ui form {{if $.hidden}}hide{{end}} comment-form comment-form-reply" action="{{$.root.Issue.HTMLURL}}/files/reviews/comments" method="post">
|
||||
<form class="ui form {{if $.hidden}}hide comment-form comment-form-reply{{end}}" action="{{$.root.Issue.HTMLURL}}/files/reviews/comments" method="post">
|
||||
{{$.root.CsrfTokenHtml}}
|
||||
<input type="hidden" name="latest_commit_id" value="{{$.root.AfterCommitID}}"/>
|
||||
<input type="hidden" name="side" value="{{if $.Side}}{{$.Side}}{{end}}">
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "diff" true }}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui attached segment">
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff">
|
||||
<a class="active item" data-tab="write">{{svg "octicon-code" 16}} {{if .IsNewFile}}{{.i18n.Tr "repo.editor.new_file"}}{{else}}{{.i18n.Tr "repo.editor.edit_file"}}{{end}}</a>
|
||||
{{if not .IsNewFile}}
|
||||
<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}">{{svg "octicon-eye" 16}} {{.i18n.Tr "preview"}}</a>
|
||||
<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}" data-markdown-mode="gfm">{{svg "octicon-eye" 16}} {{.i18n.Tr "preview"}}</a>
|
||||
<a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | EscapePound}}/{{.TreePath | EscapePound}}" data-context="{{.BranchLink}}">{{svg "octicon-diff" 16}} {{.i18n.Tr "repo.editor.preview_changes"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
{{if not $.Repository.IsArchived}}
|
||||
<div class="ui right actions">
|
||||
{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" .Issue "delete" false "diff" false }}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" .Issue "delete" false "diff" false "IsCommentPoster" $.IsIssuePoster}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</div>
|
||||
{{end}}
|
||||
{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "diff" false }}
|
||||
{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="item context clipboard" data-clipboard-text="{{Printf "%s%s/issues/%d#%s" AppUrl .ctx.Repository.FullName .ctx.Issue.Index .item.HashTag}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
|
||||
{{end}}
|
||||
<div class="item context quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.ID}}">{{.ctx.i18n.Tr "repo.issues.context.quote_reply"}}</div>
|
||||
{{if or .ctx.Permission.IsAdmin .ctx.IsIssuePoster .ctx.HasIssuesOrPullsWritePermission}}
|
||||
{{if or .ctx.Permission.IsAdmin .IsCommentPoster .ctx.HasIssuesOrPullsWritePermission}}
|
||||
<div class="divider"></div>
|
||||
<div class="item context edit-content">{{.ctx.i18n.Tr "repo.issues.context.edit"}}</div>
|
||||
{{if .delete}}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
{{- else}}red{{end}}">{{svg "octicon-git-merge" 32}}</a>
|
||||
<div class="content">
|
||||
{{template "repo/pulls/status" .}}
|
||||
<div class="ui {{if not $.LatestCommitStatus}}top attached header{{else}}attached merge-section segment{{end}}">
|
||||
<div class="ui attached merge-section segment {{if not $.LatestCommitStatus}}no-header{{end}}">
|
||||
{{if .Issue.PullRequest.HasMerged}}
|
||||
<div class="item text purple">
|
||||
{{if .Issue.PullRequest.MergedCommitID}}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
{{range $.PullReviewers}}
|
||||
{{if eq .ReviewerID $ReviewerID }}
|
||||
{{$notReviewed = false }}
|
||||
{{$notReviewed = false }}
|
||||
{{if eq .Type 4 }}
|
||||
{{$checked = true}}
|
||||
{{if or (eq $ReviewerID $.SignedUserID) $.Permission.IsAdmin}}
|
||||
@@ -357,7 +357,7 @@
|
||||
{{if ne .Issue.DeadlineUnix 0}}
|
||||
<p>
|
||||
{{svg "octicon-calendar" 16}}
|
||||
{{.Issue.DeadlineUnix.FormatShort}}
|
||||
{{.Issue.DeadlineUnix.FormatDate}}
|
||||
{{if .Issue.IsOverdue}}
|
||||
<span style="color: red;">{{.i18n.Tr "repo.issues.due_date_overdue"}}</span>
|
||||
{{end}}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<a class="item" data-tab="preview">{{.i18n.Tr "preview"}}</a>
|
||||
</div>
|
||||
<div class="field">
|
||||
<textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/wiki" required>{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea>
|
||||
<textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}" required>{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}">
|
||||
|
||||
@@ -1771,8 +1771,8 @@
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "only include private repositories this user has access to (defaults to false)",
|
||||
"name": "onlyPrivate",
|
||||
"description": "show only pubic, private or all repositories (defaults to all)",
|
||||
"name": "is_private",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
@@ -2746,6 +2746,15 @@
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/FileResponse"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#/responses/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2795,6 +2804,15 @@
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/responses/FileResponse"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#/responses/error"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6575,6 +6593,9 @@
|
||||
"403": {
|
||||
"$ref": "#/responses/forbidden"
|
||||
},
|
||||
"409": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"412": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
@@ -9105,6 +9126,9 @@
|
||||
"201": {
|
||||
"$ref": "#/responses/GPGKey"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#/responses/validationError"
|
||||
}
|
||||
@@ -9165,6 +9189,9 @@
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/forbidden"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11953,6 +11980,10 @@
|
||||
},
|
||||
"x-go-name": "Assignees"
|
||||
},
|
||||
"base": {
|
||||
"type": "string",
|
||||
"x-go-name": "Base"
|
||||
},
|
||||
"body": {
|
||||
"type": "string",
|
||||
"x-go-name": "Body"
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
<div class="ui attached table segment">
|
||||
<ul class="repo-owner-name-list">
|
||||
<li v-for="repo in repos" :class="{'private': repo.private}" v-show="showRepo(repo)">
|
||||
<li v-for="repo in repos" :class="{'private': repo.private}">
|
||||
<a :href="suburl + '/' + repo.full_name">
|
||||
<svg :class="'svg ' + repoClass(repo)" width="16" height="16" aria-hidden="true"><use :xlink:href="'#' + repoClass(repo)" /></svg>
|
||||
<strong class="text truncate item-name">${repo.full_name}</strong>
|
||||
|
||||
180
vendor/github.com/go-enry/go-enry/v2/README.md
generated
vendored
180
vendor/github.com/go-enry/go-enry/v2/README.md
generated
vendored
@@ -1,26 +1,26 @@
|
||||
# go-enry [](https://pkg.go.dev/github.com/go-enry/go-enry/v2) [](https://github.com/go-enry/go-enry/actions?query=workflow%3ATest+branch%3Amaster) [](https://codecov.io/gh/go-enry/go-enry)
|
||||
|
||||
Programming language detector and toolbox to ignore binary or vendored files. *enry*, started as a port to _Go_ of the original [Linguist](https://github.com/github/linguist) _Ruby_ library, that has an improved *2x performance*.
|
||||
Programming language detector and toolbox to ignore binary or vendored files. _enry_, started as a port to _Go_ of the original [Linguist](https://github.com/github/linguist) _Ruby_ library, that has an improved _2x performance_.
|
||||
|
||||
* [CLI](#cli)
|
||||
* [Library](#library)
|
||||
* [Use cases](#use-cases)
|
||||
* [By filename](#by-filename)
|
||||
* [By text](#by-text)
|
||||
* [By file](#by-file)
|
||||
* [Filtering](#filtering-vendoring-binaries-etc)
|
||||
* [Coloring](#language-colors-and-groups)
|
||||
* [Languages](#languages)
|
||||
* [Go](#go)
|
||||
* [Java bindings](#java-bindings)
|
||||
* [Python bindings](#python-bindings)
|
||||
* [Divergences from linguist](#divergences-from-linguist)
|
||||
* [Benchmarks](#benchmarks)
|
||||
* [Why Enry?](#why-enry)
|
||||
* [Development](#development)
|
||||
* [Sync with github/linguist upstream](#sync-with-githublinguist-upstream)
|
||||
* [Misc](#misc)
|
||||
* [License](#license)
|
||||
- [CLI](#cli)
|
||||
- [Library](#library)
|
||||
- [Use cases](#use-cases)
|
||||
- [By filename](#by-filename)
|
||||
- [By text](#by-text)
|
||||
- [By file](#by-file)
|
||||
- [Filtering](#filtering-vendoring-binaries-etc)
|
||||
- [Coloring](#language-colors-and-groups)
|
||||
- [Languages](#languages)
|
||||
- [Go](#go)
|
||||
- [Java bindings](#java-bindings)
|
||||
- [Python bindings](#python-bindings)
|
||||
- [Divergences from linguist](#divergences-from-linguist)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Why Enry?](#why-enry)
|
||||
- [Development](#development)
|
||||
- [Sync with github/linguist upstream](#sync-with-githublinguist-upstream)
|
||||
- [Misc](#misc)
|
||||
- [License](#license)
|
||||
|
||||
# CLI
|
||||
|
||||
@@ -28,50 +28,62 @@ The CLI binary is hosted in a separate repository [go-enry/enry](https://github.
|
||||
|
||||
# Library
|
||||
|
||||
*enry* is also a Go library for guessing a programming language that exposes API through FFI to multiple programming environments.
|
||||
_enry_ is also a Go library for guessing a programming language that exposes API through FFI to multiple programming environments.
|
||||
|
||||
## Use cases
|
||||
|
||||
*enry* guesses a programming language using a sequence of matching *strategies* that are
|
||||
applied progressively to narrow down the possible options. Each *strategy* varies on the type
|
||||
_enry_ guesses a programming language using a sequence of matching _strategies_ that are
|
||||
applied progressively to narrow down the possible options. Each _strategy_ varies on the type
|
||||
of input data that it needs to make a decision: file name, extension, the first line of the file, the full content of the file, etc.
|
||||
|
||||
Depending on available input data, enry API can be roughly divided into the next categories or use cases.
|
||||
|
||||
### By filename
|
||||
Next functions require only a name of the file to make a guess:
|
||||
- `GetLanguageByExtension` uses only file extension (wich may be ambiguous)
|
||||
- `GetLanguageByFilename` useful for cases like `.gitignore`, `.bashrc`, etc
|
||||
- all [filtering helpers](#filtering)
|
||||
|
||||
Please note that such guesses are expected not to be very accurate.
|
||||
Next functions require only a name of the file to make a guess:
|
||||
|
||||
- `GetLanguageByExtension` uses only file extension (wich may be ambiguous)
|
||||
- `GetLanguageByFilename` useful for cases like `.gitignore`, `.bashrc`, etc
|
||||
- all [filtering helpers](#filtering)
|
||||
|
||||
Please note that such guesses are expected not to be very accurate.
|
||||
|
||||
### By text
|
||||
To make a guess only based on the content of the file or a text snippet, use
|
||||
- `GetLanguageByShebang` reads only the first line of text to identify the [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)).
|
||||
- `GetLanguageByModeline` for cases when Vim/Emacs modeline e.g. `/* vim: set ft=cpp: */` may be present at a head or a tail of the text.
|
||||
- `GetLanguageByClassifier` uses a Bayesian classifier trained on all the `./samples/` from Linguist.
|
||||
|
||||
It usually is a last-resort strategy that is used to disambiguate the guess of the previous strategies, and thus it requires a list of "candidate" guesses. One can provide a list of all known languages - keys from the `data.LanguagesLogProbabilities` as possible candidates if more intelligent hypotheses are not available, at the price of possibly suboptimal accuracy.
|
||||
To make a guess only based on the content of the file or a text snippet, use
|
||||
|
||||
- `GetLanguageByShebang` reads only the first line of text to identify the [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>).
|
||||
- `GetLanguageByModeline` for cases when Vim/Emacs modeline e.g. `/* vim: set ft=cpp: */` may be present at a head or a tail of the text.
|
||||
- `GetLanguageByClassifier` uses a Bayesian classifier trained on all the `./samples/` from Linguist.
|
||||
|
||||
It usually is a last-resort strategy that is used to disambiguate the guess of the previous strategies, and thus it requires a list of "candidate" guesses. One can provide a list of all known languages - keys from the `data.LanguagesLogProbabilities` as possible candidates if more intelligent hypotheses are not available, at the price of possibly suboptimal accuracy.
|
||||
|
||||
### By file
|
||||
|
||||
The most accurate guess would be one when both, the file name and the content are available:
|
||||
- `GetLanguagesByContent` only uses file extension and a set of regexp-based content heuristics.
|
||||
- `GetLanguages` uses the full set of matching strategies and is expected to be most accurate.
|
||||
|
||||
- `GetLanguagesByContent` only uses file extension and a set of regexp-based content heuristics.
|
||||
- `GetLanguages` uses the full set of matching strategies and is expected to be most accurate.
|
||||
|
||||
### Filtering: vendoring, binaries, etc
|
||||
*enry* expose a set of file-level helpers `Is*` to simplify filtering out the files that are less interesting for the purpose of source code analysis:
|
||||
- `IsBinary`
|
||||
- `IsVendor`
|
||||
- `IsConfiguration`
|
||||
- `IsDocumentation`
|
||||
- `IsDotFile`
|
||||
- `IsImage`
|
||||
|
||||
_enry_ expose a set of file-level helpers `Is*` to simplify filtering out the files that are less interesting for the purpose of source code analysis:
|
||||
|
||||
- `IsBinary`
|
||||
- `IsVendor`
|
||||
- `IsConfiguration`
|
||||
- `IsDocumentation`
|
||||
- `IsDotFile`
|
||||
- `IsImage`
|
||||
- `IsTest`
|
||||
- `IsGenerated`
|
||||
|
||||
### Language colors and groups
|
||||
*enry* exposes function to get language color to use for example in presenting statistics in graphs:
|
||||
- `GetColor`
|
||||
- `GetLanguageGroup` can be used to group similar languages together e.g. for `Less` this function will return `CSS`
|
||||
|
||||
_enry_ exposes function to get language color to use for example in presenting statistics in graphs:
|
||||
|
||||
- `GetColor`
|
||||
- `GetLanguageGroup` can be used to group similar languages together e.g. for `Less` this function will return `CSS`
|
||||
|
||||
## Languages
|
||||
|
||||
@@ -136,39 +148,36 @@ Generated Python bindings using a C shared library and cffi are WIP under [src-d
|
||||
A library is going to be published on pypi as [enry](https://pypi.org/project/enry/) for
|
||||
macOS and linux platforms. Windows support is planned under [src-d/enry#150](https://github.com/src-d/enry/issues/150).
|
||||
|
||||
Divergences from Linguist
|
||||
------------
|
||||
## Divergences from Linguist
|
||||
|
||||
The `enry` library is based on the data from `github/linguist` version **v7.9.0**.
|
||||
|
||||
Parsing [linguist/samples](https://github.com/github/linguist/tree/master/samples) the following `enry` results are different from the Linguist:
|
||||
|
||||
* [Heuristics for ".es" extension](https://github.com/github/linguist/blob/e761f9b013e5b61161481fcb898b59721ee40e3d/lib/linguist/heuristics.yml#L103) in JavaScript could not be parsed, due to unsupported backreference in RE2 regexp engine.
|
||||
- [Heuristics for ".es" extension](https://github.com/github/linguist/blob/e761f9b013e5b61161481fcb898b59721ee40e3d/lib/linguist/heuristics.yml#L103) in JavaScript could not be parsed, due to unsupported backreference in RE2 regexp engine.
|
||||
|
||||
* [Heuristics for ".rno" extension](https://github.com/github/linguist/blob/3a1bd3c3d3e741a8aaec4704f782e06f5cd2a00d/lib/linguist/heuristics.yml#L365) in RUNOFF could not be parsed, due to unsupported lookahead in RE2 regexp engine.
|
||||
- [Heuristics for ".rno" extension](https://github.com/github/linguist/blob/3a1bd3c3d3e741a8aaec4704f782e06f5cd2a00d/lib/linguist/heuristics.yml#L365) in RUNOFF could not be parsed, due to unsupported lookahead in RE2 regexp engine.
|
||||
|
||||
* [Heuristics for ".inc" extension](https://github.com/github/linguist/blob/f0e2d0d7f1ce600b2a5acccaef6b149c87d8b99c/lib/linguist/heuristics.yml#L222) in NASL could not be parsed, due to unsupported possessive quantifier in RE2 regexp engine.
|
||||
- [Heuristics for ".inc" extension](https://github.com/github/linguist/blob/f0e2d0d7f1ce600b2a5acccaef6b149c87d8b99c/lib/linguist/heuristics.yml#L222) in NASL could not be parsed, due to unsupported possessive quantifier in RE2 regexp engine.
|
||||
|
||||
* As of [Linguist v5.3.2](https://github.com/github/linguist/releases/tag/v5.3.2) it is using [flex-based scanner in C for tokenization](https://github.com/github/linguist/pull/3846). Enry still uses [extract_token](https://github.com/github/linguist/pull/3846/files#diff-d5179df0b71620e3fac4535cd1368d15L60) regex-based algorithm. See [#193](https://github.com/src-d/enry/issues/193).
|
||||
- As of [Linguist v5.3.2](https://github.com/github/linguist/releases/tag/v5.3.2) it is using [flex-based scanner in C for tokenization](https://github.com/github/linguist/pull/3846). Enry still uses [extract_token](https://github.com/github/linguist/pull/3846/files#diff-d5179df0b71620e3fac4535cd1368d15L60) regex-based algorithm. See [#193](https://github.com/src-d/enry/issues/193).
|
||||
|
||||
* Bayesian classifier can't distinguish "SQL" from "PLpgSQL. See [#194](https://github.com/src-d/enry/issues/194).
|
||||
- Bayesian classifier can't distinguish "SQL" from "PLpgSQL. See [#194](https://github.com/src-d/enry/issues/194).
|
||||
|
||||
* Detection of [generated files](https://github.com/github/linguist/blob/bf95666fc15e49d556f2def4d0a85338423c25f3/lib/linguist/generated.rb#L53) is not supported yet.
|
||||
(Thus they are not excluded from CLI output). See [#213](https://github.com/src-d/enry/issues/213).
|
||||
- Detection of [generated files](https://github.com/github/linguist/blob/bf95666fc15e49d556f2def4d0a85338423c25f3/lib/linguist/generated.rb#L53) is not supported yet.
|
||||
(Thus they are not excluded from CLI output). See [#213](https://github.com/src-d/enry/issues/213).
|
||||
|
||||
* XML detection strategy is not implemented. See [#192](https://github.com/src-d/enry/issues/192).
|
||||
- XML detection strategy is not implemented. See [#192](https://github.com/src-d/enry/issues/192).
|
||||
|
||||
* Overriding languages and types though `.gitattributes` is not yet supported. See [#18](https://github.com/src-d/enry/issues/18).
|
||||
- Overriding languages and types though `.gitattributes` is not yet supported. See [#18](https://github.com/src-d/enry/issues/18).
|
||||
|
||||
* `enry` CLI output does NOT exclude `.gitignore`ed files and git submodules, as Linguist does
|
||||
- `enry` CLI output does NOT exclude `.gitignore`ed files and git submodules, as Linguist does
|
||||
|
||||
In all the cases above that have an issue number - we plan to update enry to match Linguist behavior.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Benchmarks
|
||||
------------
|
||||
|
||||
Enry's language detection has been compared with Linguist's on [*linguist/samples*](https://github.com/github/linguist/tree/master/samples).
|
||||
Enry's language detection has been compared with Linguist's on [_linguist/samples_](https://github.com/github/linguist/tree/master/samples).
|
||||
|
||||
We got these results:
|
||||
|
||||
@@ -182,9 +191,7 @@ Go regexp engine being slower than Ruby's on, wich is based on [oniguruma](https
|
||||
|
||||
See [instructions](#misc) for running enry with oniguruma.
|
||||
|
||||
|
||||
Why Enry?
|
||||
------------
|
||||
## Why Enry?
|
||||
|
||||
In the movie [My Fair Lady](https://en.wikipedia.org/wiki/My_Fair_Lady), [Professor Henry Higgins](http://www.imdb.com/character/ch0011719/) is a linguist who at the very beginning of the movie enjoys guessing the origin of people based on their accent.
|
||||
|
||||
@@ -199,10 +206,9 @@ To run the tests use:
|
||||
Setting `ENRY_TEST_REPO` to the path to existing checkout of Linguist will avoid cloning it and sepeed tests up.
|
||||
Setting `ENRY_DEBUG=1` will provide insight in the Bayesian classifier building done by `make code-generate`.
|
||||
|
||||
|
||||
### Sync with github/linguist upstream
|
||||
|
||||
*enry* re-uses parts of the original [github/linguist](https://github.com/github/linguist) to generate internal data structures.
|
||||
_enry_ re-uses parts of the original [github/linguist](https://github.com/github/linguist) to generate internal data structures.
|
||||
In order to update to the latest release of linguist do:
|
||||
|
||||
```bash
|
||||
@@ -217,10 +223,10 @@ $ make code-generate
|
||||
|
||||
To stay in sync, enry needs to be updated when a new release of the linguist includes changes to any of the following files:
|
||||
|
||||
* [languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml)
|
||||
* [heuristics.yml](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.yml)
|
||||
* [vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml)
|
||||
* [documentation.yml](https://github.com/github/linguist/blob/master/lib/linguist/documentation.yml)
|
||||
- [languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml)
|
||||
- [heuristics.yml](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.yml)
|
||||
- [vendor.yml](https://github.com/github/linguist/blob/master/lib/linguist/vendor.yml)
|
||||
- [documentation.yml](https://github.com/github/linguist/blob/master/lib/linguist/documentation.yml)
|
||||
|
||||
There is no automation for detecting the changes in the linguist project, so this process above has to be done manually from time to time.
|
||||
|
||||
@@ -229,8 +235,6 @@ the generated files (in [data](https://github.com/go-enry/go-enry/blob/master/da
|
||||
|
||||
Separating all the necessary "manual" code changes to a different PR that includes some background description and an update to the documentation on ["divergences from linguist"](#divergences-from-linguist) is very much appreciated as it simplifies the maintenance (review/release notes/etc).
|
||||
|
||||
|
||||
|
||||
## Misc
|
||||
|
||||
<details>
|
||||
@@ -238,19 +242,20 @@ Separating all the necessary "manual" code changes to a different PR that includ
|
||||
|
||||
### Benchmark
|
||||
|
||||
All benchmark scripts are in [*benchmarks*](https://github.com/go-enry/go-enry/blob/master/benchmarks) directory.
|
||||
|
||||
All benchmark scripts are in [_benchmarks_](https://github.com/go-enry/go-enry/blob/master/benchmarks) directory.
|
||||
|
||||
#### Dependencies
|
||||
As benchmarks depend on Ruby and Github-Linguist gem make sure you have:
|
||||
- Ruby (e.g using [`rbenv`](https://github.com/rbenv/rbenv)), [`bundler`](https://bundler.io/) installed
|
||||
- Docker
|
||||
- [native dependencies](https://github.com/github/linguist/#dependencies) installed
|
||||
- Build the gem `cd .linguist && bundle install && rake build_gem && cd -`
|
||||
- Install it `gem install --no-rdoc --no-ri --local .linguist/github-linguist-*.gem`
|
||||
|
||||
As benchmarks depend on Ruby and Github-Linguist gem make sure you have:
|
||||
|
||||
- Ruby (e.g using [`rbenv`](https://github.com/rbenv/rbenv)), [`bundler`](https://bundler.io/) installed
|
||||
- Docker
|
||||
- [native dependencies](https://github.com/github/linguist/#dependencies) installed
|
||||
- Build the gem `cd .linguist && bundle install && rake build_gem && cd -`
|
||||
- Install it `gem install --no-rdoc --no-ri --local .linguist/github-linguist-*.gem`
|
||||
|
||||
#### Quick benchmark
|
||||
|
||||
To run quicker benchmarks
|
||||
|
||||
make benchmarks
|
||||
@@ -259,19 +264,20 @@ to get average times for the primary detection function and strategies for the w
|
||||
|
||||
make benchmarks-samples
|
||||
|
||||
|
||||
#### Full benchmark
|
||||
|
||||
If you want to reproduce the same benchmarks as reported above:
|
||||
- Make sure all [dependencies](#benchmark-dependencies) are installed
|
||||
- Install [gnuplot](http://gnuplot.info) (in order to plot the histogram)
|
||||
- Run `ENRY_TEST_REPO="$PWD/.linguist" benchmarks/run.sh` (takes ~15h)
|
||||
|
||||
- Make sure all [dependencies](#benchmark-dependencies) are installed
|
||||
- Install [gnuplot](http://gnuplot.info) (in order to plot the histogram)
|
||||
- Run `ENRY_TEST_REPO="$PWD/.linguist" benchmarks/run.sh` (takes ~15h)
|
||||
|
||||
It will run the benchmarks for enry and Linguist, parse the output, create csv files and plot the histogram.
|
||||
|
||||
### Faster regexp engine (optional)
|
||||
|
||||
[Oniguruma](https://github.com/kkos/oniguruma) is CRuby's regular expression engine.
|
||||
It is very fast and performs better than the one built into Go runtime. *enry* supports swapping
|
||||
It is very fast and performs better than the one built into Go runtime. _enry_ supports swapping
|
||||
between those two engines thanks to [rubex](https://github.com/moovweb/rubex) project.
|
||||
The typical overall speedup from using Oniguruma is 1.5-2x. However, it requires CGo and the external shared library.
|
||||
On macOS with [Homebrew](https://brew.sh/), it is:
|
||||
@@ -296,8 +302,6 @@ and then rebuild the project.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
License
|
||||
------------
|
||||
## License
|
||||
|
||||
Apache License, Version 2.0. See [LICENSE](LICENSE)
|
||||
|
||||
12
vendor/github.com/go-enry/go-enry/v2/common.go
generated
vendored
12
vendor/github.com/go-enry/go-enry/v2/common.go
generated
vendored
@@ -328,15 +328,13 @@ func getInterpreter(data []byte) (interpreter string) {
|
||||
return
|
||||
}
|
||||
|
||||
func getFirstLine(data []byte) []byte {
|
||||
buf := bufio.NewScanner(bytes.NewReader(data))
|
||||
buf.Scan()
|
||||
line := buf.Bytes()
|
||||
if err := buf.Err(); err != nil {
|
||||
return nil
|
||||
func getFirstLine(content []byte) []byte {
|
||||
nlpos := bytes.IndexByte(content, '\n')
|
||||
if nlpos < 0 {
|
||||
return content
|
||||
}
|
||||
|
||||
return line
|
||||
return content[:nlpos]
|
||||
}
|
||||
|
||||
func hasShebang(line []byte) bool {
|
||||
|
||||
40
vendor/github.com/go-enry/go-enry/v2/data/documentation.go
generated
vendored
40
vendor/github.com/go-enry/go-enry/v2/data/documentation.go
generated
vendored
@@ -3,24 +3,24 @@
|
||||
|
||||
package data
|
||||
|
||||
import "gopkg.in/toqueteos/substring.v1"
|
||||
import "github.com/go-enry/go-enry/v2/regex"
|
||||
|
||||
var DocumentationMatchers = substring.Or(
|
||||
substring.Regexp(`^[Dd]ocs?/`),
|
||||
substring.Regexp(`(^|/)[Dd]ocumentation/`),
|
||||
substring.Regexp(`(^|/)[Gg]roovydoc/`),
|
||||
substring.Regexp(`(^|/)[Jj]avadoc/`),
|
||||
substring.Regexp(`^[Mm]an/`),
|
||||
substring.Regexp(`^[Ee]xamples/`),
|
||||
substring.Regexp(`^[Dd]emos?/`),
|
||||
substring.Regexp(`(^|/)inst/doc/`),
|
||||
substring.Regexp(`(^|/)CHANGE(S|LOG)?(\.|$)`),
|
||||
substring.Regexp(`(^|/)CONTRIBUTING(\.|$)`),
|
||||
substring.Regexp(`(^|/)COPYING(\.|$)`),
|
||||
substring.Regexp(`(^|/)INSTALL(\.|$)`),
|
||||
substring.Regexp(`(^|/)LICEN[CS]E(\.|$)`),
|
||||
substring.Regexp(`(^|/)[Ll]icen[cs]e(\.|$)`),
|
||||
substring.Regexp(`(^|/)README(\.|$)`),
|
||||
substring.Regexp(`(^|/)[Rr]eadme(\.|$)`),
|
||||
substring.Regexp(`^[Ss]amples?/`),
|
||||
)
|
||||
var DocumentationMatchers = []regex.EnryRegexp{
|
||||
regex.MustCompile(`^[Dd]ocs?/`),
|
||||
regex.MustCompile(`(^|/)[Dd]ocumentation/`),
|
||||
regex.MustCompile(`(^|/)[Gg]roovydoc/`),
|
||||
regex.MustCompile(`(^|/)[Jj]avadoc/`),
|
||||
regex.MustCompile(`^[Mm]an/`),
|
||||
regex.MustCompile(`^[Ee]xamples/`),
|
||||
regex.MustCompile(`^[Dd]emos?/`),
|
||||
regex.MustCompile(`(^|/)inst/doc/`),
|
||||
regex.MustCompile(`(^|/)CHANGE(S|LOG)?(\.|$)`),
|
||||
regex.MustCompile(`(^|/)CONTRIBUTING(\.|$)`),
|
||||
regex.MustCompile(`(^|/)COPYING(\.|$)`),
|
||||
regex.MustCompile(`(^|/)INSTALL(\.|$)`),
|
||||
regex.MustCompile(`(^|/)LICEN[CS]E(\.|$)`),
|
||||
regex.MustCompile(`(^|/)[Ll]icen[cs]e(\.|$)`),
|
||||
regex.MustCompile(`(^|/)README(\.|$)`),
|
||||
regex.MustCompile(`(^|/)[Rr]eadme(\.|$)`),
|
||||
regex.MustCompile(`^[Ss]amples?/`),
|
||||
}
|
||||
|
||||
823
vendor/github.com/go-enry/go-enry/v2/data/generated.go
generated
vendored
Normal file
823
vendor/github.com/go-enry/go-enry/v2/data/generated.go
generated
vendored
Normal file
@@ -0,0 +1,823 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/go-enry/go-enry/v2/regex"
|
||||
)
|
||||
|
||||
// GeneratedCodeExtensions contains all extensions that belong to generated
|
||||
// files for sure.
|
||||
var GeneratedCodeExtensions = map[string]struct{}{
|
||||
// XCode files
|
||||
".nib": {},
|
||||
".xcworkspacedata": {},
|
||||
".xcuserstate": {},
|
||||
}
|
||||
|
||||
// GeneratedCodeNameMatcher is a function that tells whether the file with the
|
||||
// given name is generated.
|
||||
type GeneratedCodeNameMatcher func(string) bool
|
||||
|
||||
func nameMatches(pattern string) GeneratedCodeNameMatcher {
|
||||
r := regex.MustCompile(pattern)
|
||||
return func(name string) bool {
|
||||
return r.MatchString(name)
|
||||
}
|
||||
}
|
||||
|
||||
func nameContains(pattern string) GeneratedCodeNameMatcher {
|
||||
return func(name string) bool {
|
||||
return strings.Contains(name, pattern)
|
||||
}
|
||||
}
|
||||
|
||||
func nameEndsWith(pattern string) GeneratedCodeNameMatcher {
|
||||
return func(name string) bool {
|
||||
return strings.HasSuffix(name, pattern)
|
||||
}
|
||||
}
|
||||
|
||||
// GeneratedCodeNameMatchers are all the matchers that check whether the code
|
||||
// is generated based only on the file name.
|
||||
var GeneratedCodeNameMatchers = []GeneratedCodeNameMatcher{
|
||||
// Cocoa pods
|
||||
nameMatches(`(^Pods|\/Pods)\/`),
|
||||
|
||||
// Carthage build
|
||||
nameMatches(`(^|\/)Carthage\/Build\/`),
|
||||
|
||||
// NET designer file
|
||||
nameMatches(`(?i)\.designer\.(cs|vb)$`),
|
||||
|
||||
// Generated NET specflow feature file
|
||||
nameEndsWith(".feature.cs"),
|
||||
|
||||
// Node modules
|
||||
nameContains("node_modules/"),
|
||||
|
||||
// Go vendor
|
||||
nameMatches(`vendor\/([-0-9A-Za-z]+\.)+(com|edu|gov|in|me|net|org|fm|io)`),
|
||||
|
||||
// Go lock
|
||||
nameEndsWith("Gopkg.lock"),
|
||||
nameEndsWith("glide.lock"),
|
||||
|
||||
// Esy lock
|
||||
nameMatches(`(^|\/)(\w+\.)?esy.lock$`),
|
||||
|
||||
// NPM shrinkwrap
|
||||
nameEndsWith("npm-shrinkwrap.json"),
|
||||
|
||||
// NPM package lock
|
||||
nameEndsWith("package-lock.json"),
|
||||
|
||||
// Yarn plugnplay
|
||||
nameMatches(`(^|\/)\.pnp\.(c|m)?js$`),
|
||||
|
||||
// Godeps
|
||||
nameContains("Godeps/"),
|
||||
|
||||
// Composer lock
|
||||
nameEndsWith("composer.lock"),
|
||||
|
||||
// Generated by zephir
|
||||
nameMatches(`.\.zep\.(?:c|h|php)$`),
|
||||
|
||||
// Cargo lock
|
||||
nameEndsWith("Cargo.lock"),
|
||||
|
||||
// Pipenv lock
|
||||
nameEndsWith("Pipfile.lock"),
|
||||
|
||||
// GraphQL relay
|
||||
nameContains("__generated__/"),
|
||||
}
|
||||
|
||||
// GeneratedCodeMatcher checks whether the file with the given data is
|
||||
// generated code.
|
||||
type GeneratedCodeMatcher func(path, ext string, content []byte) bool
|
||||
|
||||
// GeneratedCodeMatchers is the list of all generated code matchers that
|
||||
// rely on checking the content of the file to make the guess.
|
||||
var GeneratedCodeMatchers = []GeneratedCodeMatcher{
|
||||
isMinifiedFile,
|
||||
hasSourceMapReference,
|
||||
isSourceMap,
|
||||
isCompiledCoffeeScript,
|
||||
isGeneratedNetDocfile,
|
||||
isGeneratedJavaScriptPEGParser,
|
||||
isGeneratedPostScript,
|
||||
isGeneratedGo,
|
||||
isGeneratedProtobuf,
|
||||
isGeneratedJavaScriptProtocolBuffer,
|
||||
isGeneratedApacheThrift,
|
||||
isGeneratedJNIHeader,
|
||||
isVCRCassette,
|
||||
isCompiledCythonFile,
|
||||
isGeneratedModule,
|
||||
isGeneratedUnity3DMeta,
|
||||
isGeneratedRacc,
|
||||
isGeneratedJFlex,
|
||||
isGeneratedGrammarKit,
|
||||
isGeneratedRoxygen2,
|
||||
isGeneratedJison,
|
||||
isGeneratedGRPCCpp,
|
||||
isGeneratedDart,
|
||||
isGeneratedPerlPPPortHeader,
|
||||
isGeneratedGameMakerStudio,
|
||||
isGeneratedGimp,
|
||||
isGeneratedVisualStudio6,
|
||||
isGeneratedHaxe,
|
||||
isGeneratedHTML,
|
||||
isGeneratedJooq,
|
||||
}
|
||||
|
||||
func canBeMinified(ext string) bool {
|
||||
return ext == ".js" || ext == ".css"
|
||||
}
|
||||
|
||||
// isMinifiedFile returns whether the file may be minified.
|
||||
// We consider a minified file any css or js file whose average number of chars
|
||||
// per line is more than 110.
|
||||
func isMinifiedFile(path, ext string, content []byte) bool {
|
||||
if !canBeMinified(ext) {
|
||||
return false
|
||||
}
|
||||
|
||||
var chars, lines uint64
|
||||
forEachLine(content, func(line []byte) {
|
||||
chars += uint64(len(line))
|
||||
lines++
|
||||
})
|
||||
|
||||
if lines == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return chars/lines > 110
|
||||
}
|
||||
|
||||
var sourceMapRegex = regex.MustCompile(`^\/[*\/][\#@] source(?:Mapping)?URL|sourceURL=`)
|
||||
|
||||
// hasSourceMapReference returns whether the file contains a reference to a
|
||||
// source-map file.
|
||||
func hasSourceMapReference(_ string, ext string, content []byte) bool {
|
||||
if !canBeMinified(ext) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range getLines(content, -2) {
|
||||
if sourceMapRegex.Match(line) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var sourceMapRegexps = []regex.EnryRegexp{
|
||||
regex.MustCompile(`^{"version":\d+,`),
|
||||
regex.MustCompile(`^\/\*\* Begin line maps\. \*\*\/{`),
|
||||
}
|
||||
|
||||
// isSourceMap returns whether the file itself is a source map.
|
||||
func isSourceMap(path, _ string, content []byte) bool {
|
||||
if strings.HasSuffix(path, ".js.map") || strings.HasSuffix(path, ".css.map") {
|
||||
return true
|
||||
}
|
||||
|
||||
firstLine := getFirstLine(content)
|
||||
if len(firstLine) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, r := range sourceMapRegexps {
|
||||
if r.Match(firstLine) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isCompiledCoffeeScript(path, ext string, content []byte) bool {
|
||||
if ext != ".js" {
|
||||
return false
|
||||
}
|
||||
|
||||
firstLine := getFirstLine(content)
|
||||
lastLines := getLines(content, -2)
|
||||
if len(lastLines) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
if string(firstLine) == "(function() {" &&
|
||||
string(lastLines[1]) == "}).call(this);" &&
|
||||
string(lastLines[0]) == "" {
|
||||
score := 0
|
||||
|
||||
forEachLine(content, func(line []byte) {
|
||||
if bytes.Contains(line, []byte("var ")) {
|
||||
// Underscored temp vars are likely to be Coffee
|
||||
score += 1 * countAppearancesInLine(line, "_fn", "_i", "_len", "_ref", "_results")
|
||||
|
||||
// bind and extend functions are very Coffee specific
|
||||
score += 3 * countAppearancesInLine(line, "__bind", "__extends", "__hasProp", "__indexOf", "__slice")
|
||||
}
|
||||
})
|
||||
|
||||
// Require a score of 3. This is fairly abritrary. Consider tweaking later.
|
||||
// See: https://github.com/github/linguist/blob/master/lib/linguist/generated.rb#L176-L213
|
||||
return score >= 3
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedNetDocfile(_, ext string, content []byte) bool {
|
||||
if ext != ".xml" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := bytes.Split(content, []byte{'\n'})
|
||||
if len(lines) <= 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[1], []byte("<doc>")) &&
|
||||
bytes.Contains(lines[2], []byte("<assembly>")) &&
|
||||
bytes.Contains(lines[len(lines)-2], []byte("</doc>"))
|
||||
}
|
||||
|
||||
var pegJavaScriptGeneratedRegex = regex.MustCompile(`^(?:[^\/]|\/[^\*])*\/\*(?:[^\*]|\*[^\/])*Generated by PEG.js`)
|
||||
|
||||
func isGeneratedJavaScriptPEGParser(_, ext string, content []byte) bool {
|
||||
if ext != ".js" {
|
||||
return false
|
||||
}
|
||||
|
||||
// PEG.js-generated parsers include a comment near the top of the file
|
||||
// that marks them as such.
|
||||
return pegJavaScriptGeneratedRegex.Match(bytes.Join(getLines(content, 5), []byte("")))
|
||||
}
|
||||
|
||||
var postScriptType1And42Regex = regex.MustCompile(`(\n|\r\n|\r)\s*(?:currentfile eexec\s+|\/sfnts\s+\[)`)
|
||||
|
||||
var postScriptRegexes = []regex.EnryRegexp{
|
||||
regex.MustCompile(`[0-9]|draw|mpage|ImageMagick|inkscape|MATLAB`),
|
||||
regex.MustCompile(`PCBNEW|pnmtops|\(Unknown\)|Serif Affinity|Filterimage -tops`),
|
||||
}
|
||||
|
||||
func isGeneratedPostScript(_, ext string, content []byte) bool {
|
||||
if ext != ".ps" && ext != ".eps" && ext != ".pfa" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Type 1 and Type 42 fonts converted to PostScript are stored as hex-encoded byte streams; these
|
||||
// streams are always preceded the `eexec` operator (if Type 1), or the `/sfnts` key (if Type 42).
|
||||
if postScriptType1And42Regex.Match(content) {
|
||||
return true
|
||||
}
|
||||
|
||||
// We analyze the "%%Creator:" comment, which contains the author/generator
|
||||
// of the file. If there is one, it should be in one of the first few lines.
|
||||
var creator []byte
|
||||
for _, line := range getLines(content, 10) {
|
||||
if bytes.HasPrefix(line, []byte("%%Creator: ")) {
|
||||
creator = line
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(creator) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// EAGLE doesn't include a version number when it generates PostScript.
|
||||
// However, it does prepend its name to the document's "%%Title" field.
|
||||
if bytes.Contains(creator, []byte("EAGLE")) {
|
||||
for _, line := range getLines(content, 5) {
|
||||
if bytes.HasPrefix(line, []byte("%%Title: EAGLE Drawing ")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Most generators write their version number, while human authors' or companies'
|
||||
// names don't contain numbers. So look if the line contains digits. Also
|
||||
// look for some special cases without version numbers.
|
||||
for _, r := range postScriptRegexes {
|
||||
if r.Match(creator) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedGo(_, ext string, content []byte) bool {
|
||||
if ext != ".go" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 40)
|
||||
if len(lines) <= 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
if bytes.Contains(line, []byte("Code generated by")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var protoExtensions = map[string]struct{}{
|
||||
".py": {},
|
||||
".java": {},
|
||||
".h": {},
|
||||
".cc": {},
|
||||
".cpp": {},
|
||||
".m": {},
|
||||
".rb": {},
|
||||
".php": {},
|
||||
}
|
||||
|
||||
func isGeneratedProtobuf(_, ext string, content []byte) bool {
|
||||
if _, ok := protoExtensions[ext]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 3)
|
||||
if len(lines) <= 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
if bytes.Contains(line, []byte("Generated by the protocol buffer compiler. DO NOT EDIT!")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedJavaScriptProtocolBuffer(_, ext string, content []byte) bool {
|
||||
if ext != ".js" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 6)
|
||||
if len(lines) < 6 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[5], []byte("GENERATED CODE -- DO NOT EDIT!"))
|
||||
}
|
||||
|
||||
var apacheThriftExtensions = map[string]struct{}{
|
||||
".rb": {},
|
||||
".py": {},
|
||||
".go": {},
|
||||
".js": {},
|
||||
".m": {},
|
||||
".java": {},
|
||||
".h": {},
|
||||
".cc": {},
|
||||
".cpp": {},
|
||||
".php": {},
|
||||
}
|
||||
|
||||
func isGeneratedApacheThrift(_, ext string, content []byte) bool {
|
||||
if _, ok := apacheThriftExtensions[ext]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range getLines(content, 6) {
|
||||
if bytes.Contains(line, []byte("Autogenerated by Thrift Compiler")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedJNIHeader(_, ext string, content []byte) bool {
|
||||
if ext != ".h" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 2)
|
||||
if len(lines) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("/* DO NOT EDIT THIS FILE - it is machine generated */")) &&
|
||||
bytes.Contains(lines[1], []byte("#include <jni.h>"))
|
||||
}
|
||||
|
||||
func isVCRCassette(_, ext string, content []byte) bool {
|
||||
if ext != ".yml" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, -2)
|
||||
if len(lines) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[1], []byte("recorded_with: VCR"))
|
||||
}
|
||||
|
||||
func isCompiledCythonFile(_, ext string, content []byte) bool {
|
||||
if ext != ".c" && ext != ".cpp" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("Generated by Cython"))
|
||||
}
|
||||
|
||||
func isGeneratedModule(_, ext string, content []byte) bool {
|
||||
if ext != ".mod" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("PCBNEW-LibModule-V")) ||
|
||||
bytes.Contains(lines[0], []byte("GFORTRAN module version '"))
|
||||
}
|
||||
|
||||
func isGeneratedUnity3DMeta(_, ext string, content []byte) bool {
|
||||
if ext != ".meta" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("fileFormatVersion: "))
|
||||
}
|
||||
|
||||
func isGeneratedRacc(_, ext string, content []byte) bool {
|
||||
if ext != ".rb" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 3)
|
||||
if len(lines) < 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.HasPrefix(lines[2], []byte("# This file is automatically generated by Racc"))
|
||||
}
|
||||
|
||||
func isGeneratedJFlex(_, ext string, content []byte) bool {
|
||||
if ext != ".java" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.HasPrefix(lines[0], []byte("/* The following code was generated by JFlex "))
|
||||
}
|
||||
|
||||
func isGeneratedGrammarKit(_, ext string, content []byte) bool {
|
||||
if ext != ".java" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("// This is a generated file. Not intended for manual editing."))
|
||||
}
|
||||
|
||||
func isGeneratedRoxygen2(_, ext string, content []byte) bool {
|
||||
if ext != ".rd" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("% Generated by roxygen2: do not edit by hand"))
|
||||
}
|
||||
|
||||
func isGeneratedJison(_, ext string, content []byte) bool {
|
||||
if ext != ".js" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("/* parser generated by jison ")) ||
|
||||
bytes.Contains(lines[0], []byte("/* generated by jison-lex "))
|
||||
}
|
||||
|
||||
func isGeneratedGRPCCpp(_, ext string, content []byte) bool {
|
||||
switch ext {
|
||||
case ".cpp", ".hpp", ".h", ".cc":
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[0], []byte("// Generated by the gRPC"))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var dartRegex = regex.MustCompile(`generated code\W{2,3}do not modify`)
|
||||
|
||||
func isGeneratedDart(_, ext string, content []byte) bool {
|
||||
if ext != ".dart" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
return dartRegex.Match(bytes.ToLower(lines[0]))
|
||||
}
|
||||
|
||||
func isGeneratedPerlPPPortHeader(name, _ string, content []byte) bool {
|
||||
if !strings.HasSuffix(name, "ppport.h") {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 10)
|
||||
if len(lines) < 10 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Contains(lines[8], []byte("Automatically created by Devel::PPPort"))
|
||||
}
|
||||
|
||||
var (
|
||||
gameMakerStudioFirstLineRegex = regex.MustCompile(`^\d\.\d\.\d.+\|\{`)
|
||||
gameMakerStudioThirdLineRegex = regex.MustCompile(`\"modelName\"\:\s*\"GM`)
|
||||
)
|
||||
|
||||
func isGeneratedGameMakerStudio(_, ext string, content []byte) bool {
|
||||
if ext != ".yy" && ext != ".yyp" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 3)
|
||||
if len(lines) < 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
return gameMakerStudioThirdLineRegex.Match(lines[2]) ||
|
||||
gameMakerStudioFirstLineRegex.Match(lines[0])
|
||||
}
|
||||
|
||||
var gimpRegexes = []regex.EnryRegexp{
|
||||
regex.MustCompile(`\/\* GIMP [a-zA-Z0-9\- ]+ C\-Source image dump \(.+?\.c\) \*\/`),
|
||||
regex.MustCompile(`\/\* GIMP header image file format \([a-zA-Z0-9\- ]+\)\: .+?\.h \*\/`),
|
||||
}
|
||||
|
||||
func isGeneratedGimp(_, ext string, content []byte) bool {
|
||||
if ext != ".c" && ext != ".h" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, r := range gimpRegexes {
|
||||
if r.Match(lines[0]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedVisualStudio6(_, ext string, content []byte) bool {
|
||||
if ext != ".dsp" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, l := range getLines(content, 3) {
|
||||
if bytes.Contains(l, []byte("# Microsoft Developer Studio Generated Build File")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var haxeExtensions = map[string]struct{}{
|
||||
".js": {},
|
||||
".py": {},
|
||||
".lua": {},
|
||||
".cpp": {},
|
||||
".h": {},
|
||||
".java": {},
|
||||
".cs": {},
|
||||
".php": {},
|
||||
}
|
||||
|
||||
func isGeneratedHaxe(_, ext string, content []byte) bool {
|
||||
if _, ok := haxeExtensions[ext]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, l := range getLines(content, 3) {
|
||||
if bytes.Contains(l, []byte("Generated by Haxe")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
doxygenRegex = regex.MustCompile(`<!--\s+Generated by Doxygen\s+[.0-9]+\s*-->`)
|
||||
htmlMetaRegex = regex.MustCompile(`<meta(\s+[^>]+)>`)
|
||||
htmlMetaContentRegex = regex.MustCompile(`\s+(name|content|value)\s*=\s*("[^"]+"|'[^']+'|[^\s"']+)`)
|
||||
orgModeMetaRegex = regex.MustCompile(`org\s+mode`)
|
||||
)
|
||||
|
||||
func isGeneratedHTML(_, ext string, content []byte) bool {
|
||||
if ext != ".html" && ext != ".htm" && ext != ".xhtml" {
|
||||
return false
|
||||
}
|
||||
|
||||
lines := getLines(content, 30)
|
||||
|
||||
// Pkgdown
|
||||
if len(lines) >= 2 {
|
||||
for _, l := range lines[:2] {
|
||||
if bytes.Contains(l, []byte("<!-- Generated by pkgdown: do not edit by hand -->")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mandoc
|
||||
if len(lines) > 2 &&
|
||||
bytes.HasPrefix(lines[2], []byte("<!-- This is an automatically generated file.")) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Doxygen
|
||||
for _, l := range lines {
|
||||
if doxygenRegex.Match(l) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// HTML tag: <meta name="generator" content="" />
|
||||
part := bytes.ToLower(bytes.Join(lines, []byte{' '}))
|
||||
part = bytes.ReplaceAll(part, []byte{'\n'}, []byte{})
|
||||
part = bytes.ReplaceAll(part, []byte{'\r'}, []byte{})
|
||||
matches := htmlMetaRegex.FindAll(part, -1)
|
||||
if len(matches) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, m := range matches {
|
||||
var name, value, content string
|
||||
ms := htmlMetaContentRegex.FindAllStringSubmatch(string(m), -1)
|
||||
for _, m := range ms {
|
||||
switch m[1] {
|
||||
case "name":
|
||||
name = m[2]
|
||||
case "value":
|
||||
value = m[2]
|
||||
case "content":
|
||||
content = m[2]
|
||||
}
|
||||
}
|
||||
|
||||
var val = value
|
||||
if val == "" {
|
||||
val = content
|
||||
}
|
||||
|
||||
name = strings.Trim(name, `"'`)
|
||||
val = strings.Trim(val, `"'`)
|
||||
|
||||
if name != "generator" || val == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(val, "jlatex2html") ||
|
||||
strings.Contains(val, "latex2html") ||
|
||||
strings.Contains(val, "groff") ||
|
||||
strings.Contains(val, "makeinfo") ||
|
||||
strings.Contains(val, "texi2html") ||
|
||||
strings.Contains(val, "ronn") ||
|
||||
orgModeMetaRegex.MatchString(val) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isGeneratedJooq(_, ext string, content []byte) bool {
|
||||
if ext != ".java" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, l := range getLines(content, 2) {
|
||||
if bytes.Contains(l, []byte("This file is generated by jOOQ.")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getFirstLine(content []byte) []byte {
|
||||
lines := getLines(content, 1)
|
||||
if len(lines) > 0 {
|
||||
return lines[0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getLines returns up to the first n lines. A negative index will return up to
|
||||
// the last n lines in reverse order.
|
||||
func getLines(content []byte, n int) [][]byte {
|
||||
var result [][]byte
|
||||
if n < 0 {
|
||||
for pos := len(content); pos > 0 && len(result) < -n; {
|
||||
nlpos := bytes.LastIndexByte(content[:pos], '\n')
|
||||
if nlpos+1 < len(content)-1 {
|
||||
result = append(result, content[nlpos+1:pos])
|
||||
}
|
||||
pos = nlpos
|
||||
}
|
||||
} else {
|
||||
for pos := 0; pos < len(content) && len(result) < n; {
|
||||
nlpos := bytes.IndexByte(content[pos:], '\n')
|
||||
if nlpos < 0 && pos < len(content) {
|
||||
nlpos = len(content)
|
||||
} else if nlpos >= 0 {
|
||||
nlpos += pos
|
||||
}
|
||||
|
||||
result = append(result, content[pos:nlpos])
|
||||
pos = nlpos + 1
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func forEachLine(content []byte, cb func([]byte)) {
|
||||
var pos int
|
||||
for pos < len(content) {
|
||||
nlpos := bytes.IndexByte(content[pos:], '\n')
|
||||
if nlpos < 0 && pos < len(content) {
|
||||
nlpos = len(content)
|
||||
} else if nlpos >= 0 {
|
||||
nlpos += pos
|
||||
}
|
||||
|
||||
cb(content[pos:nlpos])
|
||||
pos = nlpos + 1
|
||||
}
|
||||
}
|
||||
|
||||
func countAppearancesInLine(line []byte, targets ...string) int {
|
||||
var count int
|
||||
for _, t := range targets {
|
||||
count += bytes.Count(line, []byte(t))
|
||||
}
|
||||
return count
|
||||
}
|
||||
17
vendor/github.com/go-enry/go-enry/v2/data/test.go
generated
vendored
Normal file
17
vendor/github.com/go-enry/go-enry/v2/data/test.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package data
|
||||
|
||||
import "github.com/go-enry/go-enry/v2/regex"
|
||||
|
||||
// TestMatchers is hand made collection of regexp used by the function `enry.IsTest`
|
||||
// to identify test files in different languages.
|
||||
var TestMatchers = []regex.EnryRegexp{
|
||||
regex.MustCompile(`(^|/)tests/.*Test\.php$`),
|
||||
regex.MustCompile(`(^|/)test/.*Test(s?)\.java$`),
|
||||
regex.MustCompile(`(^|/)test(/|/.*/)Test.*\.java$`),
|
||||
regex.MustCompile(`(^|/)test/.*(Test(s?)|Spec(s?))\.scala$`),
|
||||
regex.MustCompile(`(^|/)test_.*\.py$`),
|
||||
regex.MustCompile(`(^|/).*_test\.go$`),
|
||||
regex.MustCompile(`(^|/).*_(test|spec)\.rb$`),
|
||||
regex.MustCompile(`(^|/).*Test(s?)\.cs$`),
|
||||
regex.MustCompile(`(^|/).*\.(test|spec)\.(ts|tsx|js)$`),
|
||||
}
|
||||
326
vendor/github.com/go-enry/go-enry/v2/data/vendor.go
generated
vendored
326
vendor/github.com/go-enry/go-enry/v2/data/vendor.go
generated
vendored
@@ -3,167 +3,167 @@
|
||||
|
||||
package data
|
||||
|
||||
import "gopkg.in/toqueteos/substring.v1"
|
||||
import "github.com/go-enry/go-enry/v2/regex"
|
||||
|
||||
var VendorMatchers = substring.Or(
|
||||
substring.Regexp(`(^|/)cache/`),
|
||||
substring.Regexp(`^[Dd]ependencies/`),
|
||||
substring.Regexp(`(^|/)dist/`),
|
||||
substring.Regexp(`^deps/`),
|
||||
substring.Regexp(`(^|/)configure$`),
|
||||
substring.Regexp(`(^|/)config.guess$`),
|
||||
substring.Regexp(`(^|/)config.sub$`),
|
||||
substring.Regexp(`(^|/)aclocal.m4`),
|
||||
substring.Regexp(`(^|/)libtool.m4`),
|
||||
substring.Regexp(`(^|/)ltoptions.m4`),
|
||||
substring.Regexp(`(^|/)ltsugar.m4`),
|
||||
substring.Regexp(`(^|/)ltversion.m4`),
|
||||
substring.Regexp(`(^|/)lt~obsolete.m4`),
|
||||
substring.Regexp(`dotnet-install\.(ps1|sh)$`),
|
||||
substring.Regexp(`cpplint.py`),
|
||||
substring.Regexp(`node_modules/`),
|
||||
substring.Regexp(`(^|/)\.yarn/releases/`),
|
||||
substring.Regexp(`(^|/)_esy$`),
|
||||
substring.Regexp(`bower_components/`),
|
||||
substring.Regexp(`^rebar$`),
|
||||
substring.Regexp(`erlang.mk`),
|
||||
substring.Regexp(`Godeps/_workspace/`),
|
||||
substring.Regexp(`(^|/)testdata/`),
|
||||
substring.Regexp(`.indent.pro`),
|
||||
substring.Regexp(`(\.|-)min\.(js|css)$`),
|
||||
substring.Regexp(`([^\s]*)import\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)bootstrap([^.]*)\.(js|css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)custom\.bootstrap([^\s]*)(js|css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)font-?awesome\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)font-?awesome/.*\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)foundation\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)normalize\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)skeleton\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)[Bb]ourbon/.*\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)animate\.(css|less|scss|styl)$`),
|
||||
substring.Regexp(`(^|/)materialize\.(css|less|scss|styl|js)$`),
|
||||
substring.Regexp(`(^|/)select2/.*\.(css|scss|js)$`),
|
||||
substring.Regexp(`(^|/)bulma\.(css|sass|scss)$`),
|
||||
substring.Regexp(`(3rd|[Tt]hird)[-_]?[Pp]arty/`),
|
||||
substring.Regexp(`vendors?/`),
|
||||
substring.Regexp(`extern(al)?/`),
|
||||
substring.Regexp(`(^|/)[Vv]+endor/`),
|
||||
substring.Regexp(`^debian/`),
|
||||
substring.Regexp(`run.n$`),
|
||||
substring.Regexp(`bootstrap-datepicker/`),
|
||||
substring.Regexp(`(^|/)jquery([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)jquery\-\d\.\d+(\.\d+)?\.js$`),
|
||||
substring.Regexp(`(^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$`),
|
||||
substring.Regexp(`(^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$`),
|
||||
substring.Regexp(`jquery.fn.gantt.js`),
|
||||
substring.Regexp(`jquery.fancybox.(js|css)`),
|
||||
substring.Regexp(`fuelux.js`),
|
||||
substring.Regexp(`(^|/)jquery\.fileupload(-\w+)?\.js$`),
|
||||
substring.Regexp(`jquery.dataTables.js`),
|
||||
substring.Regexp(`bootbox.js`),
|
||||
substring.Regexp(`pdf.worker.js`),
|
||||
substring.Regexp(`(^|/)slick\.\w+.js$`),
|
||||
substring.Regexp(`(^|/)Leaflet\.Coordinates-\d+\.\d+\.\d+\.src\.js$`),
|
||||
substring.Regexp(`leaflet.draw-src.js`),
|
||||
substring.Regexp(`leaflet.draw.css`),
|
||||
substring.Regexp(`Control.FullScreen.css`),
|
||||
substring.Regexp(`Control.FullScreen.js`),
|
||||
substring.Regexp(`leaflet.spin.js`),
|
||||
substring.Regexp(`wicket-leaflet.js`),
|
||||
substring.Regexp(`.sublime-project`),
|
||||
substring.Regexp(`.sublime-workspace`),
|
||||
substring.Regexp(`.vscode`),
|
||||
substring.Regexp(`(^|/)prototype(.*)\.js$`),
|
||||
substring.Regexp(`(^|/)effects\.js$`),
|
||||
substring.Regexp(`(^|/)controls\.js$`),
|
||||
substring.Regexp(`(^|/)dragdrop\.js$`),
|
||||
substring.Regexp(`(.*?)\.d\.ts$`),
|
||||
substring.Regexp(`(^|/)mootools([^.]*)\d+\.\d+.\d+([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)dojo\.js$`),
|
||||
substring.Regexp(`(^|/)MochiKit\.js$`),
|
||||
substring.Regexp(`(^|/)yahoo-([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)yui([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)ckeditor\.js$`),
|
||||
substring.Regexp(`(^|/)tiny_mce([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)tiny_mce/(langs|plugins|themes|utils)`),
|
||||
substring.Regexp(`(^|/)ace-builds/`),
|
||||
substring.Regexp(`(^|/)fontello(.*?)\.css$`),
|
||||
substring.Regexp(`(^|/)MathJax/`),
|
||||
substring.Regexp(`(^|/)Chart\.js$`),
|
||||
substring.Regexp(`(^|/)[Cc]ode[Mm]irror/(\d+\.\d+/)?(lib|mode|theme|addon|keymap|demo)`),
|
||||
substring.Regexp(`(^|/)shBrush([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)shCore\.js$`),
|
||||
substring.Regexp(`(^|/)shLegacy\.js$`),
|
||||
substring.Regexp(`(^|/)angular([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|\/)d3(\.v\d+)?([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)react(-[^.]*)?\.js$`),
|
||||
substring.Regexp(`(^|/)flow-typed/.*\.js$`),
|
||||
substring.Regexp(`(^|/)modernizr\-\d\.\d+(\.\d+)?\.js$`),
|
||||
substring.Regexp(`(^|/)modernizr\.custom\.\d+\.js$`),
|
||||
substring.Regexp(`(^|/)knockout-(\d+\.){3}(debug\.)?js$`),
|
||||
substring.Regexp(`(^|/)docs?/_?(build|themes?|templates?|static)/`),
|
||||
substring.Regexp(`(^|/)admin_media/`),
|
||||
substring.Regexp(`(^|/)env/`),
|
||||
substring.Regexp(`^fabfile\.py$`),
|
||||
substring.Regexp(`^waf$`),
|
||||
substring.Regexp(`^.osx$`),
|
||||
substring.Regexp(`\.xctemplate/`),
|
||||
substring.Regexp(`\.imageset/`),
|
||||
substring.Regexp(`(^|/)Carthage/`),
|
||||
substring.Regexp(`(^|/)Sparkle/`),
|
||||
substring.Regexp(`Crashlytics.framework/`),
|
||||
substring.Regexp(`Fabric.framework/`),
|
||||
substring.Regexp(`BuddyBuildSDK.framework/`),
|
||||
substring.Regexp(`Realm.framework`),
|
||||
substring.Regexp(`RealmSwift.framework`),
|
||||
substring.Regexp(`gitattributes$`),
|
||||
substring.Regexp(`gitignore$`),
|
||||
substring.Regexp(`gitmodules$`),
|
||||
substring.Regexp(`(^|/)gradlew$`),
|
||||
substring.Regexp(`(^|/)gradlew\.bat$`),
|
||||
substring.Regexp(`(^|/)gradle/wrapper/`),
|
||||
substring.Regexp(`(^|/)mvnw$`),
|
||||
substring.Regexp(`(^|/)mvnw\.cmd$`),
|
||||
substring.Regexp(`(^|/)\.mvn/wrapper/`),
|
||||
substring.Regexp(`-vsdoc\.js$`),
|
||||
substring.Regexp(`\.intellisense\.js$`),
|
||||
substring.Regexp(`(^|/)jquery([^.]*)\.validate(\.unobtrusive)?\.js$`),
|
||||
substring.Regexp(`(^|/)jquery([^.]*)\.unobtrusive\-ajax\.js$`),
|
||||
substring.Regexp(`(^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$`),
|
||||
substring.Regexp(`^[Pp]ackages\/.+\.\d+\/`),
|
||||
substring.Regexp(`(^|/)extjs/.*?\.js$`),
|
||||
substring.Regexp(`(^|/)extjs/.*?\.xml$`),
|
||||
substring.Regexp(`(^|/)extjs/.*?\.txt$`),
|
||||
substring.Regexp(`(^|/)extjs/.*?\.html$`),
|
||||
substring.Regexp(`(^|/)extjs/.*?\.properties$`),
|
||||
substring.Regexp(`(^|/)extjs/.sencha/`),
|
||||
substring.Regexp(`(^|/)extjs/docs/`),
|
||||
substring.Regexp(`(^|/)extjs/builds/`),
|
||||
substring.Regexp(`(^|/)extjs/cmd/`),
|
||||
substring.Regexp(`(^|/)extjs/examples/`),
|
||||
substring.Regexp(`(^|/)extjs/locale/`),
|
||||
substring.Regexp(`(^|/)extjs/packages/`),
|
||||
substring.Regexp(`(^|/)extjs/plugins/`),
|
||||
substring.Regexp(`(^|/)extjs/resources/`),
|
||||
substring.Regexp(`(^|/)extjs/src/`),
|
||||
substring.Regexp(`(^|/)extjs/welcome/`),
|
||||
substring.Regexp(`(^|/)html5shiv\.js$`),
|
||||
substring.Regexp(`^[Tt]ests?/fixtures/`),
|
||||
substring.Regexp(`^[Ss]pecs?/fixtures/`),
|
||||
substring.Regexp(`(^|/)cordova([^.]*)\.js$`),
|
||||
substring.Regexp(`(^|/)cordova\-\d\.\d(\.\d)?\.js$`),
|
||||
substring.Regexp(`foundation(\..*)?\.js$`),
|
||||
substring.Regexp(`^Vagrantfile$`),
|
||||
substring.Regexp(`.[Dd][Ss]_[Ss]tore$`),
|
||||
substring.Regexp(`^vignettes/`),
|
||||
substring.Regexp(`^inst/extdata/`),
|
||||
substring.Regexp(`octicons.css`),
|
||||
substring.Regexp(`sprockets-octicons.scss`),
|
||||
substring.Regexp(`(^|/)activator$`),
|
||||
substring.Regexp(`(^|/)activator\.bat$`),
|
||||
substring.Regexp(`proguard.pro`),
|
||||
substring.Regexp(`proguard-rules.pro`),
|
||||
substring.Regexp(`^puphpet/`),
|
||||
substring.Regexp(`(^|/)\.google_apis/`),
|
||||
substring.Regexp(`^Jenkinsfile$`),
|
||||
)
|
||||
var VendorMatchers = []regex.EnryRegexp{
|
||||
regex.MustCompile(`(^|/)cache/`),
|
||||
regex.MustCompile(`^[Dd]ependencies/`),
|
||||
regex.MustCompile(`(^|/)dist/`),
|
||||
regex.MustCompile(`^deps/`),
|
||||
regex.MustCompile(`(^|/)configure$`),
|
||||
regex.MustCompile(`(^|/)config.guess$`),
|
||||
regex.MustCompile(`(^|/)config.sub$`),
|
||||
regex.MustCompile(`(^|/)aclocal.m4`),
|
||||
regex.MustCompile(`(^|/)libtool.m4`),
|
||||
regex.MustCompile(`(^|/)ltoptions.m4`),
|
||||
regex.MustCompile(`(^|/)ltsugar.m4`),
|
||||
regex.MustCompile(`(^|/)ltversion.m4`),
|
||||
regex.MustCompile(`(^|/)lt~obsolete.m4`),
|
||||
regex.MustCompile(`dotnet-install\.(ps1|sh)$`),
|
||||
regex.MustCompile(`cpplint.py`),
|
||||
regex.MustCompile(`node_modules/`),
|
||||
regex.MustCompile(`(^|/)\.yarn/releases/`),
|
||||
regex.MustCompile(`(^|/)_esy$`),
|
||||
regex.MustCompile(`bower_components/`),
|
||||
regex.MustCompile(`^rebar$`),
|
||||
regex.MustCompile(`erlang.mk`),
|
||||
regex.MustCompile(`Godeps/_workspace/`),
|
||||
regex.MustCompile(`(^|/)testdata/`),
|
||||
regex.MustCompile(`.indent.pro`),
|
||||
regex.MustCompile(`(\.|-)min\.(js|css)$`),
|
||||
regex.MustCompile(`([^\s]*)import\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)bootstrap([^.]*)\.(js|css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)custom\.bootstrap([^\s]*)(js|css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)font-?awesome\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)font-?awesome/.*\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)foundation\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)normalize\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)skeleton\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)[Bb]ourbon/.*\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)animate\.(css|less|scss|styl)$`),
|
||||
regex.MustCompile(`(^|/)materialize\.(css|less|scss|styl|js)$`),
|
||||
regex.MustCompile(`(^|/)select2/.*\.(css|scss|js)$`),
|
||||
regex.MustCompile(`(^|/)bulma\.(css|sass|scss)$`),
|
||||
regex.MustCompile(`(3rd|[Tt]hird)[-_]?[Pp]arty/`),
|
||||
regex.MustCompile(`vendors?/`),
|
||||
regex.MustCompile(`extern(al)?/`),
|
||||
regex.MustCompile(`(^|/)[Vv]+endor/`),
|
||||
regex.MustCompile(`^debian/`),
|
||||
regex.MustCompile(`run.n$`),
|
||||
regex.MustCompile(`bootstrap-datepicker/`),
|
||||
regex.MustCompile(`(^|/)jquery([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)jquery\-\d\.\d+(\.\d+)?\.js$`),
|
||||
regex.MustCompile(`(^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$`),
|
||||
regex.MustCompile(`(^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$`),
|
||||
regex.MustCompile(`jquery.fn.gantt.js`),
|
||||
regex.MustCompile(`jquery.fancybox.(js|css)`),
|
||||
regex.MustCompile(`fuelux.js`),
|
||||
regex.MustCompile(`(^|/)jquery\.fileupload(-\w+)?\.js$`),
|
||||
regex.MustCompile(`jquery.dataTables.js`),
|
||||
regex.MustCompile(`bootbox.js`),
|
||||
regex.MustCompile(`pdf.worker.js`),
|
||||
regex.MustCompile(`(^|/)slick\.\w+.js$`),
|
||||
regex.MustCompile(`(^|/)Leaflet\.Coordinates-\d+\.\d+\.\d+\.src\.js$`),
|
||||
regex.MustCompile(`leaflet.draw-src.js`),
|
||||
regex.MustCompile(`leaflet.draw.css`),
|
||||
regex.MustCompile(`Control.FullScreen.css`),
|
||||
regex.MustCompile(`Control.FullScreen.js`),
|
||||
regex.MustCompile(`leaflet.spin.js`),
|
||||
regex.MustCompile(`wicket-leaflet.js`),
|
||||
regex.MustCompile(`.sublime-project`),
|
||||
regex.MustCompile(`.sublime-workspace`),
|
||||
regex.MustCompile(`.vscode`),
|
||||
regex.MustCompile(`(^|/)prototype(.*)\.js$`),
|
||||
regex.MustCompile(`(^|/)effects\.js$`),
|
||||
regex.MustCompile(`(^|/)controls\.js$`),
|
||||
regex.MustCompile(`(^|/)dragdrop\.js$`),
|
||||
regex.MustCompile(`(.*?)\.d\.ts$`),
|
||||
regex.MustCompile(`(^|/)mootools([^.]*)\d+\.\d+.\d+([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)dojo\.js$`),
|
||||
regex.MustCompile(`(^|/)MochiKit\.js$`),
|
||||
regex.MustCompile(`(^|/)yahoo-([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)yui([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)ckeditor\.js$`),
|
||||
regex.MustCompile(`(^|/)tiny_mce([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)tiny_mce/(langs|plugins|themes|utils)`),
|
||||
regex.MustCompile(`(^|/)ace-builds/`),
|
||||
regex.MustCompile(`(^|/)fontello(.*?)\.css$`),
|
||||
regex.MustCompile(`(^|/)MathJax/`),
|
||||
regex.MustCompile(`(^|/)Chart\.js$`),
|
||||
regex.MustCompile(`(^|/)[Cc]ode[Mm]irror/(\d+\.\d+/)?(lib|mode|theme|addon|keymap|demo)`),
|
||||
regex.MustCompile(`(^|/)shBrush([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)shCore\.js$`),
|
||||
regex.MustCompile(`(^|/)shLegacy\.js$`),
|
||||
regex.MustCompile(`(^|/)angular([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|\/)d3(\.v\d+)?([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)react(-[^.]*)?\.js$`),
|
||||
regex.MustCompile(`(^|/)flow-typed/.*\.js$`),
|
||||
regex.MustCompile(`(^|/)modernizr\-\d\.\d+(\.\d+)?\.js$`),
|
||||
regex.MustCompile(`(^|/)modernizr\.custom\.\d+\.js$`),
|
||||
regex.MustCompile(`(^|/)knockout-(\d+\.){3}(debug\.)?js$`),
|
||||
regex.MustCompile(`(^|/)docs?/_?(build|themes?|templates?|static)/`),
|
||||
regex.MustCompile(`(^|/)admin_media/`),
|
||||
regex.MustCompile(`(^|/)env/`),
|
||||
regex.MustCompile(`^fabfile\.py$`),
|
||||
regex.MustCompile(`^waf$`),
|
||||
regex.MustCompile(`^.osx$`),
|
||||
regex.MustCompile(`\.xctemplate/`),
|
||||
regex.MustCompile(`\.imageset/`),
|
||||
regex.MustCompile(`(^|/)Carthage/`),
|
||||
regex.MustCompile(`(^|/)Sparkle/`),
|
||||
regex.MustCompile(`Crashlytics.framework/`),
|
||||
regex.MustCompile(`Fabric.framework/`),
|
||||
regex.MustCompile(`BuddyBuildSDK.framework/`),
|
||||
regex.MustCompile(`Realm.framework`),
|
||||
regex.MustCompile(`RealmSwift.framework`),
|
||||
regex.MustCompile(`gitattributes$`),
|
||||
regex.MustCompile(`gitignore$`),
|
||||
regex.MustCompile(`gitmodules$`),
|
||||
regex.MustCompile(`(^|/)gradlew$`),
|
||||
regex.MustCompile(`(^|/)gradlew\.bat$`),
|
||||
regex.MustCompile(`(^|/)gradle/wrapper/`),
|
||||
regex.MustCompile(`(^|/)mvnw$`),
|
||||
regex.MustCompile(`(^|/)mvnw\.cmd$`),
|
||||
regex.MustCompile(`(^|/)\.mvn/wrapper/`),
|
||||
regex.MustCompile(`-vsdoc\.js$`),
|
||||
regex.MustCompile(`\.intellisense\.js$`),
|
||||
regex.MustCompile(`(^|/)jquery([^.]*)\.validate(\.unobtrusive)?\.js$`),
|
||||
regex.MustCompile(`(^|/)jquery([^.]*)\.unobtrusive\-ajax\.js$`),
|
||||
regex.MustCompile(`(^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$`),
|
||||
regex.MustCompile(`^[Pp]ackages\/.+\.\d+\/`),
|
||||
regex.MustCompile(`(^|/)extjs/.*?\.js$`),
|
||||
regex.MustCompile(`(^|/)extjs/.*?\.xml$`),
|
||||
regex.MustCompile(`(^|/)extjs/.*?\.txt$`),
|
||||
regex.MustCompile(`(^|/)extjs/.*?\.html$`),
|
||||
regex.MustCompile(`(^|/)extjs/.*?\.properties$`),
|
||||
regex.MustCompile(`(^|/)extjs/.sencha/`),
|
||||
regex.MustCompile(`(^|/)extjs/docs/`),
|
||||
regex.MustCompile(`(^|/)extjs/builds/`),
|
||||
regex.MustCompile(`(^|/)extjs/cmd/`),
|
||||
regex.MustCompile(`(^|/)extjs/examples/`),
|
||||
regex.MustCompile(`(^|/)extjs/locale/`),
|
||||
regex.MustCompile(`(^|/)extjs/packages/`),
|
||||
regex.MustCompile(`(^|/)extjs/plugins/`),
|
||||
regex.MustCompile(`(^|/)extjs/resources/`),
|
||||
regex.MustCompile(`(^|/)extjs/src/`),
|
||||
regex.MustCompile(`(^|/)extjs/welcome/`),
|
||||
regex.MustCompile(`(^|/)html5shiv\.js$`),
|
||||
regex.MustCompile(`^[Tt]ests?/fixtures/`),
|
||||
regex.MustCompile(`^[Ss]pecs?/fixtures/`),
|
||||
regex.MustCompile(`(^|/)cordova([^.]*)\.js$`),
|
||||
regex.MustCompile(`(^|/)cordova\-\d\.\d(\.\d)?\.js$`),
|
||||
regex.MustCompile(`foundation(\..*)?\.js$`),
|
||||
regex.MustCompile(`^Vagrantfile$`),
|
||||
regex.MustCompile(`.[Dd][Ss]_[Ss]tore$`),
|
||||
regex.MustCompile(`^vignettes/`),
|
||||
regex.MustCompile(`^inst/extdata/`),
|
||||
regex.MustCompile(`octicons.css`),
|
||||
regex.MustCompile(`sprockets-octicons.scss`),
|
||||
regex.MustCompile(`(^|/)activator$`),
|
||||
regex.MustCompile(`(^|/)activator\.bat$`),
|
||||
regex.MustCompile(`proguard.pro`),
|
||||
regex.MustCompile(`proguard-rules.pro`),
|
||||
regex.MustCompile(`^puphpet/`),
|
||||
regex.MustCompile(`(^|/)\.google_apis/`),
|
||||
regex.MustCompile(`^Jenkinsfile$`),
|
||||
}
|
||||
|
||||
4
vendor/github.com/go-enry/go-enry/v2/go.mod
generated
vendored
4
vendor/github.com/go-enry/go-enry/v2/go.mod
generated
vendored
@@ -3,9 +3,7 @@ module github.com/go-enry/go-enry/v2
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/go-enry/go-oniguruma v1.2.0
|
||||
github.com/go-enry/go-oniguruma v1.2.1
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/toqueteos/trie v1.0.0 // indirect
|
||||
gopkg.in/toqueteos/substring.v1 v1.0.2
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user