Git Product home page Git Product logo

clj-new's People

Contributors

abcdw avatar arichiardi avatar behrica avatar borkdude avatar burn2delete avatar dijonkitchen avatar holyjak avatar joelittlejohn avatar jpe90 avatar levitanong avatar masmatsum avatar noonian avatar norton avatar pez avatar rwstauner avatar seancorfield avatar solussd avatar waffle-iron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clj-new's Issues

Consider options using tools.cli

boot-new and lein new have a lot of options to control the project generation. Are any of these worth porting to clj-new? If so, use tools.cli to specify what the command-line should look like.

Consider option to copy entire project tree

Currently, template projects have to be created file-by-file and often assume a file source structure and a nested target structure. For larger templates, that makes for a long list of arguments passed to ->files.

It would be convenient to be able to structure the project source to match the desired target structure and have clj-new.create recursively walk the source tree to create the target tree.

Customize generator prefix

Hi Sean,

Opening a new issue so that we can discuss how to approach the problem of customizing the prefix parameter to the generator - it looks like there is no way for a generator to tell what prefix to target and it seems like every change would be breaking so better talk about it beforehand.

The arguments to -main are a non-solution because we don't want the user to input the prefix, but the generator setting it.

I am tempted to propose a new.generate2 command or a command that reads from a clj.generate2.foo/generate2 function with completely different semantics.

I would like to restate my goal here as well: be able to have a mechanism to additively modify edn files in the project.

Thank you a lot again as usual.

P.S.: I can take care of the patch

Hard to conditionally add some files

For example, I may only want to add sass files if the project has "--frontend" as a flag.

Currently to do this I have to create a second block lik.e:

(when frontend?
  (binding [*force?* true]
    (->files …)))

The *force?* in particular makes this awkward, as I don't know what other implications that has.

One option would be to have ->files ignore nil, such that this would work:

(->files data
  ["main.clj" …]
  (when frontend?
    ["main.cljs …"]))

compojure template fails to create deps.edn

Using the https://github.com/weavejester/compojure-template to create projects with clj-new fails to create a deps.edn file.

clojure -A:new compojure practicalli/compojure-website

This creates the following project files, but a deps.edn file is not created.

compojure-website-cli
├── project.clj
├── README.md
├── resources
│   └── public
├── src
│   └── practicalli
│       └── compojure_website
│           └── handler.clj
└── test
    └── practicalli
        └── compojure_website
            └── handler_test.clj

Using the multi-segment name the same files are produced, without the deps.edn file again

clojure -A:new compojure practicalli.my-website

Using the following leiningen command, the same project files are created and content in all files are identical.

lein new compojure practicalli/compojure-website

clj-new version 0.7.6 is used by adding an alias to the $HOME/.clojure/deps.edn file

 :aliases
 {:new {:extra-deps {seancorfield/clj-new
                     {:mvn/version "0.7.6"}}
        :main-opts  ["-m" "clj-new.create"]}}

Support command-line variables

It would be useful to allow -e var=value to provide additional substitutions in templates. This might be particularly useful if you are generating a project with a POM, for example.

Map literal must contain an even number of forms

Either adding

{:aliases
  {:new {:extra-deps {seancorfield/clj-new
                      {:mvn/version "0.5.5"}}
         :main-opts ["-m" "clj-new.create"]}}}

and running clj from command line

or running from command line

clj -Sdeps '{:deps
              {seancorfield/clj-new
                {:mvn/version "0.5.5"}}}' \
  -m clj-new.create \
  app \
  myname/myapp

creates a stacktrace:

Error building classpath. Map literal must contain an even number of forms
java.lang.RuntimeException: Map literal must contain an even number of forms
	at clojure.lang.Util.runtimeException(Util.java:221)
	at clojure.lang.EdnReader$MapReader.invoke(EdnReader.java:682)
	at clojure.lang.EdnReader.read(EdnReader.java:145)
	at clojure.lang.EdnReader.read(EdnReader.java:111)
	at clojure.edn$read.invokeStatic(edn.clj:35)
	at clojure.edn$read.invoke(edn.clj:14)
	at clojure.tools.deps.alpha.util.io$slurp_edn.invokeStatic(io.clj:29)
	at clojure.tools.deps.alpha.util.io$slurp_edn.invoke(io.clj:22)
	at clojure.tools.deps.alpha.reader$slurp_edn_map.invokeStatic(reader.clj:38)
	at clojure.tools.deps.alpha.reader$slurp_edn_map.invoke(reader.clj:35)
	at clojure.tools.deps.alpha.reader$slurp_deps.invokeStatic(reader.clj:58)
	at clojure.tools.deps.alpha.reader$slurp_deps.invoke(reader.clj:54)
	at clojure.core$map$fn__5587.invoke(core.clj:2745)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.Cons.next(Cons.java:39)
	at clojure.lang.RT.boundedLength(RT.java:1785)
	at clojure.lang.RestFn.applyTo(RestFn.java:130)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at clojure.tools.deps.alpha.reader$merge_deps.invokeStatic(reader.clj:73)
	at clojure.tools.deps.alpha.reader$merge_deps.invoke(reader.clj:70)
	at clojure.tools.deps.alpha.reader$read_deps.invokeStatic(reader.clj:78)
	at clojure.tools.deps.alpha.reader$read_deps.invoke(reader.clj:75)
	at clojure.tools.deps.alpha.script.make_classpath$combine_deps_files.invokeStatic(make_classpath.clj:47)
	at clojure.tools.deps.alpha.script.make_classpath$combine_deps_files.invoke(make_classpath.clj:43)
	at clojure.tools.deps.alpha.script.make_classpath$run.invokeStatic(make_classpath.clj:68)
	at clojure.tools.deps.alpha.script.make_classpath$run.invoke(make_classpath.clj:64)
	at clojure.tools.deps.alpha.script.make_classpath$_main.invokeStatic(make_classpath.clj:109)
	at clojure.tools.deps.alpha.script.make_classpath$_main.doInvoke(make_classpath.clj:84)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)

New to the project, simple example appears to stacktrace

Long time experienced lein new myproject user here. Just read the clj-new documentation in the README and wanted to try it out.

Just wanted to try the deps.edn approach and already the first example listed fails with a stack trace. Is there a better start up doc or quick fix to the below?

$ clj -Sdeps '{:deps
>               {seancorfield/clj-new
>                 {:mvn/version "0.5.5"}}}' \
>   -m clj-new.create \
>   app \
>   myname/myapp
Error building classpath. EOF while reading
java.lang.RuntimeException: EOF while reading
	at clojure.lang.Util.runtimeException(Util.java:221)
	at clojure.lang.EdnReader.readDelimitedList(EdnReader.java:746)
	at clojure.lang.EdnReader$MapReader.invoke(EdnReader.java:680)
	at clojure.lang.EdnReader.read(EdnReader.java:145)
	at clojure.lang.EdnReader.read(EdnReader.java:111)
	at clojure.edn$read.invokeStatic(edn.clj:35)
	at clojure.edn$read.invoke(edn.clj:14)
	at clojure.tools.deps.alpha.util.io$slurp_edn.invokeStatic(io.clj:29)
	at clojure.tools.deps.alpha.util.io$slurp_edn.invoke(io.clj:22)
	at clojure.tools.deps.alpha.reader$slurp_edn_map.invokeStatic(reader.clj:38)
	at clojure.tools.deps.alpha.reader$slurp_edn_map.invoke(reader.clj:35)
	at clojure.tools.deps.alpha.reader$slurp_deps.invokeStatic(reader.clj:58)
	at clojure.tools.deps.alpha.reader$slurp_deps.invoke(reader.clj:54)
	at clojure.core$map$fn__5587.invoke(core.clj:2745)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.Cons.next(Cons.java:39)
	at clojure.lang.RT.boundedLength(RT.java:1785)
	at clojure.lang.RestFn.applyTo(RestFn.java:130)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at clojure.tools.deps.alpha.reader$merge_deps.invokeStatic(reader.clj:73)
	at clojure.tools.deps.alpha.reader$merge_deps.invoke(reader.clj:70)
	at clojure.tools.deps.alpha.reader$read_deps.invokeStatic(reader.clj:78)
	at clojure.tools.deps.alpha.reader$read_deps.invoke(reader.clj:75)
	at clojure.tools.deps.alpha.script.make_classpath$combine_deps_files.invokeStatic(make_classpath.clj:47)
	at clojure.tools.deps.alpha.script.make_classpath$combine_deps_files.invoke(make_classpath.clj:43)
	at clojure.tools.deps.alpha.script.make_classpath$run.invokeStatic(make_classpath.clj:68)
	at clojure.tools.deps.alpha.script.make_classpath$run.invoke(make_classpath.clj:64)
	at clojure.tools.deps.alpha.script.make_classpath$_main.invokeStatic(make_classpath.clj:109)
	at clojure.tools.deps.alpha.script.make_classpath$_main.doInvoke(make_classpath.clj:84)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
$ uname -a
Darwin cxaaelony-m.local 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64

Way for clj-new.create to show more info when errors parsing custom-templates?

Would there be a way so that if there is an error in the custom template, that clj-new could show more info on the failure.

I had some silly yet subtle errors in my ns / require block at the top of the main template function that took a very long time to debug. Much of this was my own limitations as a Clojure programmer, but the only error I got out of clj-new was:

Execution error (ExceptionInfo) at clj-new.helpers/resolve-remote-template (helpers.clj:143).
Could not load template, require of clj.new.re-frame-template failed with: Syntax error compiling at (clj/new/re_frame_template/helpers.clj:1:1).

Turned out I had a wrong namespace in a nested require as well as a spelling error in another line of the ns declaration. But it took way long to figure those out!

namespaced templates?

One legacy aspect of Leiningen (and boot) templates are that the namespace where templates are defined is under leiningen.new.*, such as leiningen.new.app or leiningen.new.plugin. This makes sense when those templates are part of the Leiningen project. However, it works against typical name spacing conventions when third parties also create templates under the leiningen.new namespace hierarchy. If I create a template, I'd like it to be able to define it under com.grzm.* so as to not collide with other templates. A practical example would be a Fulcro template that I want to define differently than the official Fulcro template maintained by Tony Kay.

From a usage point of view, I think it wouldn't be too cumbersome to call these templates in a namespaced fashion. For example, to create a project using the official Fulcro template:

cli -A:new new fulcro com.grzm/std-fulcro-app

And to use my custom template:

cli -A:new:grzm-fulcro new com.grzm.template/fulcro com.grzm/custom-fulcro-app

At one time I worked up something that was backwards compatible with Leiningen and boot templates, and if the idea makes sense, I'll dust it off as a PR.

DefaultModelResolver error using clj-new

clj alias:

       :new {:deps {seancorfield/clj-new {:mvn/version "0.8.5"}}
              :main-opts ["-m" "clj-new.create"]}

fails using this template:

$ clj -A:new https://github.com/mikeananev/slib@3c427a64ec03fcf618b9e55559345e76e08e8b76 qwerty/asd
Failed with: org.apache.maven.repository.internal.DefaultModelResolver.<init>(org.eclipse.aether.RepositorySystemSession,org.eclipse.aether.RequestTrace,java.lang.String,org.eclipse.aether.impl.ArtifactResolver,org.eclipse.aether.impl.VersionRangeResolver,org.eclipse.aether.impl.RemoteRepositoryManager,java.util.List)
Execution error (ExceptionInfo) at clj-new.helpers/resolve-remote-template (helpers.clj:149).
Could not load artifact for template: slib
	Tried coordinates:
		[slib/boot-template "RELEASE"]
		[slib/lein-template "RELEASE"]
Full report at:
/var/folders/2k/2l7ch1xn7lb5gj86tgp1ygww0000gn/T/clojure-13105343161273067757.edn

Did not happen on other user's machine, but the transitive dependency selection between pomegranate and tools.deps may be non-deterministic here.

I found forcing newest tools.deps.alpha (which no longer uses DefaultModelResolver) got past the problem:

       :new {:deps {seancorfield/clj-new {:mvn/version "0.8.5"}
                    org.clojure/tools.deps.alpha {:mvn/version "0.8.640"}}
              :main-opts ["-m" "clj-new.create"]}

So my recommendation would be to update tools.deps.alpha to the latest, 0.8.640.

Align dot-clojure and clj-new usage more closely

Currently, clj-new shows a :new alias with :template "app" as the default but dot-clojure has :template lib. These should be consistent. Perhaps consider :new-app and :new-lib as well in both (although that's not very DRY).

Stop using RELEASE in templates

People keep complaining about it so I'll hardcode specific versions. It just means I need to update clj-new when those dependencies get updated.

Specify template as git/url or local/root?

Could the template name be a Git or Local dependency?

clj -A:new https://github.com/myaccount/some-project@764237652376abcd76767fa123 myname/myapp

That seems fairly distinct for a :git/url and :sha. What about :local/root? Since templates are otherwise foo/<something>-template where you only specify foo, would the presence of / alone be enough to trigger a :local/root dependency?

clj-new error on Leiningen template "luminus"

When I execute following command:

clj -A:new luminus stardiviner/luminus_demo
I got error:

Execution error (ExceptionInfo) at clj-new.helpers/resolve-remote-template (helpers.clj:131).
Could not load template, require of leiningen.new.luminus failed with: Syntax error compiling . at (cheshire/factory.clj:79:7).

Full report at:
/tmp/clojure-8033443089734186285.edn
{:clojure.main/message
 "Execution error (ExceptionInfo) at clj-new.helpers/resolve-remote-template (helpers.clj:131).\nCould not load template, require of leiningen.new.luminus failed with: Syntax error compiling . at (cheshire/factory.clj:79:7).\n",
 :clojure.main/triage
 {:clojure.error/class  clojure.lang.ExceptionInfo,
  :clojure.error/line   131,
  :clojure.error/cause
  "Could not load template, require of leiningen.new.luminus failed with: Syntax error compiling . at (cheshire/factory.clj:79:7).",
  :clojure.error/symbol clj-new.helpers/resolve-remote-template,
  :clojure.error/source "helpers.clj",
  :clojure.error/phase  :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.ExceptionInfo,
    :message
    "Could not load template, require of leiningen.new.luminus failed with: Syntax error compiling . at (cheshire/factory.clj:79:7).",
    :data {},
    :at
    [clj_new.helpers$resolve_remote_template
     invokeStatic
     "helpers.clj"
     131]}],
  :trace
  [[clj_new.helpers$resolve_remote_template
    invokeStatic
    "helpers.clj"
    131]
   [clj_new.helpers$resolve_remote_template invoke "helpers.clj" 36]
   [clj_new.helpers$resolve_template$fn__2806 invoke "helpers.clj" 153]
   [clj_new.helpers$resolve_template invokeStatic "helpers.clj" 150]
   [clj_new.helpers$resolve_template invoke "helpers.clj" 146]
   [clj_new.helpers$create_STAR_ invokeStatic "helpers.clj" 173]
   [clj_new.helpers$create_STAR_ invoke "helpers.clj" 165]
   [clj_new.helpers$create invokeStatic "helpers.clj" 207]
   [clj_new.helpers$create invoke "helpers.clj" 186]
   [clj_new.create$_main invokeStatic "create.clj" 16]
   [clj_new.create$_main doInvoke "create.clj" 10]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.core$apply invokeStatic "core.clj" 665]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause
  "Could not load template, require of leiningen.new.luminus failed with: Syntax error compiling . at (cheshire/factory.clj:79:7).",
  :data {}}}

My environment:

java --version
openjdk 13.0.1 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode)

Make help smarter

When you invoke clojure -X:new with no additional arguments (specifically without a :name argument) you get a fairly generic help that still favors the -M style arguments and doesn't mention the alias(es) you might use.

  • update the help to be all about -X
  • get the aliases via t.d.a and use that to be more intelligent about how to invoke clj-new

allow generators to add an alias/deps to deps.edn

Just putting this out there as food for thought.

Now that configuration is just edn we could use rewrite-clj and allow generators to update deps.edn.

The use case I have in mind is to be able to generate figwheel on an existing project.

This is of course challenging as it's extremely difficult for generators to compose, but if we scope all changes to an alias that is managed by a set of generators, it becomes more approachable.

Clarify docs about project namespace

foo.bar creates a project folder called foo.bar containing src/foo/bar.clj

quux/whatever creates a project folder calls just whatever containing src/quux/whatever.clj

The intention is that you create <my-unique-id>/<my-project>.

This could be clearer!

Using wrong template

I have a template called clj-app, which is supposed to generate my default template for a Clojure app. However, when I run

clojure -A:new clj-app test-app

it generates based off the app template, not the clj-app template. My template is not installed to Clojars, but is installed to my local maven repository.

Output (using -v flag):

Output from locating template:

Generating a project called test-app based on the 'app' template.

Have depstar synchronize the pom.xml file

Add :sync-pom true to :exec-args so that depstar always tries to keep the generated pom.xml in sync for dependencies etc.

Also, add notes to README (main project and generated ones) about why the pom.xml exists and how to update the version via depstar.

Verified Group Names and templates

In light of Clojars improving security of group names -- see https://github.com/clojars/clojars-web/wiki/Verified-Group-Names -- we tool maintainers need to consider how to move forward with templates for Leiningen, Boot, and the CLI.

Leiningen long ago adopted the naming convention of <template>/lein-template and I followed suit in boot-new with <template>/boot-template and then again in clj-new with <template>/clj-template. That has led to Leiningen templates being published into "random" groups that match the name of the template but often have very little bearing on the maintainer's username and/or the URL/coordinates of the project for which the template exists.

The benefit of this naming convention is the ease of finding them programmatically, or via searches on clojars.org, or via sites like clj-templates.com but pretty much none of the existing templates have group IDs that satisfy the new Verified Group Names policy.

For existing templates, this isn't a big problem since Clojars will continue to allow new library releases into existing non-verified groups -- but by mid-April, it will not be possible to publish new project templates that have a template name that is not a reverse domain name (or at least a verified group name).

As an initial discussion point, I'm opening this issue in all three tools' GitHub repos but I don't have a solid proposal for a new naming scheme that would make templates easy to find for tools:

Support CLI -X usage

With -X coming to the Clojure CLI, clj-new could benefit from supporting it, and that may be a nicer approach.

Custom git templates: multiple template per repo

First off, thank you for creating this library 🙏

I was playing with generating my own custom templates and really like the idea of specifying a :git/url to save me having to manually clone my template repo.

I could be wrong, but it does not seem possible to specify multiple templates from inside one repo. Is this correct?

For example,

I initially created a repo which contains multiple templates like

  • starter-kit/clj/new/template-1
  • starter-kit/clj/new/template-2
  • starter-kit/clj/new/template-3

Now I would like to be able to do something like:

clj -A:new https://github.com/somename/starter-kits/template-1@c1fc0cdf5project-name ...

clj -A:new https://github.com/somename/starter-kits/template-2@c1fc0cdf5project-name ...

clj -A:new https://github.com/somename/starter-kits/template-3@c1fc0cdf5project-name ...

But this does not seem to be supported as the expectation is that the repo specified only has 1 template and the name of the repo is also the name of the template.

If this is correct, would it be worth while in your opinion to modify the structure so that a user can have multiple templates in one repo?

note that I am not suggesting that the solution is to extend the url to allow for template-* just that it would be neat to allow multiple templates from 1 repo.

Again, thank you for your work and I look forward to helping in any way I can 👍

clj -A:install fails for template on windows 10 in powershell

Hi,

I just wanted to try clj new on W10 in the powershell. Creation of a template with:
clj -A:new template de.sveri/closp
works and I can open it fine in cursive. However, when I want to install this project with:
clj -A:install
I get a FileNotFoundException:

Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
closp.jar (Das System kann die angegebene Datei nicht finden)

{:clojure.main/message "Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).\r\nclosp.jar (Das System kann die angegebene Datei nicht finden)\r\n", :clojure.main/triage {:clojure.error/class java.io.FileNotFoundException, :clojure.error/line -2, :clojure.error/cause "closp.jar (Das System kann die angegebene Datei nicht finden)", :clojure.error/symbol java.io.FileInputStream/open0, :clojure.error/source "FileInputStream.java", :clojure.error/phase :execution}, :clojure.main/trace {:via [{:type org.eclipse.aether.installation.InstallationException, :message "Failed to install artifact closp:clj-template:jar:0.1.0-SNAPSHOT: closp.jar (Das System kann die angegebene Datei nicht finden)", :at [org.eclipse.aether.internal.impl.DefaultInstaller install "DefaultInstaller.java" 280]} {:type java.io.FileNotFoundException, :message "closp.jar (Das System kann die angegebene Datei nicht finden)", :at [java.io.FileInputStream open0 "FileInputStream.java" -2]}], :trace [[java.io.FileInputStream open0 "FileInputStream.java" -2] [java.io.FileInputStream open "FileInputStream.java" 213] [java.io.FileInputStream "FileInputStream.java" 155] [org.eclipse.aether.internal.impl.DefaultFileProcessor copy "DefaultFileProcessor.java" 162] [org.eclipse.aether.internal.impl.DefaultFileProcessor copy "DefaultFileProcessor.java" 150] [org.eclipse.aether.internal.impl.DefaultInstaller install "DefaultInstaller.java" 267] [org.eclipse.aether.internal.impl.DefaultInstaller install "DefaultInstaller.java" 195] [org.eclipse.aether.internal.impl.DefaultInstaller install "DefaultInstaller.java" 152] [org.eclipse.aether.internal.impl.DefaultRepositorySystem install "DefaultRepositorySystem.java" 377] [jdk.internal.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2] [jdk.internal.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.java" 62] [jdk.internal.reflect.DelegatingMethodAccessorImpl invoke "DelegatingMethodAccessorImpl.java" 43] [java.lang.reflect.Method invoke "Method.java" 567] [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 167] [clojure.lang.Reflector invokeInstanceMethod "Reflector.java" 102] [cemerick.pomegranate.aether$install_artifacts invokeStatic "aether.clj" 377] [cemerick.pomegranate.aether$install_artifacts doInvoke "aether.clj" 363] [clojure.lang.RestFn applyTo "RestFn.java" 137] [clojure.core$apply invokeStatic "core.clj" 665] [clojure.core$apply invoke "core.clj" 660] [cemerick.pomegranate.aether$install invokeStatic "aether.clj" 450] [cemerick.pomegranate.aether$install doInvoke "aether.clj" 436] [clojure.lang.RestFn invoke "RestFn.java" 619] [deps_deploy.deps_deploy$eval1602$fn__1604 invoke "deps_deploy.clj" 45] [clojure.lang.MultiFn invoke "MultiFn.java" 229] [deps_deploy.deps_deploy$_main invokeStatic "deps_deploy.clj" 52] [deps_deploy.deps_deploy$_main doInvoke "deps_deploy.clj" 51] [clojure.lang.RestFn invoke "RestFn.java" 425] [clojure.lang.AFn applyToHelper "AFn.java" 156] [clojure.lang.RestFn applyTo "RestFn.java" 132] [clojure.lang.Var applyTo "Var.java" 705] [clojure.core$apply invokeStatic "core.clj" 665] [clojure.main$main_opt invokeStatic "main.clj" 514] [clojure.main$main_opt invoke "main.clj" 510] [clojure.main$main invokeStatic "main.clj" 664] [clojure.main$main doInvoke "main.clj" 616] [clojure.lang.RestFn applyTo "RestFn.java" 137] [clojure.lang.Var applyTo "Var.java" 705] [clojure.main main "main.java" 40]], :cause "closp.jar (Das System kann die angegebene Datei nicht finden)"}}

New release may have broken something

Hi! Love this project. I'm new to Clojure, but I think the new release may have broken something!

Problem

I installed 1.1.215 and tried running
clj -A:new figwheel-main hello-world.core -- --reagent
and it encounters an error :(

Cannot open <nil> as a Reader.

Full report at:
/var/folders/d5/wvg2fhz11l3fzks8ncz6n7sh0000gn/T/clojure-13490045115141148557.edn

The same error happened when trying to use other templates.

This is the full report:

 "Execution error (IllegalArgumentException) at clj-new.helpers/fn (helpers.clj:64).\nCannot open <nil> as a Reader.\n",
 :clojure.main/triage
 {:clojure.error/class java.lang.IllegalArgumentException,
  :clojure.error/line 64,
  :clojure.error/cause "Cannot open <nil> as a Reader.",
  :clojure.error/symbol clj-new.helpers/fn,
  :clojure.error/source "helpers.clj",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type java.lang.IllegalArgumentException,
    :message "Cannot open <nil> as a Reader.",
    :at [clojure.java.io$fn__11520 invokeStatic "io.clj" 288]}],
  :trace
  [[clojure.java.io$fn__11520 invokeStatic "io.clj" 288]
   [clojure.java.io$fn__11520 invoke "io.clj" 288]
   [clojure.java.io$fn__11422$G__11398__11429 invoke "io.clj" 69]
   [clojure.java.io$reader invokeStatic "io.clj" 102]
   [clojure.java.io$reader doInvoke "io.clj" 86]
   [clojure.lang.RestFn invoke "RestFn.java" 410]
   [clojure.lang.AFn applyToHelper "AFn.java" 154]
   [clojure.lang.RestFn applyTo "RestFn.java" 132]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$slurp invokeStatic "core.clj" 6942]
   [clojure.core$slurp doInvoke "core.clj" 6942]
   [clojure.lang.RestFn invoke "RestFn.java" 410]
   [clj_new.helpers$fn__3085 invokeStatic "helpers.clj" 64]
   [clj_new.helpers$fn__3085 invoke "helpers.clj" 62]
   [clojure.lang.Delay deref "Delay.java" 42]
   [clojure.core$deref invokeStatic "core.clj" 2320]
   [clojure.core$deref invoke "core.clj" 2306]
   [clj_new.helpers$resolve_remote_template
    invokeStatic
    "helpers.clj"
    72]
   [clj_new.helpers$resolve_remote_template invoke "helpers.clj" 67]
   [clj_new.helpers$resolve_template$fn__3128 invoke "helpers.clj" 193]
   [clj_new.helpers$resolve_template invokeStatic "helpers.clj" 190]
   [clj_new.helpers$resolve_template invoke "helpers.clj" 186]
   [clj_new.helpers$create_STAR_ invokeStatic "helpers.clj" 223]
   [clj_new.helpers$create_STAR_ invoke "helpers.clj" 217]
   [clj_new.helpers$create_x$fn__3157 invoke "helpers.clj" 318]
   [clj_new.helpers$create_x invokeStatic "helpers.clj" 308]
   [clj_new.helpers$create_x invoke "helpers.clj" 279]
   [clj_new.helpers$create invokeStatic "helpers.clj" 332]
   [clj_new.helpers$create invoke "helpers.clj" 321]
   [clj_new.create$_main invokeStatic "create.clj" 15]
   [clj_new.create$_main doInvoke "create.clj" 10]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.core$apply invokeStatic "core.clj" 665]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "Cannot open <nil> as a Reader."}}

Workaround

Rolling back to 1.0.211 fixed everything and I can use templates without error

Enable snapshot lookup

Not sure how best to pass options in here but if it's easy to pass -S or --snapshot, we could also expose all of the other options :)

Switch default group ID to com.github.<username>?

We could assume that a project name like username/my-project should have a group ID of com.github.username instead of just plain username.

We could also accept (and encourage) a fully-qualified com.github.username/my-project name.

And then we could derive the SCM from such a reverse domain name? com.gitlab.username works.

What about com.acme/my-project (or com.acme.department/my-project)?

Add easy way to display built-in variables

It would be really nice to have a quick and easy way to ask clj-new to display all the built-in values that you should expect in a template.

This might involve standardizing the ad hoc variables used across the templates today...?

Expand explanation/justification of requiring qualified project name

Something along these lines:

If you are going to publish a library, it will have a group ID and an artifact ID (e.g., seancorfield/clj-new) and the group ID should be something unique to you or your organization -- most people use their GitHub username or their company name. The qualified name you provide to clj-new is basically group/artifact. It also uses that to create the main namespace: src/group/artifact.clj containing (ns group.artifact ...) -- this ensures that when someone uses your library, it's not going to clash with other code because the first portion of the namespace is, again, something unique to you or your organization.

lein new myapp will treat myapp as both the group ID and the artifact ID (which is why a lot of older Clojure libs just have an unqualified lib name, like ring -- but really it's ring/ring and recent versions of the Clojure CLI give a deprecation warning on just ring). Leiningen also stuck .core on your name to create the main namespace -- which is why a lot of older Clojure libs have a something.core namespace: just because Leiningen did that by default. Both default behaviors here are bad because they're likely to lead to conflicts with other libraries.

As it says in the clj-new README, you can of course just ask for myapp.core and you'll get pretty much the (bad) Leiningen behavior (except your group and artifact IDs will both be myapp.core -- which is also what you get if you say lein new myapp.core).

Generator ergonomics

For the generators, maybe consider not automatically generating files within the ./src directory.

This allows one to use the terminal's autocompletion to quickly drill down into a deep namespace and make a new namespace. It seems like the file generator isn't really worth all the effort since you can just create that file easily in the terminal and just type the namespace declaration with less work and autocompletion natively.

Currently, I can use autocompletion to do something like this, but it nests a new ./src/src directory under the original ./src.

clj -m clj-new.generate ns=./src/clj/myname/myapp/somedomain/model/user

It properly appends .clj to the file and starts it off with the namespace declaration, but it is / seperated instead of .'s.

(ns ./src/clj/myname/myapp/somedomain/model/user
  "Generated by clj")

String generator

Would be useful for small one-line files, or those generated using clojure code, to use render-string, but still have the variables populated by clj-new.

Essentially instead of: ((renderer "foo") "bar.txt") doing (render-string "some={{namespace}}")

Luminus template options don't seem to work

From Rowan on Slack:

"I'm still having issues with that command, here is what I entered along with the output:

$ clojure -X:new :template luminus :name Rowan/guestbook :output '"mywebapp"' :args '["+h2" "+http-kit"]'
Downloading: luminus/lein-template/maven-metadata.xml from clojars
Unrecognized options: +h2, +http-kit
Supported options are: +sqlite, +hoplon, +kee-frame, +immutant, +datomic, +site, +undertow, +h2, +auth-jwe, +reitit, +reagent, +jetty, +cljs, +graphql, +service, +sassc, +oauth, +swagger, +servlet, +auth, +war, +http-kit, +expanded, +cucumber, +aleph, +mongodb, +basic, +postgres, +boot, +mysql, +re-frame, +kibit, +shadow-cljs

I don't understand why it says those are unrecognised options and then clearly lists them underneath as supported options"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.