diff options
37 files changed, 636 insertions, 198 deletions
@@ -342,6 +342,7 @@ func runWeb(*cli.Context) { r.Get("/commit/:branchname/*", repo.Diff) r.Get("/releases", repo.Releases) r.Get("/archive/*.*", repo.Download) + r.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff) }, ignSignIn, middleware.RepoAssignment(true, true)) m.Group("/:username", func(r *macaron.Router) { diff --git a/conf/locale/locale_de-DE.ini b/conf/locale/locale_de-DE.ini index 97ca5efd..3e9936d6 100644 --- a/conf/locale/locale_de-DE.ini +++ b/conf/locale/locale_de-DE.ini @@ -28,7 +28,7 @@ new_repo = Neues Repository new_migrate = Neue Migration new_org = Neue Organisation manage_org = Organisationen verwalten -admin_panel = Admin Panel +admin_panel = Admin-Panel account_settings = Kontoeinstellungen settings = Einstellungen @@ -50,20 +50,20 @@ my_mirrors = Meine Spiegel [auth] create_new_account = Neues Konto erstellen register_hepler_msg = Du hast schon ein Konto? Jetzt anmelden! -social_register_hepler_msg = Du hast schon ein Konto? Jetzt verknüpfen! +social_register_hepler_msg = Du hast schon ein soziales Konto? Jetzt verknüpfen! disable_register_prompt = Es tut uns leid, die Registrierung wurde deaktiviert. Bitte wende dich an den Administrator. disable_register_mail = Es tut uns leid, die Bestätigung der Registrierungs-E-Mail wurde deaktiviert. remember_me = angemeldet bleiben forgot_password= Passwort vergessen forget_password = Passwort vergessen? sign_up_now = Du willst ein Konto? Jetzt registrieren! -confirmation_mail_sent_prompt = A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete your registration. +confirmation_mail_sent_prompt = Eine neu Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden um die Registrierung abzuschließen. sign_in_email = Melden dich mit deiner E-Mail-Adresse an active_your_account = Aktivieren dein Konto -resent_limit_prompt = Sorry, you are sending an activation e-mail too frequently. Please wait 3 minutes. -has_unconfirmed_mail = Hi %s, you have an unconfirmed email address(<b>%s</b>). If you haven't received a confirmation e-mail or need to resend a new one, please click on the button below. -resend_mail = Klicke hier, um deine Aktivierungs-E-Mail nochmal zu senden -email_not_associate = Diese E-Mail-Adresse ist mit keinen Konto verknüpft. +resent_limit_prompt = Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten. +has_unconfirmed_mail = Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button. +resend_mail = Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden +email_not_associate = Diese E-Mail-Adresse ist mit keinem Konto verknüpft. send_reset_mail = Hier klicken, um die E-Mail zum Passwort-zurücksetzen erneut zu versenden reset_password = Passwort zurücksetzen invalid_code = Es tut uns leid, der Bestätigungscode ist abgelaufen oder ungültig. @@ -72,13 +72,13 @@ password_too_short = Das Passwort muss mindenstens 6 Zeichen lang sein [form] UserName = Benutzername -RepoName = Repository Name +RepoName = Repository-Name Email = E-Mail-Adresse Password = Passwort Retype = Passwort erneut eingeben SSHTitle = SSH-Schlüsselname HttpsUrl = HTTPS-URL -PayloadUrl = Payload URL +PayloadUrl = Payload-URL TeamName = Teamname AuthName = Authentifizierungsname @@ -94,19 +94,19 @@ captcha_incorrect = Captcha stimmt nicht überein. password_not_match = Die Passwörter stimmen nicht überein. username_been_taken = Benutzername ist bereits vergeben. -repo_name_been_taken = Repository Name ist bereits vergeben. +repo_name_been_taken = Repository-Name ist bereits vergeben. org_name_been_taken = Organisationsname ist bereits vergeben. team_name_been_taken = Teamname ist bereits vergeben. email_been_used = E-Mail-Adresse wird bereits verwendet. ssh_key_been_used = SSH-Schlüsselname wird bereits verwendet. -illegal_username = Ihr Benutzername enthält ungültige Zeichen. +illegal_username = Benutzername enthält ungültige Zeichen. illegal_repo_name = Repository-Name enthält ungültige Zeichen. illegal_org_name = Organisationsname enthält ungültige Zeichen. illegal_team_name = Teamname enthält ungültige Zeichen. username_password_incorrect = Benutzername oder Passwort ist nicht korrekt. -enterred_invalid_repo_name = Bitte stellen Sie sicher, dass der eingegeben Repository-Name richtig ist. -enterred_invalid_owner_name = Bitte stellen Sie sicher, dass der eingegeben Besitzername richtig ist. -enterred_invalid_password = Bitte stellen Sie sicher, dass das eingegebene Passwort richtig ist. +enterred_invalid_repo_name = Bitte stelle sicher, dass der eingegeben Repository-Name richtig ist. +enterred_invalid_owner_name = Bitte stelle sicher, dass der eingegeben Besitzername richtig ist. +enterred_invalid_password = Bitte stelle sicher, dass das eingegebene Passwort richtig ist. user_not_exist = Angegebener Benutzer existiert nicht. last_org_owner = Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben. @@ -127,40 +127,40 @@ orgs = Organisationen delete = Konto löschen public_profile = Öffentliches Profil -profile_desc = Your Email address is public and will be used for any account related notifications, and any web based operations made via the site. +profile_desc = Deine E-Mail-Adresse wird nicht veröffentlicht und dient dazu, dir Benachrichtigungen bezüglich deines Kontos und deiner Repositorys zu schicken. full_name = Vollständiger Name website = Webseite location = Standort update_profile = Profil aktualisieren -update_profile_success = Dein Profil wurde aktualisiert. +update_profile_success = Profil aktualisiert change_password = Passwort ändern old_password = Aktuelles Passwort new_password = Neues Passwort password_incorrect = Aktuelles Passwort ist nicht korrekt. -change_password_success = Passwort erfolgreich geändert. Du kannst dich jetzt mit dem neuen Passwort anmelden. +change_password_success = Passwort geändert. Du kannst dich jetzt mit dem neuen Passwort anmelden. manage_ssh_keys = SSH-Schlüssel verwalten add_key = SSH-Schlüssel hinzufügen -ssh_desc = Dies ist eine Liste aller SSH-Schlüssel, die mit deinem Konto verküpft sind. Entferne alle Schlüssel, die du nicht kennst. -ssh_helper = <strong>Du brauchst Hilfe?</strong> Hier ist eine Anleitung zum <a href="https://help.github.com/articles/generating-ssh-keys">Erzeugen von SSH-Schlüssel</a> oder <a href="https://help.github.com/ssh-issues/">Problemlösung einfacher SSH-Probleme</a>. +ssh_desc = Dies ist eine Liste aller SSH-Schlüssel, die mit deinem Konto verknüpft sind. Entferne alle Schlüssel, die du nicht kennst. +ssh_helper = <strong>Du brauchst Hilfe?</strong> Hier ist eine Anleitung zum <a href="https://help.github.com/articles/generating-ssh-keys">Erzeugen von SSH-Schlüsseln</a> oder <a href="https://help.github.com/ssh-issues/">Problemlösen einfacher SSH-Probleme</a>. add_new_key = SSH-Schlüssel hinzufügen key_name = Schlüsselname key_content = Inhalt -add_key_success = SSH-Schlüssel wurde hinzugefügt! +add_key_success = SSH-Schlüssel hinzugefügt delete_key = SSH-Schlüssel löschen add_on = Hinzugefügt am last_used = Zuletzt verwendet auf no_activity = Keine neuen Aktivitäten -manage_social = Verküpfte soziale Konten verwalten -social_desc = Dies ist eine Liste verküpfter sozialer Konten. Entferne alle Verküpfungen, die du nicht kennst. +manage_social = Verknüpfte soziale Konten verwalten +social_desc = Dies ist eine Liste verknüpfter sozialer Konten. Entferne alle Verknüpfungen, die du nicht kennst. unbind = Verknüpfung entfernen unbind_success = Die Verknüpfung zum sozialen Konto wurde entfernt. delete_account = Konto löschen delete_prompt = Diese Aktion wird dein Konto dauerhaft löschen und kann <strong>NICHT</strong> rückgängig gemacht werden! -confirm_delete_account = Löschen bestätigen +confirm_delete_account = Löschen [repo] owner = Besitzer @@ -172,13 +172,14 @@ repo_desc = Beschreibung repo_lang = Sprache repo_lang_helper = Wähle eine .gitignore Datei license = Lizenz -license_helper = Wählen Sie eine Lizenz aus +license_helper = Wähle eine Lizenz aus init_readme = Repository mit README.md initialisieren create_repo = Repository erstellen default_branch = Standard-Branch mirror_interval = Spiegel-Intervall (in Stunden) goget_meta = Go-Get Meta goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span> +goget_meta_helper = Dieses Repository wird man mit <span class="label label-blue label-radius">go get</span> klonen können. need_auth = Authorisierung benötigt migrate_type = Migrationstyp @@ -194,46 +195,51 @@ star = Markierung fork = Abspaltung quick_guide = Kurzanleitung -clone_this_repo = Dieses Repositorie klonen -create_new_repo_command = Erstellen Sie ein neues Repositorie mittels der Kommandozeile +clone_this_repo = Dieses Repository klonen +create_new_repo_command = Erstelle ein neues Repository mittels der Kommandozeile push_exist_repo = Push an existing repository from the command line settings = Einstellungen settings.options = Optionen settings.collaboration = Zusammenarbeit settings.hooks = Webhooks -settings.deploy_keys = Schlüssel bereitstellen +settings.deploy_keys = Deploy-Keys settings.basic_settings = Grundeinstellungen settings.danger_zone = Gefahrenzone -settings.site = Offizielle Website +settings.site = Offizielle Webseite settings.update_settings = Aktualisierungseinstellungen settings.transfer = Besitz übertragen settings.transfer_desc = Übertrage dieses Repository einem anderen Benutzer oder einer Organisation. settings.delete = Repository löschen settings.delete_desc = Wenn dieses Repository gelöschet ist, gibt es keinen Weg zurück. Sei dir sicher! -settings.update_settings_success = Repository-Optionen wurde erfolgreich aktualisiert. +settings.update_settings_success = Repository-Optionen aktualisiert settings.transfer_owner = Neuer Besitzer settings.make_transfer = übertragen -settings.confirm_delete = Löschen bestätigen -settings.add_collaborator = Neuen Mitarbeiter hinzufügen -settings.add_collaborator_success = Neuer Mitarbeiter wurde hinzugefügt. -settings.remove_collaborator_success = Mitarbeiter wurde entfernt. +settings.confirm_delete = Löschen +settings.add_collaborator = Mitarbeiter hinzufügen +settings.add_collaborator_success = Mitarbeiter hinzugefügt +settings.remove_collaborator_success = Mitarbeiter entfernt settings.add_webhook = Webhook hinzufügen settings.hooks_desc = Webhooks erlauben es externe Dienste zu informieren, wenn etwas bestimmtes in deinem Repository passiert. GoGS sendet dann eine POST-Request an alle angegebenen URLs. Erfahre mehr in unserem <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>. -settings.remove_hook_success = Webhook wurde entfernt. +settings.remove_hook_success = Webhook entfernt settings.add_webhook_desc = GoGS sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonierten Ereignisse. Du kannst auch angeben, welches Datenformat du erhalten willst (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen findest du im <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>. -settings.payload_url = Payload URL +settings.payload_url = Payload-URL settings.content_type = Inhaltstyp -settings.secret = Geheimnis +settings.secret = Secret settings.event_desc = Welche Ereignisse sollen diesen Webhook auslösen? settings.event_push_only = Nur das <code>push</code>-Ereignis. settings.active = Aktiv settings.active_helper = Ereignisdetails werden ausgeliefert, wenn dieser Webhook ausgelöst wird. -settings.add_hook_success = Neuer Webhook wurde hinzugefügt. +settings.add_hook_success = Webhook hinzugefügt settings.update_webhook = Webhook aktualisieren -settings.update_hook_success = Webhook wurde aktualisiert. +settings.update_hook_success = Webhook aktualisiert settings.delete_webhook = Webhook löschen settings.recent_deliveries = letzte Zustellungen +settings.hook_type = Hook Type +settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository. +settings.slack_token = Token +settings.slack_domain = Domain +settings.slack_channel = Channel [org] org_name_holder = Name der Organisation @@ -242,7 +248,7 @@ org_email_helper = Das E-Mail-Konto der Organisation empfängt alle Benachrichti create_org = Organisation erstellen repo_updated = Aktualisiert people = Personen -invite_someone = Jemanden einladen +invite_someone = Benutzer einladen teams = Teams lower_members = Mitglieder lower_repositories = Repositorys @@ -250,8 +256,8 @@ create_new_team = Neues Team erstellen org_desc = Beschreibung team_name = Teamname team_desc = Beschreibung -team_name_helper = Sie werden diesen Namen verwenden, um dieses Team in Gesprächen zu erwähnen. -team_desc_helper = Was hat das Team auf sich? +team_name_helper = Verwende diesen Namen, um dich auf dieses Team zu beziehen. +team_desc_helper = Was hat es mit diesem Team auf sich? team_permission_desc = Welche Berechtigungsstufe soll das Team haben? settings = Einstellungen @@ -260,11 +266,11 @@ settings.full_name = Vollständiger Name settings.website = Webseite settings.location = Standort settings.update_settings = Aktualisierungseinstellungen -settings.update_setting_success = Einstellungen der Organisation wurden aktualisiert. +settings.update_setting_success = Organisationseinstellungen aktualisiert settings.delete = Organisation löschen settings.delete_account = Diese Organisation löschen settings.delete_prompt = Die Organisation wird dauerhaft gelöscht. Dies kann <strong>NICHT</strong> rückgängig gemacht werden! -settings.confirm_delete_account = Löschen bestätigen +settings.confirm_delete_account = Löschen members.public = Öffentlich members.public_helper = Privat machen @@ -297,7 +303,7 @@ teams.delete_team_success = Team gelöscht teams.read_permission_desc = Dieses Team erlaubt <strong>Lesezugriff</strong>: Mitglieder können Team-Repositorys einsehen und klonen. teams.write_permission_desc = Dieses Team erlaubt <strong>Schreibzugriff</strong>: Mitglieder können Team-Repositorys einsehen und hinein pushen. teams.admin_permission_desc = Diese Team erlaubt <strong>Adminzugriff</strong>: Mitglieder dieses Teams können pullen, pushen und dem Team Mitarbeiter hinzufügen. -teams.repositories = Team Repositorys +teams.repositories = Team-Repositorys teams.add_team_repository = Team-Repository hinzufügen teams.remove_repo = Entfernen @@ -319,8 +325,8 @@ dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Orga dashboard.operation_name = Operation Name dashboard.operation_switch = Switch dashboard.operation_run = Ausführen -dashboard.clean_unbind_oauth = ungebundene OAuthes bereinigen -dashboard.delete_inactivate_accounts = inaktiven Konten löschen +dashboard.clean_unbind_oauth = ungebundene OAuths bereinigen +dashboard.delete_inactivate_accounts = inaktive Konten löschen dashboard.server_uptime = Server-Uptime dashboard.current_goroutine = Aktuelle Goroutines dashboard.current_memory_usage = Aktuelle Speichernutzung @@ -332,7 +338,7 @@ dashboard.memory_free_times = Memory Free Times dashboard.current_heap_usage = Aktuelle Heap-Auslastung dashboard.heap_memory_obtained = erhaltener Heap-Memory dashboard.heap_memory_idle = unbenutzter Heap-Memory -dashboard.heap_memory_in_use = benutzer Heap-Memory +dashboard.heap_memory_in_use = benutzter Heap-Memory dashboard.heap_memory_released = freigegebener Heap-Memory dashboard.heap_objects = Heap-Objekte dashboard.bootstrap_stack_usage = Bootstrap-Stack-Auslastung @@ -343,26 +349,26 @@ dashboard.mcache_structures_usage = MCache-Structures-Auslastung dashboard.mcache_structures_obtained = erhaltene MCache-Structures dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained dashboard.gc_metadata_obtained = erhaltene GC-Metadata -dashboard.other_system_allocation_obtained = andere erhaltene Sustem-Allokatoren +dashboard.other_system_allocation_obtained = andere erhaltene System-Allokatoren dashboard.next_gc_recycle = nächster GC-Zyklus -dashboard.last_gc_time = seit leztem GC-Zyklus +dashboard.last_gc_time = seit letztem GC-Zyklus dashboard.total_gc_time = gesammte GC-Zeit dashboard.total_gc_pause = gesammte GC-Pause dashboard.last_gc_pause = letzte GC-Pause dashboard.gc_times = GC-Takt -users.user_manage_panel = Benutzerverwaltung +users.user_manage_panel = Benutzer users.new_account = Neues Konto erstellen users.name = Name users.activated = Aktiviert users.admin = Admin -users.repos = Repos +users.repos = Repositorys users.created = Erzeugt users.edit = Bearbeiten users.auth_source = Auth-Quelle users.local = Lokal users.auth_login_name = Auth-Login-Name -users.update_profile_success = Kontoprofil wurde erfolgreich aktualisiert. +users.update_profile_success = Kontoprofil aktualisiert users.edit_account = Konto bearbeiten users.is_activated = Dieses Konto ist aktiviert users.is_admin = Dieses Konto hat Administratorrechte @@ -375,7 +381,7 @@ orgs.name = Name orgs.teams = Teams orgs.members = Mitglieder -repos.repo_manage_panel = Repositoryverwaltung +repos.repo_manage_panel = Repositorys repos.owner = Besitzer repos.name = Name repos.private = Privat @@ -383,12 +389,12 @@ repos.watches = Watches repos.stars = Stars repos.issues = Issues -auths.auth_manage_panel = Authentifizierungsverwaltung +auths.auth_manage_panel = Authentifizierung auths.new = Neu Authentifizierungsquelle hinzufügen auths.name = Name auths.type = Typ -auths.enabled = Aktiviert -auths.updated = Aktualisiert +auths.enabled = aktiviert +auths.updated = aktualisiert auths.auth_type = Authentifizierungstyp auths.auth_name = Authentifizierungsname auths.domain = Domain @@ -398,15 +404,15 @@ auths.base_dn = Base DN auths.attributes = Suchattribute auths.filter = Suchfilter auths.ms_ad_sa = Ms Ad SA -auths.smtp_auth = SMTP Authentifizierungstyp -auths.smtphost = SMTP Host -auths.smtpport = SMTP Port +auths.smtp_auth = SMTP-Authentifizierungstyp +auths.smtphost = SMTP-Host +auths.smtpport = SMTP-Port auths.enable_tls = TLS-Verschlüsselung aktivieren auths.enable_auto_register = Automatische Registrierung aktivieren auths.tips = Tipps auths.edit = Authentifizierungseinstellungen bearbeiten auths.activated = Diese Authentifizierung ist aktiviert -auths.update_success = Authentifizierungseinstellungen wurde erfolgreich aktualisiert. +auths.update_success = Authentifizierungseinstellungen aktualisiert auths.update = Authentifizierungseinstellungen aktualisieren auths.delete = Authentifizierung löschen @@ -433,15 +439,15 @@ config.db_ssl_mode = SSL-Modus config.db_ssl_mode_helper = (nur für "postgres") config.db_path = Verzeichnis config.db_path_helper = (nur für "sqlite3") -config.service_config = Service Einstellungen -config.register_email_confirm = E-Mail Bestätigung bei Registrierung +config.service_config = Service-Einstellungen +config.register_email_confirm = E-Mail-Bestätigung bei Registrierung config.disable_register = Registrierung deaktivieren config.require_sign_in_view = Require Sign In View -config.mail_notify = E-Mail Benachrichtigung +config.mail_notify = E-Mail-Benachrichtigung config.enable_cache_avatar = Avatar-Cache aktivieren config.active_code_lives = Active Code Lives config.reset_password_code_lives = Reset Password Code Lives -config.webhook_config = Webhook Einstellungen +config.webhook_config = Webhook-Einstellungen config.task_interval = Task-Intervall config.deliver_timeout = Zeitlimit für Zustellung config.mailer_config = Mailer-Einstellungen @@ -449,28 +455,28 @@ config.mailer_enabled = Aktiviert config.mailer_name = Name config.mailer_host = Host config.mailer_user = Benutzer -config.oauth_config = OAuth Einstellungen +config.oauth_config = OAuth-Einstellungen config.oauth_enabled = Aktiviert -config.cache_config = Cache Einstellungen -config.cache_adapter = Cache Adapter -config.cache_interval = Cache Intervall -config.cache_conn = Cache Anbindung -config.session_config = Session Einstellungen -config.session_provider = Session Provider -config.provider_config = Provider Einstellungen -config.cookie_name = Cookie Name +config.cache_config = Cache-Einstellungen +config.cache_adapter = Cache-Adapter +config.cache_interval = Cache-Intervall +config.cache_conn = Cache-Anbindung +config.session_config = Session-Einstellungen +config.session_provider = Session-Provider +config.provider_config = Provider-Einstellungen +config.cookie_name = Cookie-Name config.enable_set_cookie = Enable Set Cookie config.gc_interval_time = GC-Intervallzeit -config.session_life_time = Session Lebensdauer +config.session_life_time = Session-Lebensdauer config.https_only = nur HTTPS -config.cookie_life_time = Cookie Lebensdauer -config.session_hash_function = Session-ID Hashfunktion -config.session_hash_key = Session-ID Hashschlüssel +config.cookie_life_time = Cookie-Lebensdauer +config.session_hash_function = Session-ID-Hashfunktion +config.session_hash_key = Session-ID-Hashschlüssel config.picture_config = Bildeinstellungen config.picture_service = Bildservice config.disable_gravatar = Gravatar deaktivieren -config.log_config = Log Einstellungen -config.log_mode = Log Modus +config.log_config = Log-Einstellungen +config.log_mode = Log-Modus monitor.cron = Cron-Tasks monitor.name = Name @@ -509,16 +515,3 @@ months = %d Monate %s years = %d Jahre %s raw_seconds = Sekunden raw_minutes = Minuten - - - - - - - - - - - - - diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..44891200 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,89 @@ +Docker +====== + +TOOLS ARE WRITTEN FOR TESTING AND TO SEE WHAT IT IS! + +For this to work you will need the nifty docker tool [fig]. + +The most simple setup will look like this: + +```sh +./assemble_blocks.sh docker_gogs w_db option_db_mysql +fig up + +``` + +That's it. You have GoGS running in docker linked to a MySQL docker container. + +Now visit http://localhost:3000/ and give details for the admin account an you're up and running. + + +How does it work +---------------- + +`./assemble_blocks.sh` will look in `blocks` for subdirectories. +In the subdirectories there are three relevant files: `Dockerfile`, `config` and `fig`. + +`Dockerfile` will be copied to `docker/` (also means last `Dockerfile` wins). + +The `config` file contains lines which will in the gogs docker container end up in `$GOGS_PATH/custom/config/app.ini` and by this gogs will be configured. +Here you can define things like the MySQL server for your database block. + +The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers. +This inculdes container linking! + +Just have a look at them and it will be clear how to write your own blocks. + +Just some things + + - all files (`Dockerfile`, `fig` and `config`) are optional + - the gogs block should always be the first block + +Currently the blocks are designed that, the blocks that start with `docker` pull in the base docker image. +Then one block starting with `w` defines, what containers should be linked to the gogs container. +For every option in the `w` block you need to add an `option` container. + +Example: + +```sh +./assemble_blocks.sh docker_gogs w_db_cache option_db_mysql option_cache_redis +``` + + +More sophisticated Example +-------------------------- + +Her is a more elaborated example + +```sh +./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql +fig up +``` + +This will set up four containters and link them proberly. One for each of + + - gogs + - database (postgresql) + - cache (redis) + - session (mysql) + +WARNING: This will not work at the Moment! MySQL session is broken! + + +Remark +------ + +After you execute `assemble_blocks.sh` you should always trigger `fig build` to inculde the the new init script `init_gogs.sh` in the docker image. + +If you want to use another GoGS docker file, but keep everything else the same, you can create a block, e.g. `docker_gogs_custom`, with only a `Dockerfile` and call + +```sh +./assemble_blocks.sh docker_gogs_custom w_db option_database_mysql +``` + +This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `docker_gogs`. + +`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev` + + +[fig]:http://www.fig.sh/
\ No newline at end of file diff --git a/docker/assemble_blocks.sh b/docker/assemble_blocks.sh new file mode 100755 index 00000000..852064de --- /dev/null +++ b/docker/assemble_blocks.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +blocks_dir=blocks +docker_dir=docker +template_dir=templates + +docker_file=Dockerfile + +gogs_config_file=conf.tmp +gogs_config=config +gogs_init_file=$docker_dir/init_gogs.sh + +fig_file=fig.yml +fig_config=fig + +gogs_init_template=$template_dir/init_gogs.sh.tpl + +if [ "$#" == 0 ]; then + blocks=`ls $blocks_dir` + if [ -z "$blocks" ]; then + echo "No Blocks available in $blocks_dir" + else + echo "Available Blocks:" + for block in $blocks; do + echo " $block" + done + fi + exit 0 +fi + +for file in $gogs_config_file $fig_file; do + if [ -e $file ]; then + echo "Deleting $file" + rm $file + fi +done + +for dir in $@; do + current_dir=$blocks_dir/$dir + if [ ! -d "$current_dir" ]; then + echo "$current_dir is not a directory" + exit 1 + fi + + if [ -e $current_dir/$docker_file ]; then + echo "Copying $current_dir/$docker_file to $docker_dir/$docker_file" + cp $current_dir/$docker_file $docker_dir/$docker_file + fi + + if [ -e $current_dir/$gogs_config ]; then + echo "Adding $current_dir/$gogs_config to $gogs_config_file" + cat $current_dir/$gogs_config >> $gogs_config_file + echo "" >> $gogs_config_file + fi + + if [ -e $current_dir/$fig_config ]; then + echo "Adding $current_dir/$fig_config to $fig_file" + cat $current_dir/fig >> $fig_file + echo "" >> $fig_file + fi +done + +echo "Creating $gogs_init_file" +sed "/{{ CONFIG }}/{ +r $gogs_config_file +d +}" $gogs_init_template > $gogs_init_file + +if [ -e $gogs_config_file ]; then + echo "Removing temporary GoGS config" + rm $gogs_config_file +fi
\ No newline at end of file diff --git a/docker/blocks/docker_gogs/Dockerfile b/docker/blocks/docker_gogs/Dockerfile new file mode 100644 index 00000000..e2e056ae --- /dev/null +++ b/docker/blocks/docker_gogs/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:14.04 + +# This part is taken from the official docker image -------------------- + +RUN apt-get update && apt-get install -y \ + build-essential ca-certificates curl \ + bzr git mercurial \ + --no-install-recommends + +ENV GOLANG_VERSION 1.3 + +RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ + | tar -v -C /usr/src -xz +WORKDIR /usr/src/go + +RUN cd src && ./make.bash --no-clean 2>&1 + +ENV PATH /usr/src/go/bin:$PATH + +RUN mkdir -p /go/src +ENV GOPATH /go +ENV PATH /go/bin:$PATH +WORKDIR /go + +# ---------------------------------------------------------------------- + + +RUN useradd -m git + +ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs +ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf +ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini + +RUN go get -u -d github.com/gogits/gogs +# WORKDIR $GOGS_PATH +WORKDIR /go/src/github.com/gogits/gogs +RUN go build github.com/gogits/gogs +RUN chown -R git $GOGS_PATH + +ADD init_gogs.sh /tmp/ +RUN chown git /tmp/init_gogs.sh +RUN chmod +x /tmp/init_gogs.sh + +USER git +ENV HOME /home/git +ENV USER git +ENV PATH $GOGS_PATH:$PATH + +RUN git config --global user.name "GoGS" + +ENTRYPOINT ["/tmp/init_gogs.sh"] +CMD ["gogs", "web"] diff --git a/docker/blocks/docker_gogs_dev/Dockerfile b/docker/blocks/docker_gogs_dev/Dockerfile new file mode 100644 index 00000000..1c001e2c --- /dev/null +++ b/docker/blocks/docker_gogs_dev/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:14.04 + +# This part is taken from the official docker image -------------------- + +RUN apt-get update && apt-get install -y \ + build-essential ca-certificates curl \ + bzr git mercurial \ + --no-install-recommends + +ENV GOLANG_VERSION 1.3 + +RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \ + | tar -v -C /usr/src -xz +WORKDIR /usr/src/go + +RUN cd src && ./make.bash --no-clean 2>&1 + +ENV PATH /usr/src/go/bin:$PATH + +RUN mkdir -p /go/src +ENV GOPATH /go +ENV PATH /go/bin:$PATH +WORKDIR /go + +# ---------------------------------------------------------------------- + + +RUN useradd -m git + +ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs +ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf +ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini + +RUN go get -u -d github.com/gogits/gogs +# WORKDIR $GOGS_PATH +WORKDIR /go/src/github.com/gogits/gogs +RUN git checkout dev; go get -u; git checkout dev; go build +RUN chown -R git $GOGS_PATH + +ADD init_gogs.sh /tmp/ +RUN chown git /tmp/init_gogs.sh +RUN chmod +x /tmp/init_gogs.sh + +USER git +ENV HOME /home/git +ENV USER git +ENV PATH $GOGS_PATH:$PATH + +RUN git config --global user.name "GoGS" + +ENTRYPOINT ["/tmp/init_gogs.sh"] +CMD ["gogs", "web"] diff --git a/docker/blocks/option_cache_memcache/config b/docker/blocks/option_cache_memcache/config new file mode 100644 index 00000000..daca6f3e --- /dev/null +++ b/docker/blocks/option_cache_memcache/config @@ -0,0 +1,3 @@ +[cache] +DB_TYPE = memcache +HOST = HOST = ${CACHE_1_PORT_11211_TCP_ADDR}:${CACHE_1_PORT_11211_TCP_PORT} diff --git a/docker/blocks/option_cache_memcache/fig b/docker/blocks/option_cache_memcache/fig new file mode 100644 index 00000000..80d0215c --- /dev/null +++ b/docker/blocks/option_cache_memcache/fig @@ -0,0 +1,2 @@ +cache: + image: sylvainlasnier/memcached:latest diff --git a/docker/blocks/option_cache_redis/config b/docker/blocks/option_cache_redis/config new file mode 100644 index 00000000..648f4f38 --- /dev/null +++ b/docker/blocks/option_cache_redis/config @@ -0,0 +1,3 @@ +[cache] +DB_TYPE = redis +HOST = ${CACHE_1_PORT_6379_TCP_ADDR}:${CACHE_1_PORT_6379_TCP_PORT} diff --git a/docker/blocks/option_cache_redis/fig b/docker/blocks/option_cache_redis/fig new file mode 100644 index 00000000..0e74bc4a --- /dev/null +++ b/docker/blocks/option_cache_redis/fig @@ -0,0 +1,2 @@ +cache: + image: redis:latest diff --git a/docker/blocks/option_db_mysql/config b/docker/blocks/option_db_mysql/config new file mode 100644 index 00000000..53f8949d --- /dev/null +++ b/docker/blocks/option_db_mysql/config @@ -0,0 +1,6 @@ +[database] +DB_TYPE = mysql +HOST = ${DB_1_PORT_3306_TCP_ADDR}:${DB_1_PORT_3306_TCP_PORT} +NAME = ${DB_1_ENV_MYSQL_DATABASE} +USER = ${DB_1_ENV_MYSQL_USER} +PASSWD = ${DB_1_ENV_MYSQL_PASSWORD} diff --git a/docker/blocks/option_db_mysql/fig b/docker/blocks/option_db_mysql/fig new file mode 100644 index 00000000..a005a059 --- /dev/null +++ b/docker/blocks/option_db_mysql/fig @@ -0,0 +1,7 @@ +db: + image: mysql:latest + environment: + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_DATABASE: gogs + MYSQL_USER: gogs + MYSQL_PASSWORD: password diff --git a/docker/blocks/option_db_postgresql/config b/docker/blocks/option_db_postgresql/config new file mode 100644 index 00000000..e5946b06 --- /dev/null +++ b/docker/blocks/option_db_postgresql/config @@ -0,0 +1,6 @@ +[database] +DB_TYPE = postgres +HOST = ${DB_1_PORT_5432_TCP_ADDR}:${DB_1_PORT_5432_TCP_PORT} +NAME = ${DB_1_ENV_POSTGRESQL_DB} +USER = ${DB_1_ENV_POSTGRESQL_USER} +PASSWD = ${DB_1_ENV_POSTGRESQL_PASS} diff --git a/docker/blocks/option_db_postgresql/fig b/docker/blocks/option_db_postgresql/fig new file mode 100644 index 00000000..c839e904 --- /dev/null +++ b/docker/blocks/option_db_postgresql/fig @@ -0,0 +1,6 @@ +db: + image: wyaeld/postgres:9.3 + environment: + POSTGRESQL_DB: gogs + POSTGRESQL_USER: gogs + POSTGRESQL_PASS: password diff --git a/docker/blocks/option_session_mysql/config b/docker/blocks/option_session_mysql/config new file mode 100644 index 00000000..b8bc2cc7 --- /dev/null +++ b/docker/blocks/option_session_mysql/config @@ -0,0 +1,3 @@ +[session] +PROVIDER = mysql +PROVIDER_CONFIG = ${SESSION_1_ENV_MYSQL_USER}:${SESSION_1_ENV_MYSQL_PASSWORD}@SESSION_1_PORT_3306_TCP_PROTO(${SESSION_1_PORT_3306_TCP_ADDR}:${SESSION_1_PORT_3306_TCP_PORT})/${SESSION_1_ENV_MYSQL_DATABASE} diff --git a/docker/blocks/option_session_mysql/fig b/docker/blocks/option_session_mysql/fig new file mode 100644 index 00000000..0e2dbf19 --- /dev/null +++ b/docker/blocks/option_session_mysql/fig @@ -0,0 +1,7 @@ +session: + image: mysql:latest + environment: + MYSQL_ROOT_PASSWORD: rootpass + MYSQL_DATABASE: gogs_session + MYSQL_USER: gogs + MYSQL_PASSWORD: password diff --git a/docker/blocks/w_cache/fig b/docker/blocks/w_cache/fig new file mode 100644 index 00000000..fd66c357 --- /dev/null +++ b/docker/blocks/w_cache/fig @@ -0,0 +1,6 @@ +gogs: + build: docker + links: + - cache + ports: + - "3000:3000" diff --git a/docker/blocks/w_cache_session/fig b/docker/blocks/w_cache_session/fig new file mode 100644 index 00000000..0f901140 --- /dev/null +++ b/docker/blocks/w_cache_session/fig @@ -0,0 +1,7 @@ +gogs: + build: docker + links: + - cache + - session + ports: + - "3000:3000" diff --git a/docker/blocks/w_db/fig b/docker/blocks/w_db/fig new file mode 100644 index 00000000..a7e9c1b6 --- /dev/null +++ b/docker/blocks/w_db/fig @@ -0,0 +1,6 @@ +gogs: + build: docker + links: + - db + ports: + - "3000:3000" diff --git a/docker/blocks/w_db_cache/fig b/docker/blocks/w_db_cache/fig new file mode 100644 index 00000000..42402e40 --- /dev/null +++ b/docker/blocks/w_db_cache/fig @@ -0,0 +1,7 @@ +gogs: + build: docker + links: + - db + - cache + ports: + - "3000:3000" diff --git a/docker/blocks/w_db_cache_session/fig b/docker/blocks/w_db_cache_session/fig new file mode 100644 index 00000000..42444405 --- /dev/null +++ b/docker/blocks/w_db_cache_session/fig @@ -0,0 +1,8 @@ +gogs: + build: docker + links: + - db + - cache + - session + ports: + - "3000:3000" diff --git a/docker/blocks/w_db_session/fig b/docker/blocks/w_db_session/fig new file mode 100644 index 00000000..3703c6ba --- /dev/null +++ b/docker/blocks/w_db_session/fig @@ -0,0 +1,7 @@ +gogs: + build: docker + links: + - db + - session + ports: + - "3000:3000" diff --git a/docker/blocks/w_none/fig b/docker/blocks/w_none/fig new file mode 100644 index 00000000..c0fed209 --- /dev/null +++ b/docker/blocks/w_none/fig @@ -0,0 +1,4 @@ +gogs: + build: docker + ports: + - "3000:3000" diff --git a/docker/blocks/w_session/fig b/docker/blocks/w_session/fig new file mode 100644 index 00000000..7dda0dde --- /dev/null +++ b/docker/blocks/w_session/fig @@ -0,0 +1,6 @@ +gogs: + build: docker + links: + - session + ports: + - "3000:3000" diff --git a/docker/docker/.gitkeep b/docker/docker/.gitkeep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/docker/docker/.gitkeep diff --git a/docker/templates/init_gogs.sh.tpl b/docker/templates/init_gogs.sh.tpl new file mode 100644 index 00000000..26cff4e5 --- /dev/null +++ b/docker/templates/init_gogs.sh.tpl @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ ! -d "$DIRECTORY" ]; then + mkdir -p $GOGS_CUSTOM_CONF_PATH + +echo " +{{ CONFIG }} +" >> $GOGS_CUSTOM_CONF + +fi + +exec "$@" diff --git a/dockerfiles/README.md b/dockerfiles/README.md deleted file mode 100644 index 11d28d0f..00000000 --- a/dockerfiles/README.md +++ /dev/null @@ -1,40 +0,0 @@ -### Install Gogs With Docker - -Deploying gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the configs: - -``` -DB_TYPE="YOUR_DB_TYPE" # type of database, support 'mysql' and 'postgres' -MEM_TYPE="YOUR_MEM_TYPE" # type of memory database, support 'redis' and 'memcache' -DB_PASSWORD="YOUR_DB_PASSWORD" # The database password. -DB_RUN_NAME="YOUR_DB_RUN_NAME" # The --name option value when run the database image. -MEM_RUN_NAME="YOUR_MEM_RUN_NAME" # The --name option value when run the mem database image. -HOST_PORT="YOUR_HOST_PORT" # The port on host, which will be redirected to the port 3000 inside gogs container. -``` - -And run: -``` -cd dockerfiles -./build.sh -``` - -The build might take some time, just be patient. After it finishes, you will receive the message: - -``` -Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service( the content might be different, according to your own configs): - docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs -``` - -Just follow the message, run: - -``` - docker run -i -t --link YOUR_DB_RUN_NAME:db --link YOUR_MEM_RUN_NAME:mem -p YOUR_HOST_PORT:3000 gogits/gogs -``` - -Now we have gogs running! Open the browser and navigate to: - -``` -http://YOUR_HOST_IP:YOUR_HOST_PORT -``` - -Let's 'gogs'! -Ouya~ diff --git a/models/action.go b/models/action.go index d536c84d..f739fc35 100644 --- a/models/action.go +++ b/models/action.go @@ -172,7 +172,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com // CommitRepoAction adds new action for committing repository. func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, - repoId int64, repoUserName, repoName string, refFullName string, commit *base.PushCommits) error { + repoId int64, repoUserName, repoName string, refFullName string, commit *base.PushCommits, oldCommitId string, newCommitId string) error { opType := COMMIT_REPO // Check it's tag push or branch. @@ -226,6 +226,11 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, } repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) + compareUrl := "" + // if not the first commit, set the compareUrl + if !strings.HasPrefix(oldCommitId, "0000000") { + compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId) + } commits := make([]*PayloadCommit, len(commit.Commits)) for i, cmt := range commit.Commits { commits[i] = &PayloadCommit{ @@ -258,6 +263,9 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, Name: repo.Owner.LowerName, Email: repo.Owner.Email, }, + Before: oldCommitId, + After: newCommitId, + CompareUrl: compareUrl, } for _, w := range ws { diff --git a/models/git_diff.go b/models/git_diff.go index 4b4d1234..21a624de 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -175,25 +175,30 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) { return diff, nil } -func GetDiff(repoPath, commitid string) (*Diff, error) { +func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff, error) { repo, err := git.OpenRepository(repoPath) if err != nil { return nil, err } - commit, err := repo.GetCommit(commitid) + commit, err := repo.GetCommit(afterCommitId) if err != nil { return nil, err } rd, wr := io.Pipe() var cmd *exec.Cmd - // First commit of repository. - if commit.ParentCount() == 0 { - cmd = exec.Command("git", "show", commitid) + // if "after" commit given + if beforeCommitId == "" { + // First commit of repository. + if commit.ParentCount() == 0 { + cmd = exec.Command("git", "show", afterCommitId) + } else { + c, _ := commit.Parent(0) + cmd = exec.Command("git", "diff", c.Id.String(), afterCommitId) + } } else { - c, _ := commit.Parent(0) - cmd = exec.Command("git", "diff", c.Id.String(), commitid) + cmd = exec.Command("git", "diff", beforeCommitId, afterCommitId) } cmd.Dir = repoPath cmd.Stdout = wr @@ -208,7 +213,7 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { }() defer rd.Close() - desc := fmt.Sprintf("GetDiff(%s)", repoPath) + desc := fmt.Sprintf("GetDiffRange(%s)", repoPath) pid := process.Add(desc, cmd) go func() { // In case process became zombie. @@ -226,3 +231,7 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { return ParsePatch(pid, cmd, rd) } + +func GetDiffCommit(repoPath, commitId string) (*Diff, error) { + return GetDiffRange(repoPath, "", commitId) +} diff --git a/models/slack.go b/models/slack.go index 0a557409..3dd40759 100644 --- a/models/slack.go +++ b/models/slack.go @@ -70,19 +70,26 @@ func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { branchName := refSplit[len(refSplit)-1] var commitString string - // TODO: add commit compare before/after link when gogs adds it if len(p.Commits) == 1 { commitString = "1 new commit" + if p.CompareUrl != "" { + commitString = SlackLinkFormatter(p.CompareUrl, commitString) + } } else { commitString = fmt.Sprintf("%d new commits", len(p.Commits)) + if p.CompareUrl != "" { + commitString = SlackLinkFormatter(p.CompareUrl, commitString) + } } - text := fmt.Sprintf("[%s:%s] %s pushed by %s", p.Repo.Name, branchName, commitString, p.Pusher.Name) + repoLink := SlackLinkFormatter(p.Repo.Url, p.Repo.Name) + branchLink := SlackLinkFormatter(p.Repo.Url+"/src/"+branchName, branchName) + text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.Name) var attachmentText string // for each commit, generate attachment text for i, commit := range p.Commits { - attachmentText += fmt.Sprintf("<%s|%s>: %s - %s", commit.Url, commit.Id[:7], SlackFormatter(commit.Message), commit.Author.Name) + attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.Url, commit.Id[:7]), SlackTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name)) // add linebreak to each commit but the last if i < len(p.Commits)-1 { attachmentText += "\n" @@ -103,7 +110,7 @@ func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { } // see: https://api.slack.com/docs/formatting -func SlackFormatter(s string) string { +func SlackTextFormatter(s string) string { // take only first line of commit first := strings.Split(s, "\n")[0] // replace & < > @@ -112,3 +119,7 @@ func SlackFormatter(s string) string { first = strings.Replace(first, ">", ">", -1) return first } + +func SlackLinkFormatter(url string, text string) string { + return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text)) +} diff --git a/models/update.go b/models/update.go index 68a92ada..ec6a9790 100644 --- a/models/update.go +++ b/models/update.go @@ -101,7 +101,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName commit := &base.PushCommits{} if err = CommitRepoAction(userId, ru.Id, userName, actEmail, - repos.Id, repoUserName, repoName, refName, commit); err != nil { + repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil { log.GitLogger.Fatal(4, "runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) } return err @@ -152,7 +152,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) if err = CommitRepoAction(userId, ru.Id, userName, actEmail, - repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { + repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}, oldCommitId, newCommitId); err != nil { return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) } return nil diff --git a/models/webhook.go b/models/webhook.go index 55ed4844..0b7b3a99 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -169,11 +169,14 @@ type BasePayload interface { // Payload represents a payload information of hook. type Payload struct { - Secret string `json:"secret"` - Ref string `json:"ref"` - Commits []*PayloadCommit `json:"commits"` - Repo *PayloadRepo `json:"repository"` - Pusher *PayloadAuthor `json:"pusher"` + Secret string `json:"secret"` + Ref string `json:"ref"` + Commits []*PayloadCommit `json:"commits"` + Repo *PayloadRepo `json:"repository"` + Pusher *PayloadAuthor `json:"pusher"` + Before string `json:"before"` + After string `json:"after"` + CompareUrl string `json:"compare_url"` } func (p Payload) GetJSONPayload() ([]byte, error) { diff --git a/public/css/gogs.css b/public/css/gogs.css index 2d30d062..0af09a3e 100755 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -968,6 +968,13 @@ body { .guide-box .zclip { left: auto !important; } +div.compare div#commits { + margin-top: 5px; +} +div.compare div#commits h4 { + margin: 10px 0; + line-height: 1.1; +} .diff-head-box h4 { margin-top: 0; margin-bottom: 0; diff --git a/routers/repo/commit.go b/routers/repo/commit.go index 6320123b..54acc85b 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -114,9 +114,9 @@ func Diff(ctx *middleware.Context) { commit := ctx.Repo.Commit - diff, err := models.GetDiff(models.RepoPath(userName, repoName), commitId) + diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName), commitId) if err != nil { - ctx.Handle(404, "GetDiff", err) + ctx.Handle(404, "GetDiffCommit", err) return } @@ -162,6 +162,67 @@ func Diff(ctx *middleware.Context) { ctx.HTML(200, DIFF) } +func CompareDiff(ctx *middleware.Context) { + ctx.Data["IsRepoToolbarCommits"] = true + ctx.Data["IsDiffCompare"] = true + userName := ctx.Repo.Owner.Name + repoName := ctx.Repo.Repository.Name + beforeCommitId := ctx.Params(":before") + afterCommitId := ctx.Params(":after") + + commit, err := ctx.Repo.GitRepo.GetCommit(afterCommitId) + if err != nil { + ctx.Handle(404, "GetCommit", err) + return + } + + diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId, afterCommitId) + if err != nil { + ctx.Handle(404, "GetDiffRange", err) + return + } + + isImageFile := func(name string) bool { + blob, err := commit.GetBlobByPath(name) + if err != nil { + return false + } + + dataRc, err := blob.Data() + if err != nil { + return false + } + buf := make([]byte, 1024) + n, _ := dataRc.Read(buf) + if n > 0 { + buf = buf[:n] + } + _, isImage := base.IsImageFile(buf) + return isImage + } + + commits, err := commit.CommitsBeforeUntil(beforeCommitId) + if err != nil { + ctx.Handle(500, "CommitsBeforeUntil", err) + return + } + + ctx.Data["Commits"] = commits + ctx.Data["CommitCount"] = commits.Len() + ctx.Data["BeforeCommitId"] = beforeCommitId + ctx.Data["AfterCommitId"] = afterCommitId + ctx.Data["Username"] = userName + ctx.Data["Reponame"] = repoName + ctx.Data["IsImageFile"] = isImageFile + ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitId) + "..." + base.ShortSha(afterCommitId) + " · " + userName + "/" + repoName + ctx.Data["Commit"] = commit + ctx.Data["Diff"] = diff + ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 + ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", afterCommitId) + ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", afterCommitId) + ctx.HTML(200, DIFF) +} + func FileHistory(ctx *middleware.Context) { ctx.Data["IsRepoToolbarCommits"] = true diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 420e973a..e7518e98 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -3,47 +3,6 @@ {{template "repo/nav" .}} {{template "repo/toolbar" .}} <div id="body" class="container"> - <div id="commits"> - <div class="panel panel-default commit-box info-box"> - <div class="panel-heading info-head"> - <form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> - <div class="input-group"> - <input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" /> - <div class="input-group-btn"> - <button type="submit" class="btn btn-default">Find</button> - </div> - </div> - </form> - <h4>{{.CommitCount}} Commits</h4> - </div> - <table class="panel-footer table commit-list table table-striped"> - <thead> - <tr> - <th class="author">Author</th> - <th class="sha">SHA1</th> - <th class="message">Message</th> - <th class="date">Date</th> - </tr> - </thead> - <tbody> - {{ $username := .Username}} - {{ $reponame := .Reponame}} - {{$r := List .Commits}} - {{range $r}} - <tr> - <td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td> - <td class="sha"><a rel="nofollow" class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> - <td class="message">{{.Summary}} </td> - <td class="date">{{TimeSince .Author.When $.Lang}}</td> - </tr> - {{end}} - </tbody> - </table> - </div> - {{if not .IsSearchPage}}<ul class="pagination" id="commits-pager"> - {{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} - {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} - </ul>{{end}} - </div> + {{template "repo/commits_table" .}} </div> {{template "base/footer" .}} diff --git a/templates/repo/commits_table.tmpl b/templates/repo/commits_table.tmpl new file mode 100644 index 00000000..4612398a --- /dev/null +++ b/templates/repo/commits_table.tmpl @@ -0,0 +1,42 @@ +<div id="commits"> + <div class="panel panel-default commit-box info-box"> + <div class="panel-heading info-head"> + <form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> + <div class="input-group"> + <input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" /> + <div class="input-group-btn"> + <button type="submit" class="btn btn-default">Find</button> + </div> + </div> + </form> + <h4>{{.CommitCount}} Commits</h4> + </div> + <table class="panel-footer table commit-list table table-striped"> + <thead> + <tr> + <th class="author">Author</th> + <th class="sha">SHA1</th> + <th class="message">Message</th> + <th class="date">Date</th> + </tr> + </thead> + <tbody> + {{ $username := .Username}} + {{ $reponame := .Reponame}} + {{$r := List .Commits}} + {{range $r}} + <tr> + <td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td> + <td class="sha"><a rel="nofollow" class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> + <td class="message">{{.Summary}} </td> + <td class="date">{{TimeSince .Author.When $.Lang}}</td> + </tr> + {{end}} + </tbody> + </table> + </div> + {{if not .IsSearchPage}}<ul class="pagination" id="commits-pager"> + {{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} + {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} + </ul>{{end}} +</div> diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index 6adea045..78733450 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -3,9 +3,20 @@ {{template "repo/nav" .}} <div id="body" class="container" data-page="repo"> <div id="source"> + {{if .IsDiffCompare }} <div class="panel panel-info diff-box diff-head-box"> <div class="panel-heading"> <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> + <h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-success">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-success">{{ShortSha .AfterCommitId}}</a></h4> + </div> + <div class="panel-body compare"> + {{template "repo/commits_table" .}} + </div> + </div> + {{else}} + <div class="panel panel-info diff-box diff-head-box"> + <div class="panel-heading"> + <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> <h4>{{.Commit.Message}}</h4> </div> <div class="panel-body"> @@ -22,9 +33,9 @@ <a class="name" href="/user/email2user?email={{.Commit.Author.Email}}"><strong>{{.Commit.Author.Name}}</strong></a> <span class="time">{{TimeSince .Commit.Author.When $.Lang}}</span> </p> - </div> + </div> </div> - + {{end}} {{if .DiffNotAvailable}} <h4>Diff Data Not Available.</h4> {{else}} |