• R/O
  • SSH
  • HTTPS

fsvn: Commit


Commit MetaInfo

Revision324 (tree)
Time2015-11-10 19:25:02
Authormhayashi1120

Log Message

improve svn executable switcher

Change Summary

Incremental Difference

--- trunk/ChangeLog (revision 323)
+++ trunk/ChangeLog (revision 324)
@@ -1,5 +1,6 @@
11 2015-11-10 Masahiro Hayashi (林 雅博) <mhayashi1120@gmail.com>
22
3+ * Improve: detect more information when register new svn command.
34 * Fix: select higher version of svn if registered multiple versions.
45 * Improve: Fix testing environment
56
--- trunk/fsvn-pub.el (revision 323)
+++ trunk/fsvn-pub.el (revision 324)
@@ -516,11 +516,11 @@
516516
517517
518518
519-(defvar fsvn-initialize-function nil)
519+(defvar fsvn--initialize-hook nil)
520+(defvar fsvn--after-initialize-hook nil)
520521
521522 (defun fsvn-initialize-loading ()
522523 (interactive)
523- (fsvn-set-command-information)
524524 (unless (file-directory-p fsvn-home-directory)
525525 (make-directory fsvn-home-directory t))
526526 (mapc
@@ -530,10 +530,11 @@
530530 (make-directory dirname))))
531531 fsvn-temp-directory-dirs)
532532 (fsvn-cleanup-temp-directory)
533+ (run-hooks 'fsvn--initialize-hook)
534+ (fsvn-set-command-information)
533535 (fsvn-build-subcommand)
534- (when fsvn-initialize-function
535- (funcall fsvn-initialize-function))
536- (fsvn-toggle-feature t 'no-msg))
536+ (fsvn-toggle-feature t 'no-msg)
537+ (run-hooks 'fsvn--after-initialize-hook))
537538
538539 (defun fsvn-toggle-command-boolean (optional-arg current-value)
539540 (cond
--- trunk/fsvn-proc.el (revision 323)
+++ trunk/fsvn-proc.el (revision 324)
@@ -22,6 +22,7 @@
2222
2323 (defvar fsvn-process-environment-lang nil)
2424 (defmacro fsvn-process-environment (&rest form)
25+ (declare (debug t))
2526 `(let ((process-environment (copy-sequence process-environment)))
2627 (setenv "LC_MESSAGES" (or fsvn-process-environment-lang "C"))
2728 ,@form))
@@ -325,6 +326,7 @@
325326 " ")))
326327
327328 (defun fsvn-guess-file-contents-coding-system (flatten-args)
329+ "Guess output coding-system file in FLATTEN-ARGS."
328330 (let (ignore)
329331 (catch 'guessed
330332 (mapc
--- trunk/fsvn-cmd.el (revision 323)
+++ trunk/fsvn-cmd.el (revision 324)
@@ -684,11 +684,6 @@
684684 (terminal-coding-system)
685685 (fsvn-prop-file-coding-system propname))))
686686
687-(defvar fsvn-targets-file-converter nil
688- "File name converter for function `--targets' argument.
689-Default value is `identity'
690-Usefull for cygwin version `svn'")
691-
692687 (defun fsvn-make-targets-file (files)
693688 "Create --targts argument file.
694689 Argument FILES ."
@@ -698,7 +693,7 @@
698693 (mapc
699694 (lambda (f)
700695 (let ((file (fsvn-url-escape-revision-mark f)))
701- (insert (funcall (or fsvn-targets-file-converter 'identity) file) "\n")))
696+ (insert file "\n")))
702697 files)
703698 (write-region (point-min) (point-max) tmpfile nil 'no-msg)))
704699 (propertize tmpfile 'fsvn-target-files files)))
--- trunk/fsvn-deps.el (revision 323)
+++ trunk/fsvn-deps.el (revision 324)
@@ -426,25 +426,37 @@
426426 ;; default
427427 fsvn-svn-command-internal))
428428
429-(defun fsvn-get-version (command)
429+(defun fsvn-deps--command-information (command)
430+ "Get command information by `svn --version` command."
430431 (with-temp-buffer
431432 (fsvn-deps-process-environment
432- ;;TODO 1.6.9 stderr "svn: warning: cannot set LC_CTYPE locale"
433- ;; not depend on fsvn-call-process
434- (process-file command nil (list (current-buffer) nil) nil "--version" "--quiet"))
435- (let ((raw-version (car (fsvn-text-buffer-line-as-list)))
436- version)
437- ;; trim "1.8.6-dev" like version
438- (unless (string-match "\\`\\([0-9]+\\.[0-9]+\\.[0-9]+\\)" raw-version)
439- (error "Unsupported version"))
440- (match-string 1 raw-version))))
433+ (process-file command nil (list (current-buffer) nil) nil "--version"))
434+ (goto-char (point-min))
435+ (let (raw-version version functional-version
436+ type cygwinp)
437+ (unless (looking-at ".*version \\(\\([0-9.]+\\)\\(?:-dev\\)?\\)")
438+ (error "Version not found"))
439+ (setq raw-version (match-string 1))
440+ (setq version (match-string 2))
441+ (unless (string-match "\\`[0-9]+\\.[0-9]+" raw-version)
442+ (error "Invalid version string"))
443+ (setq functional-version (match-string 0 raw-version))
444+ (forward-line 1)
445+ (if (looking-at "^ +compiled.*on \\([^\s\n]+\\)")
446+ ;; ignore if not found not so important.
447+ (setq type (match-string 1))
448+ (setq type "unknown"))
449+ (setq cygwinp (and (string-match "cygwin" type) t))
450+ (list version functional-version raw-version
451+ type cygwinp))))
441452
442-(defun fsvn-get-ensure-version (command)
443- (let ((ver (fsvn-get-version command)))
453+(defun fsvn-deps--get-ensure-version (command)
454+ (let* ((info (fsvn-deps--command-information command))
455+ (ver (nth 0 info)))
444456 (when (fboundp 'version<=)
445457 (when (version<= ver "1.4")
446458 (error "Svn command must be 1.5.x or later")))
447- ver))
459+ info))
448460
449461 (defun fsvn-set-command-information ()
450462 ;; FIXME modified this variables value by `start-process' on windows NTEmacs 24.5
@@ -459,37 +471,49 @@
459471 (error "No executable \"%s\"" fsvn-svnadmin-command))
460472 (fsvn-add-command-location fsvn-svn-command-internal
461473 fsvn-svnadmin-command-internal)
462- (let ((ver (fsvn-get-ensure-version fsvn-svn-command-internal)))
463- (setq fsvn-svn-version ver)))
474+ (let ((info (fsvn-deps--get-ensure-version fsvn-svn-command-internal)))
475+ (setq fsvn-svn-version (nth 0 info))))
464476
465477 (defun fsvn-add-command-location (svn-command &optional admin-command)
466- (let ((bin (executable-find svn-command)))
467- (unless bin
478+ (let ((svn-bin (executable-find svn-command))
479+ admin-bin)
480+ (unless svn-bin
468481 (error "Not a svn executable"))
469482 (unless admin-command
470483 (let ((regexp (concat "\\`\\(.+?\\)" (regexp-opt exec-suffixes t) "?\\'")))
471- (unless (string-match regexp bin)
484+ (unless (string-match regexp svn-bin)
472485 (error "Filename not matched (assert)"))
473- (let ((base (match-string 1 bin))
474- (suffix (match-string 2 bin)))
486+ (let ((base (match-string 1 svn-bin))
487+ (suffix (match-string 2 svn-bin)))
475488 (setq admin-command (concat base "admin" suffix)))))
476- (unless (executable-find admin-command)
489+ (setq admin-bin (executable-find admin-command))
490+ (unless admin-bin
477491 (error "Not found a svnadmin executable"))
478492 ;; detect command behavior
479- (let* ((ver (fsvn-get-ensure-version svn-command))
480- ;; key is Major.Minor version
481- (key (and (string-match "\\`[0-9]+\\.[0-9]+" ver)
482- (match-string 0 ver)))
483- (converter (fsvn-deps--guess-physical-path-converter
484- svn-command admin-command))
485- (alist fsvn-svn-command-alist)
486- target)
487- (unless (setq target (assoc key alist))
488- (setq target (cons key nil))
489- (setq alist (cons target alist)))
490- (setcdr target (list bin converter))
491- (setq fsvn-svn-command-alist alist)
492- ver)))
493+ (let* ((svn-info (fsvn-deps--get-ensure-version svn-bin))
494+ (admin-info (fsvn-deps--get-ensure-version admin-bin))
495+ (svn-ver (nth 0 svn-info))
496+ (admin-ver (nth 0 admin-info)))
497+ (unless (equal svn-ver admin-ver)
498+ (error "Command version is differ svn:%s but svnadmin:%s"
499+ svn-ver admin-ver))
500+ (let* (
501+ ;; key is Major.Minor version
502+ (key (nth 1 svn-info))
503+ (path-converter (fsvn-deps--guess-physical-path-converter svn-bin admin-bin))
504+ (target-converter (if (nth 4 svn-info) ; cygwin
505+ 'fsvn-cygwin-convert-target-file
506+ nil))
507+ (alist fsvn-svn-command-alist)
508+ target)
509+ (unless (setq target (assoc key alist))
510+ (setq target (cons key nil))
511+ (setq alist (cons target alist)))
512+ (setcdr target
513+ (list svn-bin admin-bin
514+ path-converter target-converter))
515+ (setq fsvn-svn-command-alist alist)
516+ svn-ver))))
493517
494518 (defun fsvn-build-subcommand (&optional force)
495519 (mapc
@@ -1226,7 +1250,7 @@
12261250
12271251
12281252
1229-(defun fsvn-svn-fetch-physical-path-function (command)
1253+(defun fsvn-deps--fetch-command-behavior (command)
12301254 ;; canonicalize
12311255 (setq command (expand-file-name command))
12321256 (catch 'found
@@ -1233,8 +1257,8 @@
12331257 (let ((lis fsvn-svn-command-alist))
12341258 (while lis
12351259 (let ((pair (car lis)))
1236- (when (string= (nth 1 pair) command)
1237- (throw 'found (nth 2 pair)))
1260+ (when (string= (expand-file-name (nth 1 pair)) command)
1261+ (throw 'found pair))
12381262 (setq lis (cdr lis)))))))
12391263
12401264 ;; cygwin version svn accept only "/" started filename not emacs path
@@ -1241,24 +1265,39 @@
12411265 ;; e.g.
12421266 ;; x c:/hoge/windows
12431267 ;; o /cygdrive/c/hoge/windows
1244-(defun fsvn-command-args-to-physical-args (command args)
1245- (let ((ensurer (fsvn-svn-fetch-physical-path-function command)))
1246- (if (null ensurer)
1268+(defun fsvn-command-args-to-physical-args (svn-command args)
1269+ (let* ((behavior (fsvn-deps--fetch-command-behavior svn-command))
1270+ (ensurer (nth 3 behavior))
1271+ (targets-converter (nth 4 behavior)))
1272+ (if (and (null ensurer)
1273+ (null targets-converter))
12471274 args
1248- (mapcar
1249- (lambda (x)
1250- (cond
1251- ((fsvn-url-local-p x)
1252- (funcall ensurer x))
1253- ((string-match "\\`\\(--[^=]+\\)=\\(.*\\)" x)
1254- (let ((option (match-string 1 x))
1255- (path (match-string 2 x)))
1256- (if (fsvn-url-local-p path)
1257- (format "%s=%s" option (funcall ensurer path))
1258- x)))
1259- (t
1260- x)))
1261- args))))
1275+ (let ((targetp nil))
1276+ (mapcar
1277+ (lambda (x)
1278+ (cond
1279+ ((fsvn-url-local-p x)
1280+ (when (and targetp targets-converter)
1281+ (funcall targets-converter x))
1282+ (setq targetp nil)
1283+ (cond
1284+ (ensurer
1285+ (funcall ensurer x))
1286+ (t x)))
1287+ ((string-match "\\`\\(--[^=]+\\)=\\(.*\\)" x)
1288+ (setq targetp nil)
1289+ (let ((option (match-string 1 x))
1290+ (path (match-string 2 x)))
1291+ (if (fsvn-url-local-p path)
1292+ (format "%s=%s" option (funcall ensurer path))
1293+ x)))
1294+ ((string= "--targets" x)
1295+ (setq targetp t)
1296+ x)
1297+ (t
1298+ (setq targetp nil)
1299+ x)))
1300+ args)))))
12621301
12631302
12641303
--- trunk/fsvn-win.el (revision 323)
+++ trunk/fsvn-win.el (revision 324)
@@ -24,8 +24,6 @@
2424 (defvar diff-switches)
2525 (defvar current-prefix-arg)
2626
27-(defvar fsvn-targets-file-converter)
28-
2927
3028
3129 (defun fsvn-win-x64-p ()
@@ -206,13 +204,13 @@
206204 (defun fsvn-cygwin-guessed-installed ()
207205 (fsvn-cygwin-installed-folder))
208206
209-(defvar fsvn-cygwin-svn-p nil)
210-(defun fsvn-cygwin-svn-p ()
211- (let ((command (executable-find fsvn-svn-command-internal))
212- (cygdir (fsvn-cygwin-installed-dir)))
213- (and command
214- cygdir
215- (string-match (concat "\\`" (regexp-quote cygdir)) command))))
207+(defun fsvn-cygwin-svn-p (&optional command)
208+ (fsvn-let*
209+ ((filename (or command fsvn-svn-command-internal))
210+ (command-path (executable-find filename))
211+ (cygdir (fsvn-cygwin-installed-dir))
212+ ((string-match (concat "\\`" (regexp-quote cygdir)) command-path)))
213+ t))
216214
217215 (defun fsvn-cygwin-expand-path (name &optional default)
218216 (let ((inst-dir fsvn-cygwin-installed-dir)
@@ -261,32 +259,43 @@
261259 (setq fsvn-url-filename-expand-function 'fsvn-win-expand-file)
262260
263261 ;; cygwin svn `--targets' arg accept only cygpath
264-(defun fsvn-win-targets-file-converter (x)
265- (fsvn-cygwin-expand-path x))
262+;; It is not so high cost re-generate target file, I think..
263+(defun fsvn-cygwin-convert-target-file (file)
264+ (with-temp-buffer
265+ (let ((coding-system-for-read (fsvn-file-name-coding-system)))
266+ (insert-file-contents file))
267+ (goto-char (point-min))
268+ (while (not (eobp))
269+ (let ((file (buffer-substring (point-at-bol) (point-at-eol))))
270+ (delete-region (point-at-bol) (point-at-eol))
271+ (insert (fsvn-cygwin-ensure-physical-path file))
272+ (forward-line 1)))
273+ (let ((coding-system-for-write (fsvn-file-name-coding-system)))
274+ (write-region (point-min) (point-max) file nil 'no-msg))))
266275
267276 (defun fsvn-win-initialize-loading ()
268- (setq fsvn-cygwin-svn-p (fsvn-cygwin-svn-p))
269277 ;; Update cygwin settings
270278 ;; FIXME: about after install/reinstall/uninstall cygwin
271279 (setq fsvn-cygwin-installed-folder (fsvn-cygwin-installed-folder)
272280 fsvn-cygwin-guessed-installed (fsvn-cygwin-guessed-installed)
273281 fsvn-cygwin-installed-dir (fsvn-cygwin-installed-dir)
274- fsvn-cygwin-drive-prefix-dir (fsvn-cygwin-drive-prefix-dir))
275- (cond
276- (fsvn-cygwin-svn-p
277- (setq fsvn-targets-file-converter 'fsvn-win-targets-file-converter
278- fsvn-password-prompt-accessible-p t))
282+ fsvn-cygwin-drive-prefix-dir (fsvn-cygwin-drive-prefix-dir)))
283+
284+(defun fsvn-win-after-initialize-loading ()
285+ (cond
286+ ;; FIXME this is only works default svn-command
287+ ;; Currently `fsvn-authenticate-repository' is a function
288+ ;; only use this variable (`fsvn-password-prompt-accessible-p')
289+ ((fsvn-cygwin-svn-p)
290+ (setq fsvn-password-prompt-accessible-p t))
279291 (t
280- (setq fsvn-targets-file-converter nil
281- fsvn-password-prompt-accessible-p nil))))
292+ (setq fsvn-password-prompt-accessible-p nil))))
282293
283-(setq fsvn-initialize-function 'fsvn-win-initialize-loading)
294+(add-hook 'fsvn--initialize-hook 'fsvn-win-initialize-loading)
295+(add-hook 'fsvn--after-initialize-hook 'fsvn-win-after-initialize-loading)
284296
285297
286298
287-(defun fsvn-win-enable-password-prompt ()
288- fsvn-cygwin-svn-p)
289-
290299 (defun fsvn-win-authenticate-repository (repository)
291300 (fsvn-win-start-external-terminal fsvn-svn-command-internal "info" repository))
292301
Show on old repository browser