magit / forge

Work with Git forges from the comfort of Magit
GNU General Public License v3.0
1.31k stars 115 forks source link

Support for private gitlab instances via http #9

Closed wedens closed 4 years ago

wedens commented 5 years ago

It'd be great to have a support for private gitlab instances.

Currently trying to use forge from a repo results in:

progn: Cannot determine forge repository.  git@gitlab.company.lan:xyz/abc.git isn’t a forge url
wedens commented 5 years ago

I've tried using forge-alist:

(add-to-list 'forge-alist '("gitlab.company.lan" "gitlab.company.lan/api/v4" "gitlab.company.lan" forge-gitlab-repository))

in ~/.authinfo:

machine gitlab.company.lan/api/v4 login wedens^forge password myapitoken

results in:

open-network-stream: make client process failed: Connection refused, :name, gitlab.company.lan, :buffer, #<killed buffer>, :host, gitlab.company.lan, :service, 443, :nowait, nil, :tls-parameters, nil

Looks like it's trying to access it via https, but it's available only via http. Can I change that?

manuel-uberti commented 5 years ago

Getting a similar error in a project on the company's GitLab:

Cannot determine forge repository.  git@lab.7bridges.eu:gaypa/sage-etl.git isn’t a forge url
wedens commented 5 years ago

@manuel-uberti Have you tried adding it to ~/.authinfo and forge-alist as I've mentioned above?

Our private instance is accessible only via http and forge hard-codes https, so I can't test it further than that.

manuel-uberti commented 5 years ago

Yes, I get:

Debugger entered--Lisp error: (cl-no-applicable-method forge--split-url-path nil "gaypa/sage-etl")
  signal(cl-no-applicable-method (forge--split-url-path nil "gaypa/sage-etl"))
  cl-no-applicable-method(#s(cl--generic :name forge--split-url-path :dispatches ((1 #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x25c4f9>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x25c50d>))) (0 #s(cl--generic-generalizer :name eieio--generic-subclass-generalizer :priority 60 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x51db45>) :specializers-function eieio--generic-subclass-specializers) #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x25c4f9>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x25c50d>)))) :method-table (#s(cl--generic-method :specializers ((subclass forge-noapi-repository) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (class path) #<bytecode 0x28f75b5>)) #s(cl--generic-method :specializers ((subclass forge-repository) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (class path) #<bytecode 0x28f759d>))) :options nil) nil "gaypa/sage-etl")
  apply(cl-no-applicable-method #s(cl--generic :name forge--split-url-path :dispatches ((1 #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x25c4f9>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x25c50d>))) (0 #s(cl--generic-generalizer :name eieio--generic-subclass-generalizer :priority 60 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x51db45>) :specializers-function eieio--generic-subclass-specializers) #s(cl--generic-generalizer :name cl--generic-t-generalizer :priority 0 :tagcode-function #f(compiled-function (name &rest _) #<bytecode 0x25c4f9>) :specializers-function #f(compiled-function (tag &rest _) #<bytecode 0x25c50d>)))) :method-table (#s(cl--generic-method :specializers ((subclass forge-noapi-repository) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (class path) #<bytecode 0x28f75b5>)) #s(cl--generic-method :specializers ((subclass forge-repository) t) :qualifiers nil :uses-cnm nil :function #f(compiled-function (class path) #<bytecode 0x28f759d>))) :options nil) (nil "gaypa/sage-etl"))
  #f(compiled-function (&rest args) #<bytecode 0x28c6815>)(nil "gaypa/sage-etl")
  apply(#f(compiled-function (&rest args) #<bytecode 0x28c6815>) nil "gaypa/sage-etl")
  forge--split-url-path(nil "gaypa/sage-etl")
  forge--split-url("git@lab.7bridges.eu:gaypa/sage-etl.git")
  #f(compiled-function (url &optional remote demand) "Return the repository at URL." #<bytecode 0x114e049>)("git@lab.7bridges.eu:gaypa/sage-etl.git" "origin" full)
  apply(#f(compiled-function (url &optional remote demand) "Return the repository at URL." #<bytecode 0x114e049>) "git@lab.7bridges.eu:gaypa/sage-etl.git" ("origin" full))
  forge-get-repository("git@lab.7bridges.eu:gaypa/sage-etl.git" "origin" full)
  #f(compiled-function (demand &optional remote) "Return the forge repository for the current Git repository." #<bytecode 0x112b0dd>)(full)
  apply(#f(compiled-function (demand &optional remote) "Return the forge repository for the current Git repository." #<bytecode 0x112b0dd>) full nil)
  forge-get-repository(full)
  forge-bug-reference-setup()
  run-hooks(change-major-mode-after-body-hook special-mode-hook magit-mode-hook magit-status-mode-hook)
  apply(run-hooks (change-major-mode-after-body-hook special-mode-hook magit-mode-hook magit-status-mode-hook))
  run-mode-hooks(magit-status-mode-hook)
  magit-status-mode()
  magit-mode-setup-internal(magit-status-mode nil)
  magit-mode-setup(magit-status-mode)
  magit-status-internal("/home/manuel/7bridges/code/sage-etl/")
  projectile-vc()
  counsel-projectile-switch-project-by-name("~/7bridges/code/sage-etl/")
  counsel-projectile-switch-project-action-vc("~/7bridges/code/sage-etl/")
  ivy-call()
  #f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\n`ivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with `completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with `ivy-minibuffer-map'.\n\nIf PRESELECT is not nil, then select the corresponding candidate\nout of the ones that match the INITIAL-INPUT.\n\nDEF is for compatibility with `completing-read'.\n\nUPDATE-FN is called each time the candidate list is redisplayed.\n\nWhen SORT is non-nil, `ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes the candidate, which is a string, as its only argument.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input.  It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nCALLER is a symbol to uniquely identify the caller to `ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0x136ef75>)("[-] Switch to project: " ("~/org/" "~/.emacs.d/" "~/7bridges/code/sage-etl/" "~/githubs/manuel-uberti/newtab/" "~/githubs/manuel-uberti/manuel-uberti.github.io/" "~/githubs/manuel-uberti/playbooks/" "~/.config/fish/" "~/7bridges/code/gaypa-docs/" "~/githubs/manuel-uberti/boodle/" "~/7bridges/code/playbooks/" "~/githubs/manuel-uberti/filmsinwords/" "~/emacs/" "~/7bridges/code/onyx-test/" "~/githubs/learn-onyx/" "~/7bridges/code/filmango/" "~/7bridges/code/chronicler/" "~/7bridges/code/onyx-dashboard/" "~/7bridges/code/clj-odbp/" "~/7bridges/code/maurice/" "~/.clojure/" "~/7bridges/code/7bv2/" "~/githubs/manuel-uberti/stash/" "~/7bridges/code/onyx-test-bak/" "~/7bridges/code/antigone/" "~/Documents/curriculum/Awesome-CV/" "~/7bridges/code/sage-soap/" "~/7bridges/code/routing-channels/" "~/7bridges/code/ethanol/" "~/githubs/manuel-uberti/four-clojure/" "~/githubs/manuel-uberti/haskell-programming/" "~/7bridges/code/exoscale/" "~/7bridges/code/gaypa-hr/") :preselect nil :action (1 ("o" counsel-projectile-switch-project-action "jump to a project buffer or file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("D" counsel-projectile-switch-project-action-dired "open project in dired") ("b" counsel-projectile-switch-project-action-switch-to-buffer "jump to a project buffer") ("m" counsel-projectile-switch-project-action-find-file-manually "find file manually from project root") ("S" counsel-projectile-switch-project-action-save-all-buffers "save all project buffers") ("k" counsel-projectile-switch-project-action-kill-buffers "kill all project buffers") ("K" counsel-projectile-switch-project-action-remove-known-project "remove project from known projects") ("c" counsel-projectile-switch-project-action-compile "run project compilation command") ("C" counsel-projectile-switch-project-action-configure "run project configure command") ("E" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals") ("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky") ("sg" counsel-projectile-switch-project-action-grep "search project with grep") ("si" counsel-projectile-switch-project-action-git-grep "search project with git grep") ("ss" counsel-projectile-switch-project-action-ag "search project with ag") ("sr" counsel-projectile-switch-project-action-rg "search project with rg") ("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root") ("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("Oc" counsel-projectile-switch-project-action-org-capture "capture into project") ("Oa" counsel-projectile-switch-project-action-org-agenda "open project agenda")) :require-match t :sort nil :caller counsel-projectile-switch-project)
  apply(#f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\n`ivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with `completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with `ivy-minibuffer-map'.\n\nIf PRESELECT is not nil, then select the corresponding candidate\nout of the ones that match the INITIAL-INPUT.\n\nDEF is for compatibility with `completing-read'.\n\nUPDATE-FN is called each time the candidate list is redisplayed.\n\nWhen SORT is non-nil, `ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes the candidate, which is a string, as its only argument.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input.  It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nCALLER is a symbol to uniquely identify the caller to `ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0x136ef75>) ("[-] Switch to project: " ("~/org/" "~/.emacs.d/" "~/7bridges/code/sage-etl/" "~/githubs/manuel-uberti/newtab/" "~/githubs/manuel-uberti/manuel-uberti.github.io/" "~/githubs/manuel-uberti/playbooks/" "~/.config/fish/" "~/7bridges/code/gaypa-docs/" "~/githubs/manuel-uberti/boodle/" "~/7bridges/code/playbooks/" "~/githubs/manuel-uberti/filmsinwords/" "~/emacs/" "~/7bridges/code/onyx-test/" "~/githubs/learn-onyx/" "~/7bridges/code/filmango/" "~/7bridges/code/chronicler/" "~/7bridges/code/onyx-dashboard/" "~/7bridges/code/clj-odbp/" "~/7bridges/code/maurice/" "~/.clojure/" "~/7bridges/code/7bv2/" "~/githubs/manuel-uberti/stash/" "~/7bridges/code/onyx-test-bak/" "~/7bridges/code/antigone/" "~/Documents/curriculum/Awesome-CV/" "~/7bridges/code/sage-soap/" "~/7bridges/code/routing-channels/" "~/7bridges/code/ethanol/" "~/githubs/manuel-uberti/four-clojure/" "~/githubs/manuel-uberti/haskell-programming/" "~/7bridges/code/exoscale/" "~/7bridges/code/gaypa-hr/") :preselect nil :action (1 ("o" counsel-projectile-switch-project-action "jump to a project buffer or file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("D" counsel-projectile-switch-project-action-dired "open project in dired") ("b" counsel-projectile-switch-project-action-switch-to-buffer "jump to a project buffer") ("m" counsel-projectile-switch-project-action-find-file-manually "find file manually from project root") ("S" counsel-projectile-switch-project-action-save-all-buffers "save all project buffers") ("k" counsel-projectile-switch-project-action-kill-buffers "kill all project buffers") ("K" counsel-projectile-switch-project-action-remove-known-project "remove project from known projects") ("c" counsel-projectile-switch-project-action-compile "run project compilation command") ("C" counsel-projectile-switch-project-action-configure "run project configure command") ("E" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals") ("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky") ("sg" counsel-projectile-switch-project-action-grep "search project with grep") ("si" counsel-projectile-switch-project-action-git-grep "search project with git grep") ("ss" counsel-projectile-switch-project-action-ag "search project with ag") ("sr" counsel-projectile-switch-project-action-rg "search project with rg") ("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root") ("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("Oc" counsel-projectile-switch-project-action-org-capture "capture into project") ("Oa" counsel-projectile-switch-project-action-org-agenda "open project agenda")) :require-match t :sort nil :caller counsel-projectile-switch-project))
  ivy-historian--nadvice/ivy-read(#f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\n`ivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with `completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with `ivy-minibuffer-map'.\n\nIf PRESELECT is not nil, then select the corresponding candidate\nout of the ones that match the INITIAL-INPUT.\n\nDEF is for compatibility with `completing-read'.\n\nUPDATE-FN is called each time the candidate list is redisplayed.\n\nWhen SORT is non-nil, `ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes the candidate, which is a string, as its only argument.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input.  It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nCALLER is a symbol to uniquely identify the caller to `ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0x136ef75>) "[-] Switch to project: " ("~/org/" "~/.emacs.d/" "~/7bridges/code/sage-etl/" "~/githubs/manuel-uberti/newtab/" "~/githubs/manuel-uberti/manuel-uberti.github.io/" "~/githubs/manuel-uberti/playbooks/" "~/.config/fish/" "~/7bridges/code/gaypa-docs/" "~/githubs/manuel-uberti/boodle/" "~/7bridges/code/playbooks/" "~/githubs/manuel-uberti/filmsinwords/" "~/emacs/" "~/7bridges/code/onyx-test/" "~/githubs/learn-onyx/" "~/7bridges/code/filmango/" "~/7bridges/code/chronicler/" "~/7bridges/code/onyx-dashboard/" "~/7bridges/code/clj-odbp/" "~/7bridges/code/maurice/" "~/.clojure/" "~/7bridges/code/7bv2/" "~/githubs/manuel-uberti/stash/" "~/7bridges/code/onyx-test-bak/" "~/7bridges/code/antigone/" "~/Documents/curriculum/Awesome-CV/" "~/7bridges/code/sage-soap/" "~/7bridges/code/routing-channels/" "~/7bridges/code/ethanol/" "~/githubs/manuel-uberti/four-clojure/" "~/githubs/manuel-uberti/haskell-programming/" "~/7bridges/code/exoscale/" "~/7bridges/code/gaypa-hr/") :preselect nil :action (1 ("o" counsel-projectile-switch-project-action "jump to a project buffer or file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("D" counsel-projectile-switch-project-action-dired "open project in dired") ("b" counsel-projectile-switch-project-action-switch-to-buffer "jump to a project buffer") ("m" counsel-projectile-switch-project-action-find-file-manually "find file manually from project root") ("S" counsel-projectile-switch-project-action-save-all-buffers "save all project buffers") ("k" counsel-projectile-switch-project-action-kill-buffers "kill all project buffers") ("K" counsel-projectile-switch-project-action-remove-known-project "remove project from known projects") ("c" counsel-projectile-switch-project-action-compile "run project compilation command") ("C" counsel-projectile-switch-project-action-configure "run project configure command") ("E" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals") ("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky") ("sg" counsel-projectile-switch-project-action-grep "search project with grep") ("si" counsel-projectile-switch-project-action-git-grep "search project with git grep") ("ss" counsel-projectile-switch-project-action-ag "search project with ag") ("sr" counsel-projectile-switch-project-action-rg "search project with rg") ("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root") ("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("Oc" counsel-projectile-switch-project-action-org-capture "capture into project") ("Oa" counsel-projectile-switch-project-action-org-agenda "open project agenda")) :require-match t :sort nil :caller counsel-projectile-switch-project)
  apply(ivy-historian--nadvice/ivy-read #f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\n`ivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with `completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with `ivy-minibuffer-map'.\n\nIf PRESELECT is not nil, then select the corresponding candidate\nout of the ones that match the INITIAL-INPUT.\n\nDEF is for compatibility with `completing-read'.\n\nUPDATE-FN is called each time the candidate list is redisplayed.\n\nWhen SORT is non-nil, `ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes the candidate, which is a string, as its only argument.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input.  It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nCALLER is a symbol to uniquely identify the caller to `ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0x136ef75>) ("[-] Switch to project: " ("~/org/" "~/.emacs.d/" "~/7bridges/code/sage-etl/" "~/githubs/manuel-uberti/newtab/" "~/githubs/manuel-uberti/manuel-uberti.github.io/" "~/githubs/manuel-uberti/playbooks/" "~/.config/fish/" "~/7bridges/code/gaypa-docs/" "~/githubs/manuel-uberti/boodle/" "~/7bridges/code/playbooks/" "~/githubs/manuel-uberti/filmsinwords/" "~/emacs/" "~/7bridges/code/onyx-test/" "~/githubs/learn-onyx/" "~/7bridges/code/filmango/" "~/7bridges/code/chronicler/" "~/7bridges/code/onyx-dashboard/" "~/7bridges/code/clj-odbp/" "~/7bridges/code/maurice/" "~/.clojure/" "~/7bridges/code/7bv2/" "~/githubs/manuel-uberti/stash/" "~/7bridges/code/onyx-test-bak/" "~/7bridges/code/antigone/" "~/Documents/curriculum/Awesome-CV/" "~/7bridges/code/sage-soap/" "~/7bridges/code/routing-channels/" "~/7bridges/code/ethanol/" "~/githubs/manuel-uberti/four-clojure/" "~/githubs/manuel-uberti/haskell-programming/" "~/7bridges/code/exoscale/" "~/7bridges/code/gaypa-hr/") :preselect nil :action (1 ("o" counsel-projectile-switch-project-action "jump to a project buffer or file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("D" counsel-projectile-switch-project-action-dired "open project in dired") ("b" counsel-projectile-switch-project-action-switch-to-buffer "jump to a project buffer") ("m" counsel-projectile-switch-project-action-find-file-manually "find file manually from project root") ("S" counsel-projectile-switch-project-action-save-all-buffers "save all project buffers") ("k" counsel-projectile-switch-project-action-kill-buffers "kill all project buffers") ("K" counsel-projectile-switch-project-action-remove-known-project "remove project from known projects") ("c" counsel-projectile-switch-project-action-compile "run project compilation command") ("C" counsel-projectile-switch-project-action-configure "run project configure command") ("E" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals") ("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky") ("sg" counsel-projectile-switch-project-action-grep "search project with grep") ("si" counsel-projectile-switch-project-action-git-grep "search project with git grep") ("ss" counsel-projectile-switch-project-action-ag "search project with ag") ("sr" counsel-projectile-switch-project-action-rg "search project with rg") ("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root") ("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("Oc" counsel-projectile-switch-project-action-org-capture "capture into project") ("Oa" counsel-projectile-switch-project-action-org-agenda "open project agenda")) :require-match t :sort nil :caller counsel-projectile-switch-project))
  ivy-read("[-] Switch to project: " ("~/org/" "~/.emacs.d/" "~/7bridges/code/sage-etl/" "~/githubs/manuel-uberti/newtab/" "~/githubs/manuel-uberti/manuel-uberti.github.io/" "~/githubs/manuel-uberti/playbooks/" "~/.config/fish/" "~/7bridges/code/gaypa-docs/" "~/githubs/manuel-uberti/boodle/" "~/7bridges/code/playbooks/" "~/githubs/manuel-uberti/filmsinwords/" "~/emacs/" "~/7bridges/code/onyx-test/" "~/githubs/learn-onyx/" "~/7bridges/code/filmango/" "~/7bridges/code/chronicler/" "~/7bridges/code/onyx-dashboard/" "~/7bridges/code/clj-odbp/" "~/7bridges/code/maurice/" "~/.clojure/" "~/7bridges/code/7bv2/" "~/githubs/manuel-uberti/stash/" "~/7bridges/code/onyx-test-bak/" "~/7bridges/code/antigone/" "~/Documents/curriculum/Awesome-CV/" "~/7bridges/code/sage-soap/" "~/7bridges/code/routing-channels/" "~/7bridges/code/ethanol/" "~/githubs/manuel-uberti/four-clojure/" "~/githubs/manuel-uberti/haskell-programming/" "~/7bridges/code/exoscale/" "~/7bridges/code/gaypa-hr/") :preselect nil :action (1 ("o" counsel-projectile-switch-project-action "jump to a project buffer or file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("D" counsel-projectile-switch-project-action-dired "open project in dired") ("b" counsel-projectile-switch-project-action-switch-to-buffer "jump to a project buffer") ("m" counsel-projectile-switch-project-action-find-file-manually "find file manually from project root") ("S" counsel-projectile-switch-project-action-save-all-buffers "save all project buffers") ("k" counsel-projectile-switch-project-action-kill-buffers "kill all project buffers") ("K" counsel-projectile-switch-project-action-remove-known-project "remove project from known projects") ("c" counsel-projectile-switch-project-action-compile "run project compilation command") ("C" counsel-projectile-switch-project-action-configure "run project configure command") ("E" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals") ("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky") ("sg" counsel-projectile-switch-project-action-grep "search project with grep") ("si" counsel-projectile-switch-project-action-git-grep "search project with git grep") ("ss" counsel-projectile-switch-project-action-ag "search project with ag") ("sr" counsel-projectile-switch-project-action-rg "search project with rg") ("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root") ("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("Oc" counsel-projectile-switch-project-action-org-capture "capture into project") ("Oa" counsel-projectile-switch-project-action-org-agenda "open project agenda")) :require-match t :sort nil :caller counsel-projectile-switch-project)
  counsel-projectile-switch-project()
  funcall-interactively(counsel-projectile-switch-project)
  call-interactively(counsel-projectile-switch-project nil nil)
  command-execute(counsel-projectile-switch-project)
manuel-uberti commented 5 years ago

I guess my error is related to https://github.com/magit/forge/issues/17

tomjorquera commented 5 years ago

@manuel-uberti I'm not sure your issue is related to #17. "My" issue concerns paths that are more than 2 "segments" long (foo/bar/baz instead of foo/bar). Your seems fine in this regard.

I'm not an elisp expert but it seems to me that forge--split-url-path use dynamic dispatch depending on the class of the repository, and it does not find an appropriate class for your forge to dispatch on.

What arguments did you use when you added your forge to forge-alist ?

tomjorquera commented 5 years ago

Also @wedens, maybe a workaround for further testing would be to create a forge-gitlab-http based on https://github.com/magit/forge/blob/master/lisp/forge-gitlab.el by simply replacing all https with http, then declare your forge to be a forge-gitlab-http when adding it to forge-alist and see if it brings you further.

manuel-uberti commented 5 years ago

@tomjorquera

(add-to-list 'forge-alist '("lab.7bridges.eu" forge-gitlab-repository))
tomjorquera commented 5 years ago

@manuel-uberti I think you're missing some args. Try something like

(add-to-list 'forge-alist '("lab.7bridges.eu" "lab.7bridges.eu/api/v4" "lab.7bridges.eu" forge-gitlab-repository))
manuel-uberti commented 5 years ago

Thank you, it's asking me this now on F y:

Git variable `gitlab.lab.7bridges.eu/api/v4.user' is unset.  Set to: 

But I guess now it's only a matter of configuration.

Edit: It's working. Thanks guys.

winpat commented 5 years ago

Edit: It's working. Thanks guys.

@manuel-uberti I get Required Gitlab token ("user^forge" for "git.company.com/api/v4") does not exist. after setting the user variable. Did you run into the same problem?

oceyral commented 5 years ago

@winpat see ~/.authinfo: https://github.com/magit/forge/issues/9#issuecomment-448866035

manuel-uberti commented 5 years ago

@winpat sorry I forgot to mention: I created a token on GitLab and edit ~/.authinfo accordingly, as @oceyral pointed out.

winpat commented 5 years ago

@oceyral Sorry, I should have mentioned that my .authinfo file exists.

machine git.company.com/api/v4 login user^forge password TOKEN

That is the weird part about it.

tarsius commented 5 years ago

Our private instance is accessible only via http and forge hard-codes https,

I was aware that this could become a problem, but decided to just support https. Also supporting http would be possible but complicate things and I concluded it wasn't worth it. Once could argue that a host only (or even also) being available using http is doing-it-wrong-tm (unless only reachable from within the company network, but even then...).

So I am afaid I don't intend to do anything about this. You'll have to get the responsible person at your company to configure https.

Meanwhile you might be able to deal with it using some advice. The right function to advice would probably be url-generic-parse-url. (If you do that, then please add it to https://github.com/magit/forge/wiki/Tips-and-Tricks.)

wedens commented 5 years ago

Once could argue that a host only (or even also) being available using http is doing-it-wrong-tm (unless only reachable from within the company network, but even then...).

It's not available outside of LAN, so it's not that bad :)

So I am afaid I don't intend to do anything about this. You'll have to get the responsible person at your company to configure https.

I agree with you and I totally understand why you may not want to add such thing.

tarsius commented 5 years ago

Okay and thanks. Closing this then.

Fuuzetsu commented 5 years ago

I'd just like to pipe up and say that we have the same issue: Gitlab instance is reachable on local network only so it uses HTTP. Of course I pinged the relevant person but it's unknown when it's going to be change if at all. Seems like a pretty common case, maybe it's worth to reconsider...

Thanks.

shuxiao9058 commented 5 years ago

I have the same question, how to resolve it?

tarsius commented 5 years ago

Please try if simply using a separate "http" class does the trick.

Evaluate the class definition and the function redefinition, and adjust the forge-alist entry:

(defclass forge-gitlab-http-repository (forge-gitlab-repository)
  ((issues-url-format         :initform "http://%h/%o/%n/issues")
   (issue-url-format          :initform "http://%h/%o/%n/issues/%i")
   (issue-post-url-format     :initform "http://%h/%o/%n/issues/%i#note_%I")
   (pullreqs-url-format       :initform "http://%h/%o/%n/merge_requests")
   (pullreq-url-format        :initform "http://%h/%o/%n/merge_requests/%i")
   (pullreq-post-url-format   :initform "http://%h/%o/%n/merge_requests/%i#note_%I")
   (commit-url-format         :initform "http://%h/%o/%n/commit/%r")
   (branch-url-format         :initform "http://%h/%o/%n/commits/%r")
   (remote-url-format         :initform "http://%h/%o/%n")
   (create-issue-url-format   :initform "http://%h/%o/%n/issues/new")
   (create-pullreq-url-format :initform "http://%h/%o/%n/merge_requests/new")
   (pullreq-refspec :initform "+refs/merge-requests/*/head:refs/pullreqs/*")))

(defun forge--url-regexp ()
  (concat "\\`\\(?:git://\\|[^/@]+@\\|ssh://\\(?:[^/@]+@\\)?\\|https?://\\)"
          (regexp-opt (mapcar #'car forge-alist) t)
          "[:/]\\(.+?\\)"
          "\\(?:\\.git\\|/\\)?\\'"))

(forge--branch-pullreq should also be adjusted, but just for trying if this works that's not necessary.)

tarsius commented 5 years ago

I have made the necessary changes to forge--branch-pullreq and forge--url-regexp. I am fairly confident that those changes together with a http-only class do the trick, but because I do not have access to an insecure gitlab instance I cannot actually try this out.

Fuuzetsu commented 4 years ago

This still seems like it wouldn't work because of things like https://github.com/magit/ghub/blob/master/ghub.el#L341 no? At least I'm still seeing it try for https:// and obviously fail due to it.

tarsius commented 4 years ago

Yeah you are right, that can't possibly work.

tarsius commented 4 years ago

https://github.com/magit/ghub/commit/be460be79d20f95ef8bbe75c14d4a25c7a10304d should take care of this. Please try it out and let me know.

Fuuzetsu commented 4 years ago

I evaluated forge-gitlab-http-repository and adjusted forge-alist. I can do forge-pull without it immediately crashing now. That's great.

I do only get a Pulling <repo name>... message though and can't tell if it's doing anything after that (doesn't seem to be) but I'll try to debug that as a separate problem.

Would it be possible to include forge-gitlab-http-repository in forge itself?

Fuuzetsu commented 4 years ago

Actually, I'm unsure if that worked. After messing with it a bit, I started getting errors like so if I try to forge-pull. I deleted the forge-sqlite database as I thought maybe I had a stale one from previous attempts but the error seems unrelated:

Debugger entered--Lisp error: (error "cl-ecase failed: forge-gitlab-http-repository, (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository)")
  signal(error ("cl-ecase failed: forge-gitlab-http-repository, (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository)"))
  error("cl-ecase failed: %s, %s" forge-gitlab-http-repository (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository))
  (cond ((eql class (quote forge-github-repository)) (quote ghub)) ((eql class (quote forge-gitlab-repository)) (quote glab)) ((eql class (quote forge-gitea-repository)) (quote gtea)) ((eql class (quote forge-gogs-repository)) (quote gogs)) ((eql class (quote forge-bitbucket-repository)) (quote buck)) ((error "cl-ecase failed: %s, %s" class (quote (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository))) nil))
  (ghub-repository-id owner name :host apihost :auth (quote forge) :forge (cond ((eql class (quote forge-github-repository)) (quote ghub)) ((eql class (quote forge-gitlab-repository)) (quote glab)) ((eql class (quote forge-gitea-repository)) (quote gtea)) ((eql class (quote forge-gogs-repository)) (quote gogs)) ((eql class (quote forge-bitbucket-repository)) (quote buck)) ((error "cl-ecase failed: %s, %s" class (quote (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository))) nil)))
  (and (not stub) (ghub-repository-id owner name :host apihost :auth (quote forge) :forge (cond ((eql class (quote forge-github-repository)) (quote ghub)) ((eql class (quote forge-gitlab-repository)) (quote glab)) ((eql class (quote forge-gitea-repository)) (quote gtea)) ((eql class (quote forge-gogs-repository)) (quote gogs)) ((eql class (quote forge-bitbucket-repository)) (quote buck)) ((error "cl-ecase failed: %s, %s" class (quote (forge-github-repository forge-gitlab-repository forge-gitea-repository forge-gogs-repository forge-bitbucket-repository))) nil))))
  (let* ((path (format "%s/%s" owner name)) (their-id (and (not stub) (ghub-repository-id owner name :host apihost :auth (quote forge) :forge (cond ((eql class ...) (quote ghub)) ((eql class ...) (quote glab)) ((eql class ...) (quote gtea)) ((eql class ...) (quote gogs)) ((eql class ...) (quote buck)) ((error "cl-ecase failed: %s, %s" class ...) nil)))))) (cons (base64-encode-string (format "%s:%s" id (cond (stub path) ((eq class (quote forge-github-repository)) (base64-decode-string their-id)) (t their-id))) t) (or their-id path)))
  (let ((_class x767) (id x765) (apihost x763) (_githost x761)) (let* ((path (format "%s/%s" owner name)) (their-id (and (not stub) (ghub-repository-id owner name :host apihost :auth (quote forge) :forge (cond (... ...) (... ...) (... ...) (... ...) (... ...) (... nil)))))) (cons (base64-encode-string (format "%s:%s" id (cond (stub path) ((eq class ...) (base64-decode-string their-id)) (t their-id))) t) (or their-id path))))
  (let* ((val (or (assoc host forge-alist) (error "No entry for %S in forge-alist" host))) (x761 (car val)) (x762 (cdr val)) (x763 (car x762)) (x764 (cdr x762)) (x765 (car x764)) (x766 (cdr x764)) (x767 (car x766)) (x768 (cdr x766))) (let ((_class x767) (id x765) (apihost x763) (_githost x761)) (let* ((path (format "%s/%s" owner name)) (their-id (and (not stub) (ghub-repository-id owner name :host apihost :auth (quote forge) :forge (cond ... ... ... ... ... ...))))) (cons (base64-encode-string (format "%s:%s" id (cond (stub path) (... ...) (t their-id))) t) (or their-id path)))))
  (progn (let* ((val (or (assoc host forge-alist) (error "No entry for %S in forge-alist" host))) (x761 (car val)) (x762 (cdr val)) (x763 (car x762)) (x764 (cdr x762)) (x765 (car x764)) (x766 (cdr x764)) (x767 (car x766)) (x768 (cdr x766))) (let ((_class x767) (id x765) (apihost x763) (_githost x761)) (let* ((path (format "%s/%s" owner name)) (their-id (and (not stub) (ghub-repository-id owner name :host apihost :auth ... :forge ...)))) (cons (base64-encode-string (format "%s:%s" id (cond ... ... ...)) t) (or their-id path))))))
  (closure (t) (class host owner name &optional stub) "Return (OUR-ID . THEIR-ID) of the specified repository.\nIf optional STUB is non-nil, then the IDs are not guaranteed to\nbe unique.  Otherwise this method has to make an API request to\nretrieve THEIR-ID, the repository's ID on the forge.  In that\ncase OUR-ID derives from THEIR-ID and is unique across all\nforges and hosts." (progn (let* ((val (or (assoc host forge-alist) (error "No entry for %S in forge-alist" host))) (x761 (car val)) (x762 (cdr val)) (x763 (car x762)) (x764 (cdr x762)) (x765 (car x764)) (x766 (cdr x764)) (x767 (car x766)) (x768 (cdr x766))) (let ((_class x767) (id x765) (apihost x763) (_githost x761)) (let* ((path (format "%s/%s" owner name)) (their-id (and ... ...))) (cons (base64-encode-string (format "%s:%s" id ...) t) (or their-id path)))))))(forge-gitlab-http-repository "gitlab.tsuru.it" "tsuru" "trader" nil)
  apply((closure (t) (class host owner name &optional stub) "Return (OUR-ID . THEIR-ID) of the specified repository.\nIf optional STUB is non-nil, then the IDs are not guaranteed to\nbe unique.  Otherwise this method has to make an API request to\nretrieve THEIR-ID, the repository's ID on the forge.  In that\ncase OUR-ID derives from THEIR-ID and is unique across all\nforges and hosts." (progn (let* ((val (or (assoc host forge-alist) (error "No entry for %S in forge-alist" host))) (x761 (car val)) (x762 (cdr val)) (x763 (car x762)) (x764 (cdr x762)) (x765 (car x764)) (x766 (cdr x764)) (x767 (car x766)) (x768 (cdr x766))) (let ((_class x767) (id x765) (apihost x763) (_githost x761)) (let* ((path ...) (their-id ...)) (cons (base64-encode-string ... t) (or their-id path))))))) forge-gitlab-http-repository ("gitlab.tsuru.it" "tsuru" "trader" nil))
  forge--repository-ids(forge-gitlab-http-repository "gitlab.tsuru.it" "tsuru" "trader" nil)
  (let* ((val (forge--repository-ids class host owner name (eq demand (quote stub)))) (x777 (car val)) (x778 (cdr val))) (let ((forge-id x778) (id x777)) (setq obj (funcall class :id id :forge-id forge-id :forge forge :owner owner :name name :apihost apihost :githost githost :remote remote))))
  (progn (let* ((val (forge--repository-ids class host owner name (eq demand (quote stub)))) (x777 (car val)) (x778 (cdr val))) (let ((forge-id x778) (id x777)) (setq obj (funcall class :id id :forge-id forge-id :forge forge :owner owner :name name :apihost apihost :githost githost :remote remote)))) (if (eq demand (quote create)) (progn (closql-insert (forge-db) obj))))
  (if (and (memq demand (quote (stub create))) (not obj)) (progn (let* ((val (forge--repository-ids class host owner name (eq demand (quote stub)))) (x777 (car val)) (x778 (cdr val))) (let ((forge-id x778) (id x777)) (setq obj (funcall class :id id :forge-id forge-id :forge forge :owner owner :name name :apihost apihost :githost githost :remote remote)))) (if (eq demand (quote create)) (progn (closql-insert (forge-db) obj)))))
  (let* ((row (car (forge-sql [:select * :from repository :where (and (= forge $s1) (= owner $s2) (= name $s3))] forge owner name))) (obj (and row (closql--remake-instance class (forge-db) row)))) (if obj (progn (eieio-oset obj (quote apihost) apihost) (eieio-oset obj (quote githost) githost) (eieio-oset obj (quote remote) remote))) (cond ((and (eq demand t) (or (not obj) (eieio-oref obj (quote sparse-p)))) (error "Cannot use `%s' in %S yet.\n%s" this-command (magit-toplevel) "Use `M-x forge-pull' before trying again.")) ((and (eq demand (quote full)) obj (eieio-oref obj (quote sparse-p))) (setq obj nil))) (if (and (memq demand (quote (stub create))) (not obj)) (progn (let* ((val (forge--repository-ids class host owner name (eq demand ...))) (x777 (car val)) (x778 (cdr val))) (let ((forge-id x778) (id x777)) (setq obj (funcall class :id id :forge-id forge-id :forge forge :owner owner :name name :apihost apihost :githost githost :remote remote)))) (if (eq demand (quote create)) (progn (closql-insert (forge-db) obj))))) obj)
  (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* ((row (car (forge-sql [:select * :from repository :where (and ... ... ...)] forge owner name))) (obj (and row (closql--remake-instance class (forge-db) row)))) (if obj (progn (eieio-oset obj (quote apihost) apihost) (eieio-oset obj (quote githost) githost) (eieio-oset obj (quote remote) remote))) (cond ((and (eq demand t) (or (not obj) (eieio-oref obj (quote sparse-p)))) (error "Cannot use `%s' in %S yet.\n%s" this-command (magit-toplevel) "Use `M-x forge-pull' before trying again.")) ((and (eq demand (quote full)) obj (eieio-oref obj (quote sparse-p))) (setq obj nil))) (if (and (memq demand (quote (stub create))) (not obj)) (progn (let* ((val (forge--repository-ids class host owner name ...)) (x777 (car val)) (x778 (cdr val))) (let ((forge-id x778) (id x777)) (setq obj (funcall class :id id :forge-id forge-id :forge forge :owner owner :name name :apihost apihost :githost githost :remote remote)))) (if (eq demand (quote create)) (progn (closql-insert (forge-db) obj))))) obj))
  (let* ((x769 (car spec)) (x770 (cdr spec)) (x771 (car x770)) (x772 (cdr x770)) (x773 (car x772)) (x774 (cdr x772)) (x775 (car x774)) (x776 (cdr x774))) (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* ((row (car (forge-sql [:select * :from repository :where ...] forge owner name))) (obj (and row (closql--remake-instance class (forge-db) row)))) (if obj (progn (eieio-oset obj (quote apihost) apihost) (eieio-oset obj (quote githost) githost) (eieio-oset obj (quote remote) remote))) (cond ((and (eq demand t) (or (not obj) (eieio-oref obj ...))) (error "Cannot use `%s' in %S yet.\n%s" this-command (magit-toplevel) "Use `M-x forge-pull' before trying again.")) ((and (eq demand (quote full)) obj (eieio-oref obj (quote sparse-p))) (setq obj nil))) (if (and (memq demand (quote (stub create))) (not obj)) (progn (let* ((val ...) (x777 ...) (x778 ...)) (let (... ...) (setq obj ...))) (if (eq demand (quote create)) (progn (closql-insert ... obj))))) obj)))
  (if spec (let* ((x769 (car spec)) (x770 (cdr spec)) (x771 (car x770)) (x772 (cdr x770)) (x773 (car x772)) (x774 (cdr x772)) (x775 (car x774)) (x776 (cdr x774))) (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* ((row (car (forge-sql [:select * :from repository :where ...] forge owner name))) (obj (and row (closql--remake-instance class ... row)))) (if obj (progn (eieio-oset obj (quote apihost) apihost) (eieio-oset obj (quote githost) githost) (eieio-oset obj (quote remote) remote))) (cond ((and (eq demand t) (or ... ...)) (error "Cannot use `%s' in %S yet.\n%s" this-command (magit-toplevel) "Use `M-x forge-pull' before trying again.")) ((and (eq demand ...) obj (eieio-oref obj ...)) (setq obj nil))) (if (and (memq demand (quote ...)) (not obj)) (progn (let* (... ... ...) (let ... ...)) (if (eq demand ...) (progn ...)))) obj))) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  No entry for %S in %s" host (quote forge-alist)))))
  (let* ((spec (and t (assoc host forge-alist)))) (if spec (let* ((x769 (car spec)) (x770 (cdr spec)) (x771 (car x770)) (x772 (cdr x770)) (x773 (car x772)) (x774 (cdr x772)) (x775 (car x774)) (x776 (cdr x774))) (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* ((row (car ...)) (obj (and row ...))) (if obj (progn (eieio-oset obj ... apihost) (eieio-oset obj ... githost) (eieio-oset obj ... remote))) (cond ((and ... ...) (error "Cannot use `%s' in %S yet.\n%s" this-command ... "Use `M-x forge-pull' before trying again.")) ((and ... obj ...) (setq obj nil))) (if (and (memq demand ...) (not obj)) (progn (let* ... ...) (if ... ...))) obj))) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  No entry for %S in %s" host (quote forge-alist))))))
  (progn (if --cl-rest-- (signal (quote wrong-number-of-arguments) (list nil (+ 3 (length --cl-rest--))))) (let* ((spec (and t (assoc host forge-alist)))) (if spec (let* ((x769 (car spec)) (x770 (cdr spec)) (x771 (car x770)) (x772 (cdr x770)) (x773 (car x772)) (x774 (cdr x772)) (x775 (car x774)) (x776 (cdr x774))) (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* ((row ...) (obj ...)) (if obj (progn ... ... ...)) (cond (... ...) (... ...)) (if (and ... ...) (progn ... ...)) obj))) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  No entry for %S in %s" host (quote forge-alist)))))))
  (let* ((--cl-rest-- (if --cl-rest-- (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--)))) (signal (quote wrong-number-of-arguments) (list nil (length --cl-rest--))))) (host (if (= (length --cl-rest--) 3) (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--)))) (signal (quote wrong-number-of-arguments) (list nil (length --cl-rest--))))) (owner (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--))))) (name (car --cl-rest--)) (remote (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--))))) (demand (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--)))))) (progn (if --cl-rest-- (signal (quote wrong-number-of-arguments) (list nil (+ 3 (length --cl-rest--))))) (let* ((spec (and t (assoc host forge-alist)))) (if spec (let* ((x769 (car spec)) (x770 (cdr spec)) (x771 (car x770)) (x772 (cdr x770)) (x773 (car x772)) (x774 (cdr x772)) (x775 (car x774)) (x776 (cdr x774))) (let ((class x775) (forge x773) (apihost x771) (githost x769)) (let* (... ...) (if obj ...) (cond ... ...) (if ... ...) obj))) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  No entry for %S in %s" host (quote forge-alist))))))))
  (progn (let* ((--cl-rest-- (if --cl-rest-- (car-safe (prog1 --cl-rest-- (setq --cl-rest-- ...))) (signal (quote wrong-number-of-arguments) (list nil (length --cl-rest--))))) (host (if (= (length --cl-rest--) 3) (car-safe (prog1 --cl-rest-- (setq --cl-rest-- ...))) (signal (quote wrong-number-of-arguments) (list nil (length --cl-rest--))))) (owner (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--))))) (name (car --cl-rest--)) (remote (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--))))) (demand (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--)))))) (progn (if --cl-rest-- (signal (quote wrong-number-of-arguments) (list nil (+ 3 (length --cl-rest--))))) (let* ((spec (and t (assoc host forge-alist)))) (if spec (let* ((x769 ...) (x770 ...) (x771 ...) (x772 ...) (x773 ...) (x774 ...) (x775 ...) (x776 ...)) (let (... ... ... ...) (let* ... ... ... ... obj))) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  No entry for %S in %s" host ...))))))))
  (closure (t) (&rest --cl-rest--) "Return the repository identified by HOST, OWNER and NAME.\n\n(fn (HOST OWNER NAME) &optional REMOTE DEMAND)" (progn (let* ((--cl-rest-- (if --cl-rest-- (car-safe (prog1 --cl-rest-- ...)) (signal (quote wrong-number-of-arguments) (list nil ...)))) (host (if (= (length --cl-rest--) 3) (car-safe (prog1 --cl-rest-- ...)) (signal (quote wrong-number-of-arguments) (list nil ...)))) (owner (car-safe (prog1 --cl-rest-- (setq --cl-rest-- ...)))) (name (car --cl-rest--)) (remote (car-safe (prog1 --cl-rest-- (setq --cl-rest-- ...)))) (demand (car-safe (prog1 --cl-rest-- (setq --cl-rest-- ...))))) (progn (if --cl-rest-- (signal (quote wrong-number-of-arguments) (list nil (+ 3 ...)))) (let* ((spec (and t ...))) (if spec (let* (... ... ... ... ... ... ... ...) (let ... ...)) (if (memq demand forge--signal-no-entry) (progn ...))))))))(("gitlab.tsuru.it" "tsuru" "trader") "origin" create)
  apply((closure (t) (&rest --cl-rest--) "Return the repository identified by HOST, OWNER and NAME.\n\n(fn (HOST OWNER NAME) &optional REMOTE DEMAND)" (progn (let* ((--cl-rest-- (if --cl-rest-- (car-safe ...) (signal ... ...))) (host (if (= ... 3) (car-safe ...) (signal ... ...))) (owner (car-safe (prog1 --cl-rest-- ...))) (name (car --cl-rest--)) (remote (car-safe (prog1 --cl-rest-- ...))) (demand (car-safe (prog1 --cl-rest-- ...)))) (progn (if --cl-rest-- (signal (quote wrong-number-of-arguments) (list nil ...))) (let* ((spec ...)) (if spec (let* ... ...) (if ... ...))))))) ("gitlab.tsuru.it" "tsuru" "trader") ("origin" create))
  forge-get-repository(("gitlab.tsuru.it" "tsuru" "trader") "origin" create)
  (if parts (forge-get-repository parts remote demand) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s isn't a forge url" url))))
  (let* ((parts (and t (forge--split-url url)))) (if parts (forge-get-repository parts remote demand) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s isn't a forge url" url)))))
  (progn (let* ((parts (and t (forge--split-url url)))) (if parts (forge-get-repository parts remote demand) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s isn't a forge url" url))))))
  (closure (t) (url &optional remote demand) "Return the repository at URL." (progn (let* ((parts (and t (forge--split-url url)))) (if parts (forge-get-repository parts remote demand) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s isn't a forge url" url)))))))("git@gitlab.tsuru.it:tsuru/trader.git" "origin" create)
  apply((closure (t) (url &optional remote demand) "Return the repository at URL." (progn (let* ((parts (and t (forge--split-url url)))) (if parts (forge-get-repository parts remote demand) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s isn't a forge url" url))))))) "git@gitlab.tsuru.it:tsuru/trader.git" ("origin" create))
  forge-get-repository("git@gitlab.tsuru.it:tsuru/trader.git" "origin" create)
  (and t (forge-get-repository url remote demand))
  (let* ((repo (and t (forge-get-repository url remote demand)))) (if repo (progn (eieio-oset repo (quote worktree) (magit-toplevel)) repo) nil))
  (if url (let* ((repo (and t (forge-get-repository url remote demand)))) (if repo (progn (eieio-oset repo (quote worktree) (magit-toplevel)) repo) nil)) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s\n%s  %s" (cond (remote (format "No url configured for %S." remote)) (remotes "Cannot decide on remote to use.") (t "No remote configured.")) "You might have to set `forge.remote'." "See https://magit.vc/manual/forge/Token-Creation.html."))))
  (let* ((url (and t (and remote (magit-git-string "remote" "get-url" remote))))) (if url (let* ((repo (and t (forge-get-repository url remote demand)))) (if repo (progn (eieio-oset repo (quote worktree) (magit-toplevel)) repo) nil)) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s\n%s  %s" (cond (remote (format "No url configured for %S." remote)) (remotes "Cannot decide on remote to use.") (t "No remote configured.")) "You might have to set `forge.remote'." "See https://magit.vc/manual/forge/Token-Creation.html.")))))
  (let* ((remotes (magit-list-remotes)) (remote (or remote (if (cdr remotes) (car (member (forge--get-remote) remotes)) (car remotes))))) (let* ((url (and t (and remote (magit-git-string "remote" "get-url" remote))))) (if url (let* ((repo (and t (forge-get-repository url remote demand)))) (if repo (progn (eieio-oset repo (quote worktree) (magit-toplevel)) repo) nil)) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s\n%s  %s" (cond (remote ...) (remotes "Cannot decide on remote to use.") (t "No remote configured.")) "You might have to set `forge.remote'." "See https://magit.vc/manual/forge/Token-Creation.html."))))))
  (if magit--refresh-cache (let ((G293 (list default-directory (quote forge-get-repository) demand))) (let ((it (assoc G293 (cdr magit--refresh-cache)))) (if it (progn (let* ((v magit--refresh-cache)) (setcar (car v) (+ ... 1))) (cdr it)) (let* ((v magit--refresh-cache)) (setcdr (car v) (+ (cdr ...) 1))) (let ((value (let* ... ...))) (let* ((v ...) (v magit--refresh-cache)) (setcdr v (cons v ...))) value)))) (let* ((remotes (magit-list-remotes)) (remote (or remote (if (cdr remotes) (car (member ... remotes)) (car remotes))))) (let* ((url (and t (and remote (magit-git-string "remote" "get-url" remote))))) (if url (let* ((repo (and t ...))) (if repo (progn (eieio-oset repo ... ...) repo) nil)) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s\n%s  %s" (cond ... ... ...) "You might have to set `forge.remote'." "See https://magit.vc/manual/forge/Token-Creation.html.")))))))
  (or forge-buffer-repository (and forge-buffer-topic (forge-get-repository forge-buffer-topic)) (if magit--refresh-cache (let ((G293 (list default-directory (quote forge-get-repository) demand))) (let ((it (assoc G293 (cdr magit--refresh-cache)))) (if it (progn (let* (...) (setcar ... ...)) (cdr it)) (let* ((v magit--refresh-cache)) (setcdr (car v) (+ ... 1))) (let ((value ...)) (let* (... ...) (setcdr v ...)) value)))) (let* ((remotes (magit-list-remotes)) (remote (or remote (if (cdr remotes) (car ...) (car remotes))))) (let* ((url (and t (and remote ...)))) (if url (let* ((repo ...)) (if repo (progn ... repo) nil)) (if (memq demand forge--signal-no-entry) (progn (error "Cannot determine forge repository.  %s\n%s  %s" ... "You might have to set `forge.remote'." "See https://magit.vc/manual/forge/Token-Creation.html."))))))))
  (progn (or forge-buffer-repository (and forge-buffer-topic (forge-get-repository forge-buffer-topic)) (if magit--refresh-cache (let ((G293 (list default-directory (quote forge-get-repository) demand))) (let ((it (assoc G293 ...))) (if it (progn (let* ... ...) (cdr it)) (let* (...) (setcdr ... ...)) (let (...) (let* ... ...) value)))) (let* ((remotes (magit-list-remotes)) (remote (or remote (if ... ... ...)))) (let* ((url (and t ...))) (if url (let* (...) (if repo ... nil)) (if (memq demand forge--signal-no-entry) (progn ...))))))))
  (closure (t) (demand &optional remote) "Return the current forge repository.\n\nIf the `forge-buffer-repository' is non-nil, then return that.\nOtherwise if `forge-buffer-topic' is non-nil, then return the\nrepository for that.  Finally if both variables are nil, then\nreturn the forge repository corresponding to the current Git\nrepository, if any." (progn (or forge-buffer-repository (and forge-buffer-topic (forge-get-repository forge-buffer-topic)) (if magit--refresh-cache (let ((G293 (list default-directory ... demand))) (let ((it ...)) (if it (progn ... ...) (let* ... ...) (let ... ... value)))) (let* ((remotes (magit-list-remotes)) (remote (or remote ...))) (let* ((url ...)) (if url (let* ... ...) (if ... ...))))))))(create)
  apply((closure (t) (demand &optional remote) "Return the current forge repository.\n\nIf the `forge-buffer-repository' is non-nil, then return that.\nOtherwise if `forge-buffer-topic' is non-nil, then return the\nrepository for that.  Finally if both variables are nil, then\nreturn the forge repository corresponding to the current Git\nrepository, if any." (progn (or forge-buffer-repository (and forge-buffer-topic (forge-get-repository forge-buffer-topic)) (if magit--refresh-cache (let ((G293 ...)) (let (...) (if it ... ... ...))) (let* ((remotes ...) (remote ...)) (let* (...) (if url ... ...))))))) create nil)
  forge-get-repository(create)
  (setq repo (forge-get-repository (quote create)))
  (if repo nil (setq repo (forge-get-repository (quote create))) (setq create t))
  (if repo nil (setq repo (forge-get-repository (quote full))) (if repo nil (setq repo (forge-get-repository (quote create))) (setq create t)))
  (let (create) (if repo nil (setq repo (forge-get-repository (quote full))) (if repo nil (setq repo (forge-get-repository (quote create))) (setq create t))) (if (eieio-oref repo (quote selective-p)) (progn (if (yes-or-no-p (format "Always pull all of %s/%s's topics going forward?" (eieio-oref repo (quote owner)) (eieio-oref repo (quote name)))) (eieio-oset repo (quote selective-p) nil) (user-error "Abort")))) (setq forge--mode-line-buffer (current-buffer)) (let* ((remote (and t (eieio-oref repo (quote remote)))) (refspec (and remote (eieio-oref repo (quote pullreq-refspec))))) (if refspec (if (and create (not (member refspec (magit-get-all "remote" remote "fetch"))) (or (eq forge-add-pullreq-refspec t) (and (eq forge-add-pullreq-refspec ...) (y-or-n-p ...)))) (progn (magit-call-git "config" "--add" (format "remote.%s.fetch" remote) refspec))) nil)) (forge--msg repo t nil "Pulling REPO") (forge--pull repo until))
  forge-pull(nil nil)
  funcall-interactively(forge-pull nil nil)
  #<subr call-interactively>(forge-pull record nil)
  apply(#<subr call-interactively> forge-pull (record nil))
  (let ((ido-cr+-current-command command)) (apply orig-fun command args))
  call-interactively@ido-cr+-record-current-command(#<subr call-interactively> forge-pull record nil)
  apply(call-interactively@ido-cr+-record-current-command #<subr call-interactively> (forge-pull record nil))
  call-interactively(forge-pull record nil)
  command-execute(forge-pull record)
  execute-extended-command(nil "forge-pull")
  (with-no-warnings (execute-extended-command current-prefix-arg chosen-item-name))
  (unwind-protect (with-no-warnings (execute-extended-command current-prefix-arg chosen-item-name)) (smex-rank chosen-item))
  (if smex-custom-action (let ((action smex-custom-action)) (setq smex-custom-action nil) (funcall action chosen-item)) (unwind-protect (with-no-warnings (execute-extended-command current-prefix-arg chosen-item-name)) (smex-rank chosen-item)))
  (let* ((chosen-item-name (smex-completing-read commands initial-input)) (chosen-item (intern chosen-item-name))) (if smex-custom-action (let ((action smex-custom-action)) (setq smex-custom-action nil) (funcall action chosen-item)) (unwind-protect (with-no-warnings (execute-extended-command current-prefix-arg chosen-item-name)) (smex-rank chosen-item))))
  smex-read-and-run(("eval-buffer" "forge-pull" "byte-recompile-directory" "customize-variable" "rgrep" "package-list-packages" "magit-blame" "revert-buffer" "whitespace-mode" "haskell-sort-imports" "fundamental-mode" "asm-mode" "haskell-mode" "sort-lines" "elp-instrument-list" "haskell-align-imports" "list-packages" "markdown-mode" "coffee-mode" "elp-results" "profiler-start" "nix-mode" "debug-on-entry" "c-mode" "package-refresh-contents" "erc" "customize" "bazel-mode" "wgrep-exit" "haskell-menu" "yafolding-mode" "javascript-mode" "package-install" "auto-complete-mode" "package-autoremove" "forge-browse-remote" "ivy-occur-grep-mode" "create-scratch-buffer" "toggle-debug-on-error" "wgrep-save-all-buffers" "delete-trailing-whitespace" "wgrep-change-to-wgrep-mode" "cd" "5x5" "arp" "dbx" "dig" "ert" "eww" "ftp" ...))
  (if (smex-already-running) (smex-update-and-rerun) (and smex-auto-update (smex-detect-new-commands) (smex-update)) (smex-read-and-run smex-ido-cache))
  smex()
  funcall-interactively(smex)
  #<subr call-interactively>(smex nil nil)
  apply(#<subr call-interactively> smex (nil nil))
  (let ((ido-cr+-current-command command)) (apply orig-fun command args))
  call-interactively@ido-cr+-record-current-command(#<subr call-interactively> smex nil nil)
  apply(call-interactively@ido-cr+-record-current-command #<subr call-interactively> (smex nil nil))
  call-interactively(smex nil nil)
  command-execute(smex)
                               :forge (cl-ecase class
                                        (forge-github-repository    'ghub)
                                        (forge-gitlab-repository    'glab)
                                        (forge-gitea-repository     'gtea)
                                        (forge-gogs-repository      'gogs)
                                        (forge-bitbucket-repository 'buck))))))

Perhaps because the forge-gitlab-http-repository is not mentioned here? If I add it, I get open-network-stream: Failed connect: Connection refused however... Plot thickens.

Fuuzetsu commented 4 years ago

I managed to get it to work I think! In forge--repository-ids I changed the el-case to

                               :forge (cond ((child-of-class-p class forge-github-repository) 'ghub)
                                            ((child-of-class-p class forge-gitlab-repository) 'glab)
                                            ((child-of-class p class forge-gitea-repository)     'gtea)
                                            ((child-of-class p class forge-gogs-repository)      'gogs)
                                            ((child-of-class p class forge-bitbucket-repository) 'buck)
                                            (t (error "No class not found")))))))

I also had to set the ghub-insecure-hosts variable to the same host as in .authinfo (that is, including the /api/v4 bit in case of gitlab).

tarsius commented 4 years ago

I think it should work now. Please give it a try. You will have to update ghub and forge.

strutt commented 4 years ago

@tarsius I just followed the steps outlined in this thread for my organisation's private http gitlab server,

(defclass forge-gitlab-http-repository ...) (add-to-list 'ghub-insecure-hosts "git.private.network.repo/api/v4") and it does work. Cheers.

jmones commented 3 years ago

Added advice to https://github.com/magit/forge/wiki/Tips-and-Tricks#accessing-private-gitlab-instances-via-http as suggested by @tarsius in the thread, to increase visibility of the workaround (which worked for me too, thanks).

hummuscience commented 2 years ago

@jmones thanks for posting the advice onto the wiki. Could you add some words on how to actually implement it? Is this supposed to be added to the init file or evaluated and ran in a scratch buffer (??)

jmones commented 2 years ago

@Cumol For vanilla emacs, that would be ~/.emacs.d/init.el May differ for configuration frameworks. For example, I use Doom Emacs and that would go in ~/.doom.d/.config.el

hummuscience commented 2 years ago

When I paste the code below into init I get the following error:

error: Given parent class forge-gitlab-repository is not a class

  (defclass forge-gitlab-http-repository (forge-gitlab-repository)
    ((issues-url-format         :initform "http://%h/%o/%n/issues")
     (issue-url-format          :initform "http://%h/%o/%n/issues/%i")
     (issue-post-url-format     :initform "http://%h/%o/%n/issues/%i#note_%I")
     (pullreqs-url-format       :initform "http://%h/%o/%n/merge_requests")
     (pullreq-url-format        :initform "http://%h/%o/%n/merge_requests/%i")
     (pullreq-post-url-format   :initform "http://%h/%o/%n/merge_requests/%i#note_%I")
     (commit-url-format         :initform "http://%h/%o/%n/commit/%r")
     (branch-url-format         :initform "http://%h/%o/%n/commits/%r")
     (remote-url-format         :initform "http://%h/%o/%n")
     (create-issue-url-format   :initform "http://%h/%o/%n/issues/new")
     (create-pullreq-url-format :initform "http://%h/%o/%n/merge_requests/new")
     (pullreq-refspec :initform "+refs/merge-requests/*/head:refs/pullreqs/*")))

  (add-to-list 'ghub-insecure-hosts "git.private.network.repo/api/v4")
ctaque commented 1 year ago

Does anybody had forge-browse-issue and forge-browse-pull-request browse with insecure url ?

At home and at work it navigates to https, although I configured forge-gitlab-http-repository; the rest works

ctaque commented 1 year ago

Anyone *