unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Bug in my WIP-npm-importer with blacklist
@ 2018-11-25 13:26 swedebugia
  2018-11-25 15:01 ` Gábor Boskovits
  2018-11-26 19:39 ` Catonano
  0 siblings, 2 replies; 4+ messages in thread
From: swedebugia @ 2018-11-25 13:26 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 527 bytes --]

Hi

I am still a novice in guile so I humbly ask for help with this error 
trying to get the blacklisting to work:

sdb@komputilo ~$ ~/guix-tree/pre-inst-env guix import npm leaflet
ice-9/boot-9.scm:222:17: In procedure map1:
Syntax error:
/home/sdb/guix-tree/guix/import/npm.scm:304:2: source expression failed 
to match any pattern in form (if (member (cut guix-name "node-" <>) 
blacklist))

The relevant code is in npm.scm as detailed in the error above.

The files are attached.

Thanks in advance!

-- 
Cheers
Swedebugia

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: npm.scm --]
[-- Type: text/x-scheme; name="npm.scm", Size: 18227 bytes --]

;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;; Copyright © 2016 Jelle Licht <jlicht@fsfe.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix import npm)
  #:use-module (json)
  #:use-module (gcrypt hash)
  #:use-module (guix import npm-blacklist)
  #:use-module (guix import github)
  #:use-module ((guix licenses) #:select (expat))
  #:use-module (guix utils)
  #:use-module (guix upstream)
  #:use-module (web uri)
  #:use-module (guix build git)
  #:use-module (guix base32)
  #:use-module ((guix download) #:prefix download:)
  #:use-module (guix serialization)
  #:use-module (guix import json)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-11)
  #:use-module (srfi srfi-9 gnu)
  #:use-module (srfi srfi-9)
  #:use-module (srfi srfi-26)
  #:use-module (ice-9 regex)
  #:use-module (ice-9 rdelim)
  #:use-module (ice-9 control)
  #:use-module (ice-9 vlist)
  #:use-module (rnrs bytevectors)
  #:use-module (ice-9 binary-ports)
  #:use-module (rnrs io ports)
  #:use-module (ice-9 match)
  #:use-module (ice-9 regex)
  #:use-module (ice-9 receive)
  #:use-module (guix import utils)
  #:use-module (guix packages)
  #:use-module (gnu packages)
  #:use-module (guix build-system node)
  #:export (npm->guix-package
            npm-recursive-import))

(define scheme-pat
  "[a-zA-Z][-a-zA-Z0-9+.-]*")
(define host-pat
  "[a-zA-Z0-9.-]+")
(define authority-pat
  (make-regexp "[^/?#]*"))
(define path-pat
  (make-regexp "[^?#]*"))
(define user-project-pat
  "([a-zA-Z][-a-zA-Z0-9+.]*)/([a-zA-Z][-a-zA-Z0-9+.]*)")

(define gh-shorthand-regexp
  (make-regexp (format #f "^~a$" user-project-pat)))
(define alternative-gh-shorthand-regexp
  (make-regexp (format #f "^github:~a$" user-project-pat)))
(define bitbucket-shorthand-regexp
  (make-regexp (format #f "^bitbucket:~a$" user-project-pat)))
(define gitlab-shorthand-regexp
  (make-regexp (format #f "^gitlab:~a$" user-project-pat)))
(define pseudo-url-regexp
  (make-regexp (format #f "^(~a)@(~a):(~a)\\.git$"
                       scheme-pat
                       host-pat
                       user-project-pat)))

(define (pseudo-to-real-url pseudo-url-match)
  (let* ((m            pseudo-url-match)
         (protocol     (match:substring m 1))
         (hostname     (match:substring m 2))
         (user-project (match:substring m 3)))
    (format #f "~a://~a/~a.git"
            protocol
            hostname
            user-project)))

(define (make-gh-url user project)
  (format #f "https://github.com/~a/~a.git" user project))
(define (make-bb-url user project)
  (format #f "https://bitbucket.org/~a/~a.git" user project))
(define (make-gl-url user project)
  (format #f "https://gitlab.com/~a/~a.git" user project))

(define (normalise-url url)
  (cond ((regexp-exec pseudo-url-regexp url)
         ;; git@host:user/project.git
         =>
         (lambda (match)
           (pseudo-to-real-url match)))
        ((or (regexp-exec gh-shorthand-regexp url)
         (regexp-exec alternative-gh-shorthand-regexp url))
         ;; user/project or github:user/project
         => (lambda (match)
              (let ((user (match:substring match 1))
                    (project (match:substring match 2)))
                (make-gh-url user project))))
        ((regexp-exec bitbucket-shorthand-regexp url)
         ;; bitbucket:user/project
         =>
        (lambda (match)
          (let ((user (match:substring match 1))
                (project (match:substring match 2)))
            (make-bb-url user project))))
        ((regexp-exec gitlab-shorthand-regexp url)
         ;; gitlab:user/project
         =>
         (lambda (match)
           (let ((user (match:substring match 1))
                 (project (match:substring match 2)))
             (make-gl-url user project))))
        ((not (string-suffix? ".git" url))  ;XXX: forgetful npm people
         (normalise-url (string-append url ".git")))
        ((string->uri url)
         =>
         (lambda (uri)
           ;; XXX: Use actual schemes supported by git
           (case (uri-scheme uri)
             ((git+ssh)
              (uri->string (set-fields uri
                                        ((uri-scheme) 'git))))
             ((git+http)
              (uri->string (set-fields uri
                                       ((uri-scheme) 'http))))
             ((git+https)
              (uri->string (set-fields uri
                                       ((uri-scheme) 'https))))
             (else
              url))))
        (else
         url)))

(define (heuristic-tags version)
  (list version
        (string-append "v" version)))

(define (generic-fuzzy-tag-match repo-url version)
  "Return a likely match for the git tag VERSION for the repository at
REPO-URL"
  (let* ((fuzzy-tags (heuristic-tags version))
         (repo-tags  (git-fetch-tags repo-url))
         (proper-release (filter
                          (lambda (tags)
                            (member tags fuzzy-tags))
                          repo-tags)))
    (match proper-release
      (()
       #f)
      ((release . rest)
       ;;XXX: Just pick the first release
       release))))

(define (gh-fuzzy-tag-match github-repo version)
  "Return a likely match for the git tag VERSION for the repository at
GITHUB-REPO"
  (let* ((fuzzy-tags (heuristic-tags version))
         (token      (%github-token))
         (api-url    (string-append
                      "https://api.github.com/repos/"
                      (github-user-slash-repository github-repo)
                      "/tags"))
         (json (json-fetch
                (if token
                    (string-append api-url "?access_token=" token)
                    api-url))))
    (if (eq? json #f)
        (if token
            (error "Error downloading release information through the GitHub
API when using a GitHub token to download:" github-repo "@" version " via "
api-url)
            (error "Error downloading release information through the GitHub
API. This may be fixed by using an access token and setting the environment
variable GUIX_GITHUB_TOKEN, for instance one procured from
https://github.com/settings/tokens. E: " github-repo "@" version " via "
api-url))
        (let ((proper-release
               (filter
                (lambda (x)
                  (let ((name (hash-ref x "name")))
                    (member name fuzzy-tags)))
                json)))
          (match proper-release
            (()                       ;empty release list
             #f)
            ((release . rest)         ;one or more releases
             ;;XXX: Just pick the first release
             (let ((tag (hash-ref release "name")))
               tag)))))))


(define (github-user-slash-repository github-url)
  "Return a string e.g. arq5x/bedtools2 of the owner and the name of the
repository separated by a forward slash, from a string URL of the form
'https://github.com/arq5x/bedtools2.git'"
  (match (string-split (uri-path (string->uri github-url)) #\/)
    ((_ owner project . rest)
     (string-append owner "/" (string-drop-right project 4)))))

(define (github-repository github-url)
  "Return a string e.g. bedtools2 of the name of the repository, from a string
URL of the form 'https://github.com/arq5x/bedtools2.git'"
  (match (string-split (uri-path (string->uri github-url)) #\/)
    ((_ owner project . rest)
     (string-drop-right project 4))))

;; Disabled because these archives are not reproducible and neither archived
;; by SWH. Git commits are preferable.

;; (define (github-release-url github-url version)
;;   "Return the url for the tagged release VERSION on the github repo found at
;; GITHUB-URL."
;;   (when (not version)
;;     (error "GitHub tarball not found" github-url version))
;;   (if (equal? (uri-host (string->uri github-url)) "github.com")
;;       (let ((ext     ".tar.gz")
;;             (version version)
;;             (prefix  (string-append "https://github.com/"
;;                                     (github-user-slash-repository github-url)))
;;             (repo    (github-repository github-url)))
;;         (string-append prefix "/archive/" version "/"
;;                        repo "-" version ext))))

;; NPM specific code
(define *REGISTRY*  "https://registry.npmjs.org/")

;; First try with released tarball, (github only?)
;; then heuristics for git repo

(define (npm-fetch name)
  "Return metadata from the npm registry for package NAME."
  (json-fetch-alist (string-append *REGISTRY* name)))

(define (latest-source-release npm-meta)
  "Return the latest source release for NPM-META."
  (assoc-ref* npm-meta "dist-tags" "latest"))

(define (npm-package? package)
  "Return true if PACKAGE is an npm package."
  (string-prefix? "node-" (package-name package)))

(define (source-uri npm-meta version)
  "Return the repository url for version VERSION of NPM-META"
  (let* ((v    (assoc-ref* npm-meta "versions" version)))
    (normalise-url (assoc-ref* v "repository" "url"))))

(define (guix-hash-url path)
  "Return the hash of PATH in nix-base32 format. PATH can be either a file or
directory."
  (let-values (((port get-hash) (open-sha256-port)))
    (write-file path port)
    (flush-output-port port)
    (bytevector->nix-base32-string (get-hash))))

(define (node-package-name name)
  "Given the NAME of a package on npmjs, return a Guix-compliant name for the
package."
  (if (string-prefix? "node-" name)
      (snake-case name)
      (string-append "node-" (snake-case name))))

(define (node-git-fetch url commit directory)
  "Fetch the git repo located at URL, clone into DIRECTORY and check out
revision COMMIT. URL can be any url supported by the 'git clone' command.
COMMIT can be identifier of a commit that works with the 'git checkout'
command."
  ;;XXX: Assumes 'commit' is actually a tag
  (let ((url (normalise-url url))
        (v (string-append "v" commit)))
    (git-fetch url v directory)))

(define (package-origin repo-url version)
  "Return a complete package origin for version VERSION of the software
located at REPO-URL. Tries to locate a released tarball before falling back to
a git checkout."
  (let ((uri (string->uri repo-url)))
    (call-with-temporary-directory
     (lambda (temp-dir)
       (let ((fuzzy-version (generic-fuzzy-tag-match repo-url version)))
         (and (node-git-fetch repo-url fuzzy-version temp-dir)
              `(origin
                 (method git-fetch)
                 (uri (git-reference
                       (url ,repo-url)
                       (commit ,fuzzy-version)))
                 (sha256
                  (base32
                   ,(guix-hash-url temp-dir))))))))))

(define (blacklisted? guix-name)
  "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
  (if (member (cut guix-name "node-" <>) blacklist)))

(define (make-npm-sexp name version home-page description
                       dependencies dev-dependencies license source-url)
  "Return the `package' s-expression for a Node package with the given NAME,
VERSION, HOME-PAGE, DESCRIPTION, DEPENDENCIES, DEV-DEPENDENCIES, LICENSES and
SOURCE-URL."
  (let ((origin (package-origin source-url version)))
    `(package
       (name ,(node-package-name name))
       (version ,version)
       (source ,origin)
       (build-system node-build-system)
       ,@(if (not dependencies)
             '()
             `((inputs
                (,'quasiquote
                 ,(map (lambda (name)
                         `(,name
                           (,'unquote
                            ,(string->symbol name))))
                       dependencies)))))
       ,@(if (not dev-dependencies)
             '()
             `((native-inputs
                (,'quasiquote
                 ,(map (lambda (name)
                         (if (blacklisted? name)
                              ;; True
                              '()
                              ;; False
                              `(,name
                                (,'unquote
                                 ,(string->symbol name)))))
                       dev-dependencies)))))
       (synopsis ,description) ; no synopsis field in package.json files
       (description ,description)
       (home-page ,home-page)
       (license ,license)
       ;; Properties-field:
       ;; Populate if upstream-name differs or if any dev-dependencies were
       ;; blacklisted.
       (let ((upstream-name-and-name-not-equal?
              (not (equal? (string-append "node-" name)
                           (node-package-name name)))))
         (if (or
              (if upstream-name-and-name-not-equal?)
              (if (blacklisted? name)))
             ;; Properties header
             `((properties
             ,@(if (upstream-name-and-name-not-equal?)
                   `(,'quasiquote ((,'upstream-name . ,name))))
                   ;; False, do nothing here.
                   '())
             ,@(if (blacklisted? name)
                   (map (lambda (name)
                          (if (blacklisted? name)
                           `(,'quasiquote ((native-inputs . ,name))))))
                   ;; False, do nothing here.
                   '())
             ;; False, skip properties-field entirely
             '())))))

(define (extract-guix-dependencies dependencies)
  "Returns a list of dependencies according to the guix naming scheme, from
the npm list of dependencies DEPENDENCIES."
  (if (not dependencies)
      '()
      (map (compose node-package-name car) dependencies)))

(define (extract-npm-dependencies dependencies)
  "Returns a list of dependencies according to the npm naming scheme, from the
npm list of dependencies DEPENDENCIES."
  (if (not dependencies)
      '()
      (map car dependencies)))

(define (extract-license package-json)
  (let ((license-entry (assoc-ref package-json "license"))
        (license-legacy (assoc-ref package-json "licenses")))
    (cond
     ((string? license-entry)
      (spdx-string->license license-entry))
     ((list? license-entry)
      (spdx-string->license (assoc-ref license-entry "type")))
     ((string? license-legacy)
      (spdx-string->license license-legacy))
     ((and license-legacy (positive? (length license-legacy)))
      `(list ,@(map
                (lambda (l) (spdx-string->license (assoc-ref l "type")))
                license-legacy)))
     (else
      #f))))

(define* (npm->guix-package package-name #:optional  (repo 'npm))
  "Fetch the metadata for PACKAGE-NAME from registry.npmjs.com and return the
 `package' s-expression corresponding to that package, or  on failure."
  (let ((package (npm-fetch package-name)))
    (if package
        (let* ((name (assoc-ref package "name"))
               (version (latest-source-release package))
               (curr (assoc-ref* package "versions" version))
               (raw-dependencies (assoc-ref curr "dependencies"))
               (raw-dev-dependencies (assoc-ref curr "devDependencies"))
               (dependencies (extract-guix-dependencies raw-dependencies))
               (dev-dependencies (extract-guix-dependencies
                                  raw-dev-dependencies))
               (npm-dependencies
                (append
                 (extract-npm-dependencies raw-dependencies)
                 (extract-npm-dependencies raw-dev-dependencies)))
               (description (assoc-ref package "description"))
               (home-page (assoc-ref package "homepage"))
               (license (extract-license curr))
               (source-url (source-uri package version)))
          (values
           (make-npm-sexp name version home-page description
                          dependencies dev-dependencies license source-url)
           npm-dependencies))
        (error "Could not download metadata:" package-name))))


(define npm-guix-name (cut guix-name "node-" <>))

(define* (npm-recursive-import package-name #:optional (repo 'npm))
  (recursive-import package-name repo
                    #:repo->guix-package npm->guix-package
                    #:guix-name npm-guix-name))

;; (define (package->upstream-name package)
;;   "Return the upstream name of the PACKAGE."
;;   (let* ((properties (package-properties package))
;;          (upstream-name (and=> properties
;;                                (cut assoc-ref <> 'upstream-name))))
;;     (if upstream-name
;;         upstream-name
;;         #f))) ;; TODO: Use proper heuristics with package name and what-not


(define (latest-release package)
  "Return an <upstream-source> for the latest release of PACKAGE."

  (define upstream-name
    (package-name package))

  (define meta
    (npm-fetch upstream-name))

  (and meta
       (let ((version (latest-source-release meta)))
         (upstream-source
          (package (package-name package))
          (version version)
          (urls (source-uri meta version))))))

(define %npm-updater
  (upstream-updater
   (name 'npm)
   (description "Updater for Node Package Manager packages")
   (pred npm-package?)
   (latest latest-release)))

[-- Attachment #3: npm-blacklist.scm --]
[-- Type: text/x-scheme, Size: 3947 bytes --]

;; Copyright 2018 swedebugia
(define-module (guix import npm-blacklist)
  #:export (blacklist))

;; Many of these are already in debian.

(define blacklist-benchmark
  '(
    "matcha"
    ))
  
(define blacklist-ci
  '(
    ;; From underscore:
    "coveralls"				;is in debian
    ))

(define blacklist-complex
  ;; Complex packages we should not begin with
  '(
    ;; From debian wiki /Javascript:
    ;; Packages used to transform code written for nodejs to run in
    ;; the browser:
    "webpack"
    "rollup"
    "browserify"			;This can be replaced by one
					;of the above.
    ;; Other complex packages not yet in debian:
    "electron"
    "statsd"
    "vega"
    "grunt-release"
    "lineman"
    "lineman-angular"
    "lerna"
    "openlayers"
    "openpgp"
    "yarnpkg"
    "wekan"
    "etherpad-lite"
    "meteor"
    ))

(define blacklist-deprecated
  '(
   ;; From debian wiki:
    "keybase"
    ))

(define blacklist-doc
  '(
    ;; From underscore:
    "docco"
    ;; From mocha:
    "jsdoc"
    "markdown-toc"))

(define blacklist-lint
  '(
    ;; From underscore:
    "eslint"
    ;; From mocha:
    "eslint-config-prettier"
    "eslint-config-semistandard"
    "eslint-config-standard"
    "eslint-plugin-import"
    "eslint-plugin-node"
    "eslint-plugin-prettier"
    "eslint-plugin-promise"
    "eslint-plugin-standard"
    "lint-staged"
    "markdownlint-cli"
    "prettier-eslint-cli"
    ;;From yargs
    "standard"				;linter & automatic code fixer
    "standard-version"	 ;Automate versioning and CHANGELOG generation
    ;;From tap
    "jscs"		 ;JavaScript Code Style checker
    ;; From nsp
    "eslint-config-nodesecurity"
    ;; From
    "@ljharb/eslint-config"
    ;; From eslint-config
    "editorconfig-tools"		;A tool to verify
    ;; From requirejs
    "jshint"
    ;; from path-is-absolute
    "xo"
    ;; from glob
    "tick"
    ;; from parser5
    "husky"
    ;; video.js
    "tsml"
    ;; callsites
    "tsd-check"
   ))

(define blacklist-grunt
  '(
    ;; From tap:
    "grunt"				;The JavaScript Task Runner - is in
					;debian
    "grunt-contrib-concat"
    "grunt-contrib-uglify"
    ;; From jquery
    "grunt-compare-size"
    
    ))

(define blacklist-management
  '(
    ;; From parser5:
    "lerna"))

(define blacklist-test
  '(
   ;; From underscore:
   "karma"
   "karma-qunit"
   "karma-sauce-launcher"
   "nyc"
   "qunit-cli"
   "qunit"
   ;; From yargs
   "mocha"				;is in debian
   "yargs-test-extends"
   "chai"				;Chai is an assertion library.
   ;; From commander
   "sinon"				;Test spies, stubs and mocks
   ;; From nsp
   "code"				;assertion, fork of chai
   ;; From minimist
   "covert"				;code coverage command
   "tape"				;tap-producing test harness
   "tap"				;Test-Anything-Protocol
					;library
   "lab"				;Node.js test framework
   ;; From nsp
   "mock-fs"
   ;; From many :)
   "nyc"				;istanbul coverage, testing
   ;; from is-wsl
   "proxyquire"
   ;; From github search "test" javascript, sort by stars
   "forking-tap"
   "bogota"
   "faucet"
   "gremlins"
   "jest"
   "redux-mock-store"
   "webdriverio"
   "ava"
   "enzyme"
   "testem"
   "protractor"
   "testcafe"
   "test262"
   "storybook"
   "jasmine"
   "volkswagen"
   "nightwatch"
   "supertest"
   "istanbul"
   "sizzy"
   "zombie"
   "PhantomCSS"
   ))

(define blacklist
  ;; Combine blacklists into one.
  (append
   blacklist-benchmark
   blacklist-ci
   blacklist-complex
   blacklist-deprecated
   blacklist-doc
   blacklist-lint
   blacklist-management   
   blacklist-grunt
   blacklist-test))

(define keyword-blacklist
  ;; Blacklist based on description or keywords
  '("assert"
    "assertion"
    "check"
    "test"
    "testing"
    "mock"
    "coverage"
    "lint"
    "linter"
    "security")) 

;; Debugging
;; (format (current-error-port) "Blacklisted: ~a \n" blacklist)
;; (force-output)
;; (format (current-error-port) "Total: ~a packages blacklisted \n" (length blacklist))

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug in my WIP-npm-importer with blacklist
  2018-11-25 13:26 Bug in my WIP-npm-importer with blacklist swedebugia
@ 2018-11-25 15:01 ` Gábor Boskovits
  2018-11-26 19:39 ` Catonano
  1 sibling, 0 replies; 4+ messages in thread
From: Gábor Boskovits @ 2018-11-25 15:01 UTC (permalink / raw)
  To: swedebugia; +Cc: Guix-devel

Hello,

I had a look at that. You should not need the if there, just 'return'
the test of the if.
If has a form (if test conseqent alternate), alternate is optional and
returns the value of the
evaluated branch (consequent or alternate). This gives you a syntax
error, as the mandatory
consequent expression is missing.

Best regards,
g_bor

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug in my WIP-npm-importer with blacklist
  2018-11-25 13:26 Bug in my WIP-npm-importer with blacklist swedebugia
  2018-11-25 15:01 ` Gábor Boskovits
@ 2018-11-26 19:39 ` Catonano
  2018-11-26 20:20   ` Catonano
  1 sibling, 1 reply; 4+ messages in thread
From: Catonano @ 2018-11-26 19:39 UTC (permalink / raw)
  To: swedebugia; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 2696 bytes --]

Il giorno dom 25 nov 2018 alle ore 14:21 swedebugia <swedebugia@riseup.net>
ha scritto:

> Hi
>
> I am still a novice in guile so I humbly ask for help with this error
> trying to get the blacklisting to work:
>
> sdb@komputilo ~$ ~/guix-tree/pre-inst-env guix import npm leaflet
> ice-9/boot-9.scm:222:17: In procedure map1:
> Syntax error:
> /home/sdb/guix-tree/guix/import/npm.scm:304:2: source expression failed
> to match any pattern in form (if (member (cut guix-name "node-" <>)
> blacklist))
>
> The relevant code is in npm.scm as detailed in the error above.
>
> The files are attached.
>
> Thanks in advance!
>
>
There are 2 observations I can give

The first one is that member" returns a boolean value (#t or #f) and your
function can return just that, you don't need the if

But even if you needed the if, you have to pass it at least 2 forms: a test
and another expression whose value will be returned if the tests succeeds
(that is, it evaluates to #t)

In your code you are passing the if form only one expression.

The only expression you are passing to the if is

(member (cut guix-name "node-" <>) blacklist)

if this subexpression evaluates to #t, what is the if supposed to do ?

You could have written


(define (blacklisted? guix-name)
  "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
  (if (member (cut guix-name "node-" <>) blacklist) #t #f))

in this exaple, if the subexression evaluates to #t, the if form can return
#t, which is

but as you can see (this is my second observation), this formulation is a
bit redundant

It can be rewritten without the if at all, lie this

(define (blacklisted? guix-name)
  "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
  (member (cut guix-name "node-" <>) blacklist)))


In this formulation, if the subexpression

(member (cut guix-name "node-" <>) blacklist))

returns #t, your function will return #t, because your function returns the
value off its last subform

if the subexpression returns #f, of course your function will return  #f

That's supposedly what you wanted to achieve, isn't it ?

You can achieve it without the if 😊

Usually when Guile laments that a source expression doesn't match any
pattern, that's because you messed up the parenses or because you passed
the wrong number of subexpressions to a form

Please note that in this case Guile is not denouncing that the wrong number
of arguments were passed to a function

Because the "if" is not a function, it's a special form (I think), and the
expander tries to recognize a known "pattern" in it

It fails and it gives up

Hope this helps

[-- Attachment #2: Type: text/html, Size: 3981 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug in my WIP-npm-importer with blacklist
  2018-11-26 19:39 ` Catonano
@ 2018-11-26 20:20   ` Catonano
  0 siblings, 0 replies; 4+ messages in thread
From: Catonano @ 2018-11-26 20:20 UTC (permalink / raw)
  To: swedebugia; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 5271 bytes --]

because I made so many typing mistakes, I corrected my text and I'm posting
it again, corrected







There are 2 observations I can give

The first one is that "member" returns a boolean value (#t or #f) and your
function can return just that, you don't need the if

But even if you needed the if, you have to pass it at least 2 forms: a test
and another expression whose value will be returned if the tests succeeds
(that is, it evaluates to #t)

In your code you are passing the if form only one expression.

The only expression you are passing to the if is

(member (cut guix-name "node-" <>) blacklist)

if this subexpression evaluates to #t, what is the if supposed to do ?

You could have written


(define (blacklisted? guix-name)
  "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
  (if (member (cut guix-name "node-" <>) blacklist) #t #f))

in this exaple, if the subepxression evaluates to #t, the if form can
return #t, which is the second (sub)expression passed to it

Of course, if the (first) subexpression evaluates to #f, then your if form
will return #f, wich is the third (sub)expression passed to it

but as you can see (this is my second observation), this formulation is a
bit redundant

It can be rewritten without the if at all, like this

(define (blacklisted? guix-name)
  "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
  (member (cut guix-name "node-" <>) blacklist)))


In this formulation, if the subexpression

(member (cut guix-name "node-" <>) blacklist))

returns #t, your function will return #t, because your function returns the
value off its last subform

if the subexpression returns #f, of course your function will return  #f

That's supposedly what you wanted to achieve, isn't it ?

You can achieve it without the if 😊

Usually when Guile laments that a source expression doesn't match any
pattern, that's because you messed up the parenses or because you passed
the wrong number of subexpressions to a form

Please note that in this case Guile is not denouncing that the wrong number
of arguments were passed to a function

Because the "if" is not a function, it's a special form (I think), and the
expander tries to recognize a known "pattern" in it

It fails and it gives up

Hope this helps



Il giorno lun 26 nov 2018 alle ore 20:39 Catonano <catonano@gmail.com> ha
scritto:

>
>
> Il giorno dom 25 nov 2018 alle ore 14:21 swedebugia <swedebugia@riseup.net>
> ha scritto:
>
>> Hi
>>
>> I am still a novice in guile so I humbly ask for help with this error
>> trying to get the blacklisting to work:
>>
>> sdb@komputilo ~$ ~/guix-tree/pre-inst-env guix import npm leaflet
>> ice-9/boot-9.scm:222:17: In procedure map1:
>> Syntax error:
>> /home/sdb/guix-tree/guix/import/npm.scm:304:2: source expression failed
>> to match any pattern in form (if (member (cut guix-name "node-" <>)
>> blacklist))
>>
>> The relevant code is in npm.scm as detailed in the error above.
>>
>> The files are attached.
>>
>> Thanks in advance!
>>
>>
> There are 2 observations I can give
>
> The first one is that member" returns a boolean value (#t or #f) and your
> function can return just that, you don't need the if
>
> But even if you needed the if, you have to pass it at least 2 forms: a
> test and another expression whose value will be returned if the tests
> succeeds (that is, it evaluates to #t)
>
> In your code you are passing the if form only one expression.
>
> The only expression you are passing to the if is
>
> (member (cut guix-name "node-" <>) blacklist)
>
> if this subexpression evaluates to #t, what is the if supposed to do ?
>
> You could have written
>
>
> (define (blacklisted? guix-name)
>   "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
>   (if (member (cut guix-name "node-" <>) blacklist) #t #f))
>
> in this exaple, if the subexression evaluates to #t, the if form can
> return #t, which is
>
> but as you can see (this is my second observation), this formulation is a
> bit redundant
>
> It can be rewritten without the if at all, lie this
>
> (define (blacklisted? guix-name)
>   "Check if guix-name is blacklisted. RETURN #t if yes, else #f."
>   (member (cut guix-name "node-" <>) blacklist)))
>
>
> In this formulation, if the subexpression
>
> (member (cut guix-name "node-" <>) blacklist))
>
> returns #t, your function will return #t, because your function returns
> the value off its last subform
>
> if the subexpression returns #f, of course your function will return  #f
>
> That's supposedly what you wanted to achieve, isn't it ?
>
> You can achieve it without the if 😊
>
> Usually when Guile laments that a source expression doesn't match any
> pattern, that's because you messed up the parenses or because you passed
> the wrong number of subexpressions to a form
>
> Please note that in this case Guile is not denouncing that the wrong
> number of arguments were passed to a function
>
> Because the "if" is not a function, it's a special form (I think), and the
> expander tries to recognize a known "pattern" in it
>
> It fails and it gives up
>
> Hope this helps
>

[-- Attachment #2: Type: text/html, Size: 7058 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-11-26 20:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-25 13:26 Bug in my WIP-npm-importer with blacklist swedebugia
2018-11-25 15:01 ` Gábor Boskovits
2018-11-26 19:39 ` Catonano
2018-11-26 20:20   ` Catonano

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).