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 <praveen@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]);
Attachment:
signature.asc
Description: OpenPGP digital signature