Control: tags -1 -moreinfo On Saturday 15 April 2017 01:24 AM, Niels Thykier wrote: > Sorry for the delay in getting back to you.
Thanks for the detailed review. > > * In the postrm (RC bug): > > """ > su ${gitlab_user} -c 'psql gitlab_production -c ""' && \ > su postgres -c "dropdb gitlab_production" > """ > > This does not appear to be idempotent. If the database is dropped but a > later part of the purge fails, then this line will prevent dpkg from > rerunning the purge and reach the desired state (as the code is run > under "set -e") > > You probably want something like: > > """ > if su ${gitlab_user} -c 'psql gitlab_production -c ""'; then > su postgres -c "dropdb gitlab_production" > fi > """ done > A similar remark can be made for the following code where it would be > prudent to apply the same fix: > > """ > test -e ${gitlab_log_dir} && rm -rf ${gitlab_log_dir} > test -e ${gitlab_cache_path} && rm -rf ${gitlab_cache_path} > test -e ${gitlab_pid_path} && rm -rf ${gitlab_pid_path} > test -e ${gitlab_data_dir} && rm -rf ${gitlab_data_dir} > [...] > id -u ${gitlab_user} && userdel -r ${gitlab_user} > > [...] > test -f ${nginx_site} && echo "Found nginx site...." > [...] > # remove the configuration file itself > test -f ${nginx_site} && rm -f ${nginx_site} > test -f ${gitlab_debian_conf} && rm -f ${gitlab_debian_conf} > test -f ${gitlab_yml} && rm -f ${gitlab_yml} > test -f ${gitlab_tmpfiles} && rm -f ${gitlab_tmpfiles} > test -f ${gitlab_shell_config} && rm -f ${gitlab_shell_config} > [...] > test -n "${nginx_site}" && ucf --purge ${nginx_site} > test -n "${gitlab_debian_conf}" && ucf --purge ${gitlab_debian_conf} > test -n "${gitlab_yml}" && ucf --purge ${gitlab_yml} > test -n "${gitlab_tmpfiles}" && ucf --purge ${gitlab_tmpfiles} > test -n "${gitlab_shell_config}" && ucf -purge ${gitlab_shell_config} > [...] > test -n "${nginx_site}" && ucfr --purge gitlab ${nginx_site} > test -n "${gitlab_debian_conf}" && ucfr --purge gitlab > ${gitlab_debian_conf} > test -n "${gitlab_yml}" && ucfr --purge gitlab ${gitlab_yml} > test -n "${gitlab_tmpfiles}" && ucfr --purge gitlab ${gitlab_tmpfiles} > test -n "${gitlab_shell_config}" && ucfr -purge gitlab > ${gitlab_shell_config} > > """ This also done. > Note I got a follow up remark for the "id+userdel" line below. As for > the "test -n", these mean that the script will fail if these values are > not (still) present in the config OR worse - if the gitlab config is > already deleted (this is also listed a separate item below) > Changed to if; then;fi like above. > > * debian/postrm (RC bug): > > The postrm will fail if the admin removes the gitlab config files prior > to purging gitlab. This happens because then most of the variables are > set and as shown above, this will make several test statements evaluate > to false on the left-hand-side of an && under "set -e". > > Admittedly, this is partly mitigated by gitlab providing its own default > as a copy under /var/lib/gitlab/gitlab-debian.defaults. But in theory, > the machine could fail after removing > "/var/lib/gitlab/gitlab-debian.defaults" but prior to dpkg committing > that it had purged gitlab. > > It is an unlikely corner-case, but as it leaves the admin with an > unpurgeable package it is RC. To my knowledge, it is *not* sufficient > to make the removal of the /var/lib file the last thing. That just > narrows the window for the issue without fixing it. Now all conditions are inside if; then; fi blocks so it will ot fail if file is removed already. If the variables are not defined, it won't try deletion. > * debian/postrm (important) > > As I recall, the general consensus on handling of system users is that > we should lock them rather than remove them. The gitlab postrm deletes > the user: > > """ > id -u ${gitlab_user} && userdel -r ${gitlab_user} > """ > > That said, I believe gitlab is not the only package deleting the user, > so it is not RC. I have kept it like before for now. > * debian/config (important/RC bug): > > The config file uses the debconf database as a registry. It should > "pre-seed" itself with the defaults from the configuration files. See > "man 8 debconf-devel" under "config file handling": > > https://manpages.debian.org/jessie/debconf-doc/debconf-devel.7.en.html#ADVANCED_PROGRAMMING_WITH_DEBCONF > all variables are now seeded from config file. > * debian/postinst (RC bug): > > """ > # Override User for systemd services > for service in mailroom unicorn sidekiq workhorse; do > path=/etc/systemd/system/gitlab-${service}.service.d > mkdir -p $path > printf "[Service]\nUser=${gitlab_user}\n" > $path/override.conf > done > """ > > This part appears to override > "/etc/systemd/system/gitlab-${service}.service.d/override.conf" > completely, disregarding an existing file the admin may have created. > AFAICT, this happens on "configure" (i.e. it will also apply to > upgrades) - but even if it only happened on first install, it would > break admins who use puppet to push out a config file before installing > gitlab. Now it checks if the file already exist before writing it. > There is a similar snippet in the postrm, but it occurs only on purge, > so that should be fine. > > * debian/postinst (minor <-> RC bug, not sure): > > If the postinst script is rerun with a new gitlab user, then the > references in "${gitlab_debian_conf_private}" and > "${gitlab_yml_private}" is not updated. I suspect we are in the "RC > Bug" level because that means the postinst will use the wrong user when > using ucf to compare the "${gitlab_yml_private}" config with the actual > config. Now private copies are also updated. > * debian/{postinst,postrm} (possible RC bug): > > I am not entirely confident that the handling of gitlab user is sound in > case the admin uses a non-standard gitlab user and removes the config > file prior to purging. AFAICT, it will cause the postrm to attempt to > remove the "gitlab" user (which is the default name) rather than the > actual user. No, gitlab user is only defined in the config file (it is not in defaults). > Even if the postrm would gracefully handle that the default user does > not exist, then we still leave the system with an open system account > that should have been locked/deleted. I don't think we can do anything about an admin removing a config file and still expecting everything to work. > I wish I could say I had a proper solution for that, but I don't. I am > really not sure how to handle that gracefully AND correctly at the same > time. Worst case, the best/only option may be to undo making the gitlab > user name customizable. At the very least, it is a lot more complex > than we initially thought. Since this is a user facing option (it becomes part of the ssh url git@ or gitlab@), I'd like to keep it selectable. > * debian/README.Debian (minor): > > This file uses "export $(cat /etc/gitlab/gitlab-debian.conf)" in at > least 4 places, which will fail if there are comments in the config > file. It would be nice if those were fixed to source the file instead > like the maintainer scripts does. Updated. > > > I must admit, I am not entirely confident that I found all the possible > issues in the maintainer scripts. I would highly recommend a review > from another person once the above have been fixed. ok. In addition to the changes mentioned above, it also fixes the rc bug #858725
diff -Nru gitlab-8.13.11+dfsg/debian/changelog gitlab-8.13.11+dfsg1/debian/changelog --- gitlab-8.13.11+dfsg/debian/changelog 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/changelog 2017-04-20 11:47:49.000000000 +0530 @@ -1,3 +1,20 @@ +gitlab (8.13.11+dfsg1-1) unstable; urgency=medium + + [ Balasankar C ] + * Repack source to remove fuzzaldrin-plus.js (Closes: #858725) + + [ Pirate Praveen ] + * debian/postrm: Make checks idempotent (use if in place of &&) + * debian/postrm: Check variables are defined before using them + * debian/config: pre-seed variables to debconf db from config files + * debian/postinst: + - make sure all required variables are present in the config file + - handle reconfiguration correctly by reapplying variables from debconf db + to config files + - Don't touch systemd override.conf if already exist + + -- Pirate Praveen <prav...@debian.org> Thu, 20 Apr 2017 11:47:49 +0530 + gitlab (8.13.11+dfsg-8) unstable; urgency=medium * Don't fail if gitlab-debian.defaults not found (to support upgrading diff -Nru gitlab-8.13.11+dfsg/debian/conf/gitlab-debian.conf.example gitlab-8.13.11+dfsg1/debian/conf/gitlab-debian.conf.example --- gitlab-8.13.11+dfsg/debian/conf/gitlab-debian.conf.example 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/conf/gitlab-debian.conf.example 2017-04-19 15:11:34.000000000 +0530 @@ -1,3 +1,5 @@ +# Variables with all small letters are debian specific +# Variables with all caps are passed to gitlab app RAILS_ENV=production DB=postgres gitlab_app_root=/usr/share/gitlab diff -Nru gitlab-8.13.11+dfsg/debian/conf/gitlab.yml.example gitlab-8.13.11+dfsg1/debian/conf/gitlab.yml.example --- gitlab-8.13.11+dfsg/debian/conf/gitlab.yml.example 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/conf/gitlab.yml.example 2017-04-19 15:20:20.000000000 +0530 @@ -46,7 +46,7 @@ # relative_url_root: /gitlab # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') - user: GITLAB_USER + user: GITLAB_USER #gitlab_user (DON'T REMOVE THIS COMMENT) user_home: /var/lib/gitlab ## Date & Time settings diff -Nru gitlab-8.13.11+dfsg/debian/config gitlab-8.13.11+dfsg1/debian/config --- gitlab-8.13.11+dfsg/debian/config 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/config 2017-04-20 08:41:52.000000000 +0530 @@ -1,11 +1,25 @@ #!/bin/sh # config maintainer script for gitlab + +CONFIGFILE=/etc/gitlab/gitlab-debian.conf set -e # source debconf stuffs . /usr/share/debconf/confmodule +# Load config file, if it exists. + if [ -e $CONFIGFILE ]; then + . $CONFIGFILE || true + + # Store values from config file into + # debconf db. + db_set gitlab/fqdn "$GITLAB_HOST" + db_set gitlab/user "$gitlab_user" + db_set gitlab/ssl "${GITLAB_HTTPS:-false}" + db_set gitlab/letsencrypt "${gitlab_letsencrypt:-false}" + fi + # What is your fqdn? db_input high gitlab/fqdn || true db_go diff -Nru gitlab-8.13.11+dfsg/debian/copyright gitlab-8.13.11+dfsg1/debian/copyright --- gitlab-8.13.11+dfsg/debian/copyright 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/copyright 2017-04-17 09:36:08.000000000 +0530 @@ -3,6 +3,7 @@ Source: https://gitlab.com/gitlab-org/gitlab-ce Files-Excluded: vendor/assets/javascripts/clipboard.js + vendor/assets/javascripts/fuzzaldrin-plus.js vendor/assets/javascripts/jquery.cookie.js vendor/assets/javascripts/vue-resource.min.js vendor/assets/javascripts/vue.min.js diff -Nru gitlab-8.13.11+dfsg/debian/postinst gitlab-8.13.11+dfsg1/debian/postinst --- gitlab-8.13.11+dfsg/debian/postinst 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/postinst 2017-04-20 11:47:49.000000000 +0530 @@ -138,77 +138,121 @@ cd ${gitlab_app_root} # Obtain hostname from debconf db + echo "Configuring hostname and email..." db_get gitlab/fqdn - if [ "${RET}" != "" ]; then - if ! grep GITLAB_HOST ${gitlab_debian_conf_private}; then - echo "Configuring hostname and email..." - export GITLAB_HOST=${RET} # We need this to configure nginx below - cat <<EOF >> ${gitlab_debian_conf_private} -GITLAB_HOST=${RET} -GITLAB_EMAIL_FROM="no-reply@${RET}" -GITLAB_EMAIL_DISPLAY_NAME="Gitlab" -GITLAB_EMAIL_REPLY_TO="no-reply@${RET}" -EOF - fi - - # Check if ssl option is selected - db_get gitlab/ssl - gl_proto="http" - - # Copy example configurations - test -f ${gitlab_yml_private} || \ - cp ${gitlab_yml_example} ${gitlab_yml_private} - test -f ${gitlab_shell_config_private} || \ - cp ${gitlab_shell_config_example} ${gitlab_shell_config_private} - - sed -i "s/GITLAB_USER/${gitlab_user}/" ${gitlab_yml_private} - - if [ "${RET}" = "true" ]; then - echo "Configuring nginx with HTTPS..." - if ! grep GITLAB_HTTPS ${gitlab_debian_conf_private}; then - echo GITLAB_HTTPS=${RET} >> ${gitlab_debian_conf_private} - # Workaround for #813770 - gl_proto="https" - echo "Configuring gitlab with HTTPS..." - sed -i "s/#port: 80/port: 443/" ${gitlab_yml_private} - sed -i "s/https: false/https: true/" ${gitlab_yml_private} - echo "Updating gitlab_url in gitlab-shell configuration..." - sed -i \ + GITLAB_HOST=$RET + GITLAB_EMAIL_FROM="no-reply@$GITLAB_HOST" + GITLAB_EMAIL_DISPLAY_NAME="Gitlab" + GITLAB_EMAIL_REPLY_TO="no-reply@$GITLAB_HOST" + db_get gitlab/user + gitlab_user=$RET + # Check if ssl option is selected + db_get gitlab/ssl + GITLAB_HTTPS=$RET + gl_proto="http" + db_get gitlab/letsencrypt + gitlab_letsencrypt=$RET + + cp -a -f ${gitlab_debian_conf_private} ${gitlab_debian_conf_private}.tmp + + # If the admin deleted or commented some variables but then set + # them via debconf, (re-)add them to the conffile. + test -z "$GITLAB_HOST" || grep -Eq '^ *GITLAB_HOST=' ${gitlab_debian_conf_private} || \ + echo "GITLAB_HOST=" >> ${gitlab_debian_conf_private} + test -z "$GITLAB_EMAIL_FROM" || grep -Eq '^ *GITLAB_EMAIL_FROM=' ${gitlab_debian_conf_private} || \ + echo "GITLAB_EMAIL_FROM=" >> ${gitlab_debian_conf_private} + test -z "$GITLAB_EMAIL_DISPLAY_NAME" || grep -Eq '^ *GITLAB_EMAIL_DISPLAY_NAME=' ${gitlab_debian_conf_private} || \ + echo "GITLAB_EMAIL_DISPLAY_NAME=" >> ${gitlab_debian_conf_private} + test -z "$GITLAB_EMAIL_REPLY_TO" || grep -Eq '^ *GITLAB_EMAIL_REPLY_TO=' ${gitlab_debian_conf_private} || \ + echo "GITLAB_EMAIL_REPLY_TO=" >> ${gitlab_debian_conf_private} + test -z "$gitlab_user" || grep -Eq '^ *gitlab_user=' ${gitlab_debian_conf_private} || \ + echo "gitlab_user=" >> ${gitlab_debian_conf_private} + test -z "$GITLAB_HTTPS" || grep -Eq '^ *GITLAB_HTTPS=' ${gitlab_debian_conf_private} || \ + echo "GITLAB_HTTPS=" >> ${gitlab_debian_conf_private} + test -z "$gitlab_letsencrypt" || grep -Eq '^ *gitlab_letsencrypt=' ${gitlab_debian_conf_private} || \ + echo "gitlab_letsencrypt=" >> ${gitlab_debian_conf_private} + sed -e "s/^ *GITLAB_HOST=.*/GITLAB_HOST=\"$GITLAB_HOST\"/" \ + -e "s/^ *GITLAB_EMAIL_FROM=.*/GITLAB_EMAIL_FROM=\"$GITLAB_EMAIL_FROM\"/" \ + -e "s/^ *GITLAB_EMAIL_DISPLAY_NAME=.*/GITLAB_EMAIL_DISPLAY_NAME=\"$GITLAB_EMAIL_DISPLAY_NAME\"/" \ + -e "s/^ *GITLAB_EMAIL_REPLY_TO=.*/GITLAB_EMAIL_REPLY_TO=\"$GITLAB_EMAIL_REPLY_TO\"/" \ + -e "s/^ *gitlab_user=.*/gitlab_user=\"$gitlab_user\"/" \ + -e "s/^ *GITLAB_HTTPS=.*/GITLAB_HTTPS=\"$GITLAB_HTTPS\"/" \ + -e "s/^ *gitlab_letsencrypt=.*/gitlab_letsencrypt=\"$gitlab_letsencrypt\"/" \ + < ${gitlab_debian_conf_private} > ${gitlab_debian_conf_private}.tmp + mv -f ${gitlab_debian_conf_private}.tmp ${gitlab_debian_conf_private} + + # Copy example configurations + test -f ${gitlab_yml_private} || \ + cp ${gitlab_yml_example} ${gitlab_yml_private} + test -f ${gitlab_shell_config_private} || \ + cp ${gitlab_shell_config_example} ${gitlab_shell_config_private} + + # Set gitlab user first time + sed -i "s/GITLAB_USER/${gitlab_user}/" ${gitlab_yml_private} + # Update gitlab user (its a hack, proper fix is to have gitlab accept GITLAB_USER variable) + sed -i "s/^ *user:.* #gitlab_user/ user: $gitlab_user #gitlab_user/" ${gitlab_yml_private} + + if [ "$GITLAB_HTTPS" = "true" ]; then + echo "Configuring nginx with HTTPS..." + # Workaround for #813770 + gl_proto="https" + echo "Configuring gitlab with HTTPS..." + sed -i "s/#port: 80/port: 443/" ${gitlab_yml_private} + sed -i "s/https: false/https: true/" ${gitlab_yml_private} + echo "Updating gitlab_url in gitlab-shell configuration..." + sed -i \ "s/gitlab_url: http*:\/\/.*/gitlab_url: ${gl_proto}:\/\/${GITLAB_HOST}/"\ ${gitlab_shell_config_private} + + mkdir -p /etc/gitlab/ssl + nginx_conf_example=${nginx_ssl_conf_example} - fi - - mkdir -p /etc/gitlab/ssl - nginx_conf_example=${nginx_ssl_conf_example} - - # Check if letsencrypt option is selected - db_get gitlab/letsencrypt - if [ "${RET}" = "true" ]; then + # Check if letsencrypt option is selected + if [ "$gitlab_letsencrypt" = "true" ]; then echo "Configuring letsencrypt..." - ln -sf /etc/letsencrypt/live/${GITLAB_HOST}/fullchain.pem \ - /etc/gitlab/ssl/gitlab.crt - ln -sf /etc/letsencrypt/live/${GITLAB_HOST}/privkey.pem \ - /etc/gitlab/ssl/gitlab.key + ln -sf /etc/letsencrypt/live/${GITLAB_HOST}/fullchain.pem \ + /etc/gitlab/ssl/gitlab.crt + ln -sf /etc/letsencrypt/live/${GITLAB_HOST}/privkey.pem \ + /etc/gitlab/ssl/gitlab.key - # Check if certificate is already present - if [ -e /etc/letsencrypt/live/${GITLAB_HOST}/fullchain.pem ]; then - echo "Let's encrypt certificate already present." - else - # Port 80 and 443 should be available for letsencrypt - if command -v nginx > /dev/null; then - echo "Stopping nginx for letsencrypt..." - invoke-rc.d nginx stop - fi + # Check if certificate is already present + if [ -e /etc/letsencrypt/live/${GITLAB_HOST}/fullchain.pem ]; then + echo "Let's encrypt certificate already present." + else + # Port 80 and 443 should be available for letsencrypt + if command -v nginx > /dev/null; then + echo "Stopping nginx for letsencrypt..." + invoke-rc.d nginx stop + fi - letsencrypt -d ${GITLAB_HOST} certonly || { + letsencrypt --standalone -d ${GITLAB_HOST} certonly || { echo "letsencrypt auto configuration failed..." echo "Stop your webserver and try running letsencrypt manually..." echo "letsencrypt -d ${GITLAB_HOST} certonly" - } - fi - fi + } + fi fi + else + # Revert https setting + sed -i "s/port: 443/#port: 80/" ${gitlab_yml_private} + sed -i "s/https: true/https: false/" ${gitlab_yml_private} + fi + + # Cleanup in case letsencrypt were disabled later + if [ "$gitlab_letsencrypt" = "false" ]; then + if [ -L /etc/gitlab/ssl/gitlab.crt ]; then + if [ "$(file /etc/gitlab/ssl/gitlab.crt|awk '{ print $NF }')" = "/etc/letsencrypt/live/${GITLAB_HOST}/fullchain.pem" ]; then + echo "Removing symbolic links to letsencrypt certificate..." + rm -f /etc/gitlab/ssl/gitlab.crt + fi + fi + if [ -L /etc/gitlab/ssl/gitlab.key ]; then + if [ "$(file /etc/gitlab/ssl/gitlab.key|awk '{ print $NF }')" = "/etc/letsencrypt/live/${GITLAB_HOST}/privkey.pem" ]; then + echo "Removing symbolic links to letsencrypt certificate private key..." + rm -f /etc/gitlab/ssl/gitlab.key + fi + fi + fi # Manage tmpfiles.d/gitlab.conf via ucf test -f ${gitlab_tmpfiles_private} || \ @@ -222,7 +266,13 @@ for service in mailroom unicorn sidekiq workhorse; do path=/etc/systemd/system/gitlab-${service}.service.d mkdir -p $path - printf "[Service]\nUser=${gitlab_user}\n" > $path/override.conf + if [ -e $path/override.conf ]; then + echo "$path/override.conf already exist" + # Make sure only gitlab user is updated + sed -i "s/^ *User=.*/User=$gitlab_user/" $path/override.conf + else + printf "[Service]\nUser=${gitlab_user}\n" > $path/override.conf + fi done # Manage gitlab-shell's config.yml via ucf @@ -250,7 +300,6 @@ ucf --debconf-ok --three-way ${nginx_site_private} ${nginx_site} ucfr gitlab ${nginx_site} ln -fs ${nginx_site} /etc/nginx/sites-enabled/ - rm -f ${nginx_conf_example_tmp} else echo "nginx example configuration file not found" exit 1 @@ -261,10 +310,6 @@ echo "Reloading nginx configuration..." invoke-rc.d nginx reload fi - else - echo "Failed to retrieve fully qualified domain name" - exit 1 - fi db_stop echo "Create database if not present" diff -Nru gitlab-8.13.11+dfsg/debian/postrm gitlab-8.13.11+dfsg1/debian/postrm --- gitlab-8.13.11+dfsg/debian/postrm 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/postrm 2017-04-17 14:38:24.000000000 +0530 @@ -18,8 +18,18 @@ # Ensure the menu system is updated # Read debian specific configuration -test -f ${gitlab_debian_conf} && . ${gitlab_debian_conf} -test -f ${gitlab_debian_defaults} && . ${gitlab_debian_defaults} +if [ -f ${gitlab_debian_conf} ]; then . ${gitlab_debian_conf}; fi +if [ -f ${gitlab_debian_defaults} ]; then . ${gitlab_debian_defaults}; fi + +safely_remove() { + CANDIDATE_DIR=$1 + if [ -n ${CANDIDATE_DIR} ];then + if [ -e ${CANDIDATE_DIR} ]; then + echo "Removing $i..." + rm -rf ${CANDIDATE_DIR} + fi + fi +} case "$1" in remove) @@ -50,27 +60,27 @@ if [ "${RET}" = "true" ]; then if [ -d ${gitlab_data_dir} ]; then for i in shared public db repositories secrets.yml Gemfile.lock; do - test -e ${gitlab_data_dir}/$i && rm -rf ${gitlab_data_dir}/$i + if [ -e ${gitlab_data_dir}/$i ]; then rm -rf ${gitlab_data_dir}/$i; fi done fi - test -e ${gitlab_log_dir} && rm -rf ${gitlab_log_dir} - test -e ${gitlab_cache_path} && rm -rf ${gitlab_cache_path} - test -e ${gitlab_pid_path} && rm -rf ${gitlab_pid_path} - test -e ${gitlab_data_dir} && rm -rf ${gitlab_data_dir} + for i in ${gitlab_log_dir} ${gitlab_cache_path} ${gitlab_pid_path} \ +${gitlab_data_dir}; do + safely_remove $i + done if [ ! -z "${gitlab_user}" ]; then # Do only if gitlab_user is set if command -v dropdb >/dev/null; then echo "Removing Database: gitlab_production" - su ${gitlab_user} -c 'psql gitlab_production -c ""' && su postgres -c "dropdb gitlab_production" + if su ${gitlab_user} -c 'psql gitlab_production -c ""' ; then su postgres -c "dropdb gitlab_production"; fi else echo "dropdb command not found. Hence not removing database." fi echo "Removing user: ${gitlab_user}" - id -u ${gitlab_user} && userdel -r ${gitlab_user} + if id -u ${gitlab_user}; then userdel -r ${gitlab_user}; fi else echo "gitlab_user not set. Hence not removing user." fi - rm -rf ${gitlab_ssl_path} + safely_remove ${gitlab_ssl_path} fi # Remove my changes to the db. @@ -79,7 +89,7 @@ nginx_site="/etc/nginx/sites-available/${GITLAB_HOST}" - test -f ${nginx_site} && echo "Found nginx site configuration at ${nginx_site}..." + if [ -f ${nginx_site} ]; then echo "Found nginx site configuration at ${nginx_site}..."; fi # we mimic dpkg as closely as possible, so we remove configuration @@ -93,32 +103,21 @@ rm -f ${gitlab_shell_config}$ext done - # remove the configuration file itself - test -f ${nginx_site} && rm -f ${nginx_site} - test -f ${gitlab_debian_conf} && rm -f ${gitlab_debian_conf} - test -f ${gitlab_yml} && rm -f ${gitlab_yml} - test -f ${gitlab_tmpfiles} && rm -f ${gitlab_tmpfiles} - test -f ${gitlab_shell_config} && rm -f ${gitlab_shell_config} - - # and finally clear it out from the ucf database - if which ucf >/dev/null; then - test -n "${nginx_site}" && ucf --purge ${nginx_site} - test -n "${gitlab_debian_conf}" && ucf --purge ${gitlab_debian_conf} - test -n "${gitlab_yml}" && ucf --purge ${gitlab_yml} - test -n "${gitlab_tmpfiles}" && ucf --purge ${gitlab_tmpfiles} - test -n "${gitlab_shell_config}" && ucf -purge ${gitlab_shell_config} - fi - - if which ucfr >/dev/null; then - test -n "${nginx_site}" && ucfr --purge gitlab ${nginx_site} - test -n "${gitlab_debian_conf}" && ucfr --purge gitlab ${gitlab_debian_conf} - test -n "${gitlab_yml}" && ucfr --purge gitlab ${gitlab_yml} - test -n "${gitlab_tmpfiles}" && ucfr --purge gitlab ${gitlab_tmpfiles} - test -n "${gitlab_shell_config}" && ucfr -purge gitlab ${gitlab_shell_config} - fi + for i in ${nginx_site} ${gitlab_debian_conf} ${gitlab_yml} \ +${gitlab_tmpfiles} ${gitlab_shell_config}; do + # remove the configuration file itself + safely_remove $i + # and finally clear it out from the ucf database + if which ucf >/dev/null; then + if [ -n "$i" ]; then ucf --purge $i; fi + fi + if which ucfr >/dev/null; then + if [ -n "$i" ]; then ucfr --purge gitlab $i; fi + fi + done # remove generated assets - rm -rf ${gitlab_data_dir}/public/assets + if [ -n ${gitlab_data_dir} ]; then safely_remove ${gitlab_data_dir}/public/assets; fi # Remove private copies of configuration files rm -f ${nginx_site_private} diff -Nru gitlab-8.13.11+dfsg/debian/README.Debian gitlab-8.13.11+dfsg1/debian/README.Debian --- gitlab-8.13.11+dfsg/debian/README.Debian 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg1/debian/README.Debian 2017-04-20 11:47:49.000000000 +0530 @@ -64,7 +64,7 @@ directory /usr/share/gitlab and with the environment variables from /etc/gitlab/gitlab-debian.conf set. So above command could be run like: - $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && export $(cat /etc/gitlab/gitlab-debian.conf) && rake XXX RAILS_ENV=production' + $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && . /etc/gitlab/gitlab-debian.conf && export DB RAILS_ENV && rake XXX RAILS_ENV=production' One useful command to run in this environment is: @@ -120,19 +120,19 @@ $ find /var/lib/gitlab/public/uploads -type f -exec chmod 0644 {} \; $ find /var/lib/gitlab/public/uploads -type d -not -path /var/lib/gitlab/public/uploads -exec chmod 0700 {} \; 10. Migrate the database: - $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && export $(cat /etc/gitlab/gitlab-debian.conf) && rake db:migrate RAILS_ENV=production' + $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && . /etc/gitlab/gitlab-debian.conf && export DB RAILS_ENV && rake db:migrate RAILS_ENV=production' 11. Fix hooks: # su gitlab $ /usr/share/gitlab-shell/bin/create-hooks 12. Start gitlab: $ systemctl start gitlab.service 13. Check the installation: - $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && export $(cat /etc/gitlab/gitlab-debian.conf) && rake gitlab:check RAILS_ENV=production' + $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && . /etc/gitlab/gitlab-debian.conf && export DB RAILS_ENV && rake gitlab:check RAILS_ENV=production' Resetting admin password without web interface ============================================== - $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && export $(cat /etc/gitlab/gitlab-debian.conf) && rails console production' + $ runuser -u gitlab -- sh -c 'cd /usr/share/gitlab && . /etc/gitlab/gitlab-debian.conf && export DB RAILS_ENV && rails console production' irb(main):001:0> user = User.where(admin: true).first irb(main):002:0> user.password = 'secret_pass' irb(main):003:0> user.password_confirmation = 'secret_pass' diff -Nru gitlab-8.13.11+dfsg/vendor/assets/javascripts/fuzzaldrin-plus.js gitlab-8.13.11+dfsg1/vendor/assets/javascripts/fuzzaldrin-plus.js --- gitlab-8.13.11+dfsg/vendor/assets/javascripts/fuzzaldrin-plus.js 2017-01-10 22:23:38.000000000 +0530 +++ gitlab-8.13.11+dfsg1/vendor/assets/javascripts/fuzzaldrin-plus.js 1970-01-01 05:30:00.000000000 +0530 @@ -1,1161 +0,0 @@ -/*! - * fuzzaldrin-plus.js - 0.3.1 - * https://github.com/jeancroy/fuzzaldrin-plus - * - * Copyright 2016 - Jean Christophe Roy - * Released under the MIT license - * https://github.com/jeancroy/fuzzaldrin-plus/raw/master/LICENSE.md - */ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ -fuzzaldrinPlus = require('fuzzaldrin-plus'); - -},{"fuzzaldrin-plus":3}],2:[function(require,module,exports){ -(function() { - var PathSeparator, legacy_scorer, pluckCandidates, scorer, sortCandidates; - - scorer = require('./scorer'); - - legacy_scorer = require('./legacy'); - - pluckCandidates = function(a) { - return a.candidate; - }; - - sortCandidates = function(a, b) { - return b.score - a.score; - }; - - PathSeparator = require('path').sep; - - module.exports = function(candidates, query, _arg) { - var allowErrors, bAllowErrors, bKey, candidate, coreQuery, key, legacy, maxInners, maxResults, prepQuery, queryHasSlashes, score, scoredCandidates, spotLeft, string, _i, _j, _len, _len1, _ref; - _ref = _arg != null ? _arg : {}, key = _ref.key, maxResults = _ref.maxResults, maxInners = _ref.maxInners, allowErrors = _ref.allowErrors, legacy = _ref.legacy; - scoredCandidates = []; - spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length; - bAllowErrors = !!allowErrors; - bKey = key != null; - prepQuery = scorer.prepQuery(query); - if (!legacy) { - for (_i = 0, _len = candidates.length; _i < _len; _i++) { - candidate = candidates[_i]; - string = bKey ? candidate[key] : candidate; - if (!string) { - continue; - } - score = scorer.score(string, query, prepQuery, bAllowErrors); - if (score > 0) { - scoredCandidates.push({ - candidate: candidate, - score: score - }); - if (!--spotLeft) { - break; - } - } - } - } else { - queryHasSlashes = prepQuery.depth > 0; - coreQuery = prepQuery.core; - for (_j = 0, _len1 = candidates.length; _j < _len1; _j++) { - candidate = candidates[_j]; - string = key != null ? candidate[key] : candidate; - if (!string) { - continue; - } - score = legacy_scorer.score(string, coreQuery, queryHasSlashes); - if (!queryHasSlashes) { - score = legacy_scorer.basenameScore(string, coreQuery, score); - } - if (score > 0) { - scoredCandidates.push({ - candidate: candidate, - score: score - }); - } - } - } - scoredCandidates.sort(sortCandidates); - candidates = scoredCandidates.map(pluckCandidates); - if (maxResults != null) { - candidates = candidates.slice(0, maxResults); - } - return candidates; - }; - -}).call(this); - -},{"./legacy":4,"./scorer":6,"path":7}],3:[function(require,module,exports){ -(function() { - var PathSeparator, filter, legacy_scorer, matcher, prepQueryCache, scorer; - - scorer = require('./scorer'); - - legacy_scorer = require('./legacy'); - - filter = require('./filter'); - - matcher = require('./matcher'); - - PathSeparator = require('path').sep; - - prepQueryCache = null; - - module.exports = { - filter: function(candidates, query, options) { - if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) { - return []; - } - return filter(candidates, query, options); - }, - prepQuery: function(query) { - return scorer.prepQuery(query); - }, - score: function(string, query, prepQuery, _arg) { - var allowErrors, coreQuery, legacy, queryHasSlashes, score, _ref; - _ref = _arg != null ? _arg : {}, allowErrors = _ref.allowErrors, legacy = _ref.legacy; - if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) { - return 0; - } - if (prepQuery == null) { - prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query)); - } - if (!legacy) { - score = scorer.score(string, query, prepQuery, !!allowErrors); - } else { - queryHasSlashes = prepQuery.depth > 0; - coreQuery = prepQuery.core; - score = legacy_scorer.score(string, coreQuery, queryHasSlashes); - if (!queryHasSlashes) { - score = legacy_scorer.basenameScore(string, coreQuery, score); - } - } - return score; - }, - match: function(string, query, prepQuery, _arg) { - var allowErrors, baseMatches, matches, query_lw, string_lw, _i, _ref, _results; - allowErrors = (_arg != null ? _arg : {}).allowErrors; - if (!string) { - return []; - } - if (!query) { - return []; - } - if (string === query) { - return (function() { - _results = []; - for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); } - return _results; - }).apply(this); - } - if (prepQuery == null) { - prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query)); - } - if (!(allowErrors || scorer.isMatch(string, prepQuery.core_lw, prepQuery.core_up))) { - return []; - } - string_lw = string.toLowerCase(); - query_lw = prepQuery.query_lw; - matches = matcher.match(string, string_lw, prepQuery); - if (matches.length === 0) { - return matches; - } - if (string.indexOf(PathSeparator) > -1) { - baseMatches = matcher.basenameMatch(string, string_lw, prepQuery); - matches = matcher.mergeMatches(matches, baseMatches); - } - return matches; - } - }; - -}).call(this); - -},{"./filter":2,"./legacy":4,"./matcher":5,"./scorer":6,"path":7}],4:[function(require,module,exports){ -(function() { - var PathSeparator, queryIsLastPathSegment; - - PathSeparator = require('path').sep; - - exports.basenameScore = function(string, query, score) { - var base, depth, index, lastCharacter, segmentCount, slashCount; - index = string.length - 1; - while (string[index] === PathSeparator) { - index--; - } - slashCount = 0; - lastCharacter = index; - base = null; - while (index >= 0) { - if (string[index] === PathSeparator) { - slashCount++; - if (base == null) { - base = string.substring(index + 1, lastCharacter + 1); - } - } else if (index === 0) { - if (lastCharacter < string.length - 1) { - if (base == null) { - base = string.substring(0, lastCharacter + 1); - } - } else { - if (base == null) { - base = string; - } - } - } - index--; - } - if (base === string) { - score *= 2; - } else if (base) { - score += exports.score(base, query); - } - segmentCount = slashCount + 1; - depth = Math.max(1, 10 - segmentCount); - score *= depth * 0.01; - return score; - }; - - exports.score = function(string, query) { - var character, characterScore, indexInQuery, indexInString, lowerCaseIndex, minIndex, queryLength, queryScore, stringLength, totalCharacterScore, upperCaseIndex, _ref; - if (string === query) { - return 1; - } - if (queryIsLastPathSegment(string, query)) { - return 1; - } - totalCharacterScore = 0; - queryLength = query.length; - stringLength = string.length; - indexInQuery = 0; - indexInString = 0; - while (indexInQuery < queryLength) { - character = query[indexInQuery++]; - lowerCaseIndex = string.indexOf(character.toLowerCase()); - upperCaseIndex = string.indexOf(character.toUpperCase()); - minIndex = Math.min(lowerCaseIndex, upperCaseIndex); - if (minIndex === -1) { - minIndex = Math.max(lowerCaseIndex, upperCaseIndex); - } - indexInString = minIndex; - if (indexInString === -1) { - return 0; - } - characterScore = 0.1; - if (string[indexInString] === character) { - characterScore += 0.1; - } - if (indexInString === 0 || string[indexInString - 1] === PathSeparator) { - characterScore += 0.8; - } else if ((_ref = string[indexInString - 1]) === '-' || _ref === '_' || _ref === ' ') { - characterScore += 0.7; - } - string = string.substring(indexInString + 1, stringLength); - totalCharacterScore += characterScore; - } - queryScore = totalCharacterScore / queryLength; - return ((queryScore * (queryLength / stringLength)) + queryScore) / 2; - }; - - queryIsLastPathSegment = function(string, query) { - if (string[string.length - query.length - 1] === PathSeparator) { - return string.lastIndexOf(query) === string.length - query.length; - } - }; - - exports.match = function(string, query, stringOffset) { - var character, indexInQuery, indexInString, lowerCaseIndex, matches, minIndex, queryLength, stringLength, upperCaseIndex, _i, _ref, _results; - if (stringOffset == null) { - stringOffset = 0; - } - if (string === query) { - return (function() { - _results = []; - for (var _i = stringOffset, _ref = stringOffset + string.length; stringOffset <= _ref ? _i < _ref : _i > _ref; stringOffset <= _ref ? _i++ : _i--){ _results.push(_i); } - return _results; - }).apply(this); - } - queryLength = query.length; - stringLength = string.length; - indexInQuery = 0; - indexInString = 0; - matches = []; - while (indexInQuery < queryLength) { - character = query[indexInQuery++]; - lowerCaseIndex = string.indexOf(character.toLowerCase()); - upperCaseIndex = string.indexOf(character.toUpperCase()); - minIndex = Math.min(lowerCaseIndex, upperCaseIndex); - if (minIndex === -1) { - minIndex = Math.max(lowerCaseIndex, upperCaseIndex); - } - indexInString = minIndex; - if (indexInString === -1) { - return []; - } - matches.push(stringOffset + indexInString); - stringOffset += indexInString + 1; - string = string.substring(indexInString + 1, stringLength); - } - return matches; - }; - -}).call(this); - -},{"path":7}],5:[function(require,module,exports){ -(function() { - var PathSeparator, scorer; - - PathSeparator = require('path').sep; - - scorer = require('./scorer'); - - exports.basenameMatch = function(subject, subject_lw, prepQuery) { - var basePos, depth, end; - end = subject.length - 1; - while (subject[end] === PathSeparator) { - end--; - } - basePos = subject.lastIndexOf(PathSeparator, end); - if (basePos === -1) { - return []; - } - depth = prepQuery.depth; - while (depth-- > 0) { - basePos = subject.lastIndexOf(PathSeparator, basePos - 1); - if (basePos === -1) { - return []; - } - } - basePos++; - end++; - return exports.match(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery, basePos); - }; - - exports.mergeMatches = function(a, b) { - var ai, bj, i, j, m, n, out; - m = a.length; - n = b.length; - if (n === 0) { - return a.slice(); - } - if (m === 0) { - return b.slice(); - } - i = -1; - j = 0; - bj = b[j]; - out = []; - while (++i < m) { - ai = a[i]; - while (bj <= ai && ++j < n) { - if (bj < ai) { - out.push(bj); - } - bj = b[j]; - } - out.push(ai); - } - while (j < n) { - out.push(b[j++]); - } - return out; - }; - - exports.match = function(subject, subject_lw, prepQuery, offset) { - var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace; - if (offset == null) { - offset = 0; - } - query = prepQuery.query; - query_lw = prepQuery.query_lw; - m = subject.length; - n = query.length; - acro_score = scorer.scoreAcronyms(subject, subject_lw, query, query_lw).score; - score_row = new Array(n); - csc_row = new Array(n); - STOP = 0; - UP = 1; - LEFT = 2; - DIAGONAL = 3; - trace = new Array(m * n); - pos = -1; - j = -1; - while (++j < n) { - score_row[j] = 0; - csc_row[j] = 0; - } - i = -1; - while (++i < m) { - score = 0; - score_up = 0; - csc_diag = 0; - si_lw = subject_lw[i]; - j = -1; - while (++j < n) { - csc_score = 0; - align = 0; - score_diag = score_up; - if (query_lw[j] === si_lw) { - start = scorer.isWordStart(i, subject, subject_lw); - csc_score = csc_diag > 0 ? csc_diag : scorer.scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start); - align = score_diag + scorer.scoreCharacter(i, j, start, acro_score, csc_score); - } - score_up = score_row[j]; - csc_diag = csc_row[j]; - if (score > score_up) { - move = LEFT; - } else { - score = score_up; - move = UP; - } - if (align > score) { - score = align; - move = DIAGONAL; - } else { - csc_score = 0; - } - score_row[j] = score; - csc_row[j] = csc_score; - trace[++pos] = score > 0 ? move : STOP; - } - } - i = m - 1; - j = n - 1; - pos = i * n + j; - backtrack = true; - matches = []; - while (backtrack && i >= 0 && j >= 0) { - switch (trace[pos]) { - case UP: - i--; - pos -= n; - break; - case LEFT: - j--; - pos--; - break; - case DIAGONAL: - matches.push(i + offset); - j--; - i--; - pos -= n + 1; - break; - default: - backtrack = false; - } - } - matches.reverse(); - return matches; - }; - -}).call(this); - -},{"./scorer":6,"path":7}],6:[function(require,module,exports){ -(function() { - var AcronymResult, PathSeparator, Query, basenameScore, coreChars, countDir, doScore, emptyAcronymResult, file_coeff, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, opt_char_re, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_depth, tau_size, truncatedUpperCase, wm; - - PathSeparator = require('path').sep; - - wm = 150; - - pos_bonus = 20; - - tau_depth = 13; - - tau_size = 85; - - file_coeff = 1.2; - - miss_coeff = 0.75; - - opt_char_re = /[ _\-:\/\\]/g; - - exports.coreChars = coreChars = function(query) { - return query.replace(opt_char_re, ''); - }; - - exports.score = function(string, query, prepQuery, allowErrors) { - var score, string_lw; - if (prepQuery == null) { - prepQuery = new Query(query); - } - if (allowErrors == null) { - allowErrors = false; - } - if (!(allowErrors || isMatch(string, prepQuery.core_lw, prepQuery.core_up))) { - return 0; - } - string_lw = string.toLowerCase(); - score = doScore(string, string_lw, prepQuery); - return Math.ceil(basenameScore(string, string_lw, prepQuery, score)); - }; - - Query = (function() { - function Query(query) { - if (!(query != null ? query.length : void 0)) { - return null; - } - this.query = query; - this.query_lw = query.toLowerCase(); - this.core = coreChars(query); - this.core_lw = this.core.toLowerCase(); - this.core_up = truncatedUpperCase(this.core); - this.depth = countDir(query, query.length); - } - - return Query; - - })(); - - exports.prepQuery = function(query) { - return new Query(query); - }; - - exports.isMatch = isMatch = function(subject, query_lw, query_up) { - var i, j, m, n, qj_lw, qj_up, si; - m = subject.length; - n = query_lw.length; - if (!m || n > m) { - return false; - } - i = -1; - j = -1; - while (++j < n) { - qj_lw = query_lw[j]; - qj_up = query_up[j]; - while (++i < m) { - si = subject[i]; - if (si === qj_lw || si === qj_up) { - break; - } - } - if (i === m) { - return false; - } - } - return true; - }; - - doScore = function(subject, subject_lw, prepQuery) { - var acro, acro_score, align, csc_diag, csc_row, csc_score, i, j, m, miss_budget, miss_left, mm, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz; - query = prepQuery.query; - query_lw = prepQuery.query_lw; - m = subject.length; - n = query.length; - acro = scoreAcronyms(subject, subject_lw, query, query_lw); - acro_score = acro.score; - if (acro.count === n) { - return scoreExact(n, m, acro_score, acro.pos); - } - pos = subject_lw.indexOf(query_lw); - if (pos > -1) { - return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m); - } - score_row = new Array(n); - csc_row = new Array(n); - sz = scoreSize(n, m); - miss_budget = Math.ceil(miss_coeff * n) + 5; - miss_left = miss_budget; - j = -1; - while (++j < n) { - score_row[j] = 0; - csc_row[j] = 0; - } - i = subject_lw.indexOf(query_lw[0]); - if (i > -1) { - i--; - } - mm = subject_lw.lastIndexOf(query_lw[n - 1], m); - if (mm > i) { - m = mm + 1; - } - while (++i < m) { - score = 0; - score_diag = 0; - csc_diag = 0; - si_lw = subject_lw[i]; - record_miss = true; - j = -1; - while (++j < n) { - score_up = score_row[j]; - if (score_up > score) { - score = score_up; - } - csc_score = 0; - if (query_lw[j] === si_lw) { - start = isWordStart(i, subject, subject_lw); - csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start); - align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score); - if (align > score) { - score = align; - miss_left = miss_budget; - } else { - if (record_miss && --miss_left <= 0) { - return score_row[n - 1] * sz; - } - record_miss = false; - } - } - score_diag = score_up; - csc_diag = csc_row[j]; - csc_row[j] = csc_score; - score_row[j] = score; - } - } - return score * sz; - }; - - exports.isWordStart = isWordStart = function(pos, subject, subject_lw) { - var curr_s, prev_s; - if (pos === 0) { - return true; - } - curr_s = subject[pos]; - prev_s = subject[pos - 1]; - return isSeparator(curr_s) || isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]); - }; - - exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) { - var curr_s, next_s; - if (pos === len - 1) { - return true; - } - curr_s = subject[pos]; - next_s = subject[pos + 1]; - return isSeparator(curr_s) || isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]); - }; - - isSeparator = function(c) { - return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\'; - }; - - scorePosition = function(pos) { - var sc; - if (pos < pos_bonus) { - sc = pos_bonus - pos; - return 100 + sc * sc; - } else { - return Math.max(100 + pos_bonus - pos, 0); - } - }; - - scoreSize = function(n, m) { - return tau_size / (tau_size + Math.abs(m - n)); - }; - - scoreExact = function(n, m, quality, pos) { - return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m); - }; - - exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) { - var bonus, sz; - sz = count; - bonus = 6; - if (sameCase === count) { - bonus += 2; - } - if (start) { - bonus += 3; - } - if (end) { - bonus += 1; - } - if (count === len) { - if (start) { - if (sameCase === len) { - sz += 2; - } else { - sz += 1; - } - } - if (end) { - bonus += 1; - } - } - return sameCase + sz * (sz + bonus); - }; - - exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) { - var posBonus; - posBonus = scorePosition(i); - if (start) { - return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10); - } - return posBonus + wm * csc_score; - }; - - exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, start) { - var k, m, mi, n, nj, sameCase, startPos, sz; - m = subject.length; - n = query.length; - mi = m - i; - nj = n - j; - k = mi < nj ? mi : nj; - startPos = i; - sameCase = 0; - sz = 0; - if (query[j] === subject[i]) { - sameCase++; - } - while (++sz < k && query_lw[++j] === subject_lw[++i]) { - if (query[j] === subject[i]) { - sameCase++; - } - } - if (sz === 1) { - return 1 + 2 * sameCase; - } - return scorePattern(sz, n, sameCase, start, isWordEnd(i, subject, subject_lw, m)); - }; - - exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) { - var end, i, pos2, sameCase, start; - start = isWordStart(pos, subject, subject_lw); - if (!start) { - pos2 = subject_lw.indexOf(query_lw, pos + 1); - if (pos2 > -1) { - start = isWordStart(pos2, subject, subject_lw); - if (start) { - pos = pos2; - } - } - } - i = -1; - sameCase = 0; - while (++i < n) { - if (query[pos + i] === subject[i]) { - sameCase++; - } - } - end = isWordEnd(pos + n - 1, subject, subject_lw, m); - return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos); - }; - - AcronymResult = (function() { - function AcronymResult(score, pos, count) { - this.score = score; - this.pos = pos; - this.count = count; - } - - return AcronymResult; - - })(); - - emptyAcronymResult = new AcronymResult(0, 0.1, 0); - - exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) { - var count, i, j, m, n, pos, qj_lw, sameCase, score; - m = subject.length; - n = query.length; - if (!(m > 1 && n > 1)) { - return emptyAcronymResult; - } - count = 0; - pos = 0; - sameCase = 0; - i = -1; - j = -1; - while (++j < n) { - qj_lw = query_lw[j]; - while (++i < m) { - if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) { - if (query[j] === subject[i]) { - sameCase++; - } - pos += i; - count++; - break; - } - } - if (i === m) { - break; - } - } - if (count < 2) { - return emptyAcronymResult; - } - score = scorePattern(count, n, sameCase, true, false); - return new AcronymResult(score, pos / count, count); - }; - - basenameScore = function(subject, subject_lw, prepQuery, fullPathScore) { - var alpha, basePathScore, basePos, depth, end; - if (fullPathScore === 0) { - return 0; - } - end = subject.length - 1; - while (subject[end] === PathSeparator) { - end--; - } - basePos = subject.lastIndexOf(PathSeparator, end); - if (basePos === -1) { - return fullPathScore; - } - depth = prepQuery.depth; - while (depth-- > 0) { - basePos = subject.lastIndexOf(PathSeparator, basePos - 1); - if (basePos === -1) { - return fullPathScore; - } - } - basePos++; - end++; - basePathScore = doScore(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery); - alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1)); - return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * (end - basePos)); - }; - - exports.countDir = countDir = function(path, end) { - var count, i; - if (end < 1) { - return 0; - } - count = 0; - i = -1; - while (++i < end && path[i] === PathSeparator) { - continue; - } - while (++i < end) { - if (path[i] === PathSeparator) { - count++; - while (++i < end && path[i] === PathSeparator) { - continue; - } - } - } - return count; - }; - - truncatedUpperCase = function(str) { - var char, upper, _i, _len; - upper = ""; - for (_i = 0, _len = str.length; _i < _len; _i++) { - char = str[_i]; - upper += char.toUpperCase()[0]; - } - return upper; - }; - -}).call(this); - -},{"path":7}],7:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":8}],8:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = setTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - clearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - setTimeout(drainQueue, 0); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}]},{},[1]);
signature.asc
Description: OpenPGP digital signature