Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementation of command new #79

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

AngeloChecked
Copy link
Contributor

@AngeloChecked AngeloChecked commented Sep 18, 2023

image

The steel new command shares its purpose with tools like cargo new and stack new - it creates the initial boilerplate to kickstart programming.

There are various considerations to ponder:

  • What should the folder structure look like? (e.g., src, lib, tests...)
  • Should we offer a main manifest (like package.json or cargo.toml)?
  • Do we encourage separate test files or embedding tests within source files?
  • Is main.scm fixed as the root, or can it be configured in the manifest?
  • Any other considerations?

In this implementation, I've made certain choices: a flat file structure, an example test file, main.scm as the root, and cogs.scm as the manifest.

$ steel new myproject
$ tree myproject
myproject
├── cog.scm
├── main.scm
├── mysum.scm
└── mysum-test.scm

I don't have strong preferences and usually go with defaults I like. But I'm open to making changes and improvements, also in the code.
Please feel free to suggest any improvements.

@mattwparas
Copy link
Owner

mattwparas commented Sep 19, 2023

First off, thanks for the PR! Overall looks good, one comment so far and just want to address some of the considerations you made in the description:

There are various considerations to ponder:

  • What should the folder structure look like? (e.g., src, lib, tests...)
  • Should we offer a main manifest (like package.json or cargo.toml)?
  • Do we encourage separate test files or embedding tests within source files?
  • Is main.scm fixed as the root, or can it be configured in the manifest?
  • Any other considerations?

I don't particularly have an explicit structure in mind. I do like having some sort of top level lib.scm or info.scm file that has the majority of the exports, however I don't have anything in particular in mind nor strong preference. I'm inclined to see what grows organically here. The structure you've picked is what I tend to go for.

The manifest is hard, I think we should have something. The cog.scm file works for that.

I prefer keeping test files and the source files aligned, however I don't think it should be impossible to separate them.

Having a default main.scm seems fine, although maybe we should have that be a part of the manifest? I guess typically you'd call the entrypoint via something like steel dir/main.scm, but I'm open for discussion on that.

@AngeloChecked
Copy link
Contributor Author

each ecosystem have its structure and various manifests, for instance

elixir:

$ mix new myproject 
myproject
├── lib
│   └── myproject.ex
├── mix.exs
├── README.md
└── test
    ├── myproject_test.exs
    └── test_helper.exs

haskell:

$ stack new myproject
myproject
├── app
│   └── Main.hs
├── CHANGELOG.md
├── LICENSE
├── myproject.cabal
├── package.yaml
├── README.md
├── Setup.hs
├── src
│   └── Lib.hs
├── stack.yaml
└── test
    └── Spec.hs

java have a cultural tendency of structuring project so (but can depend from tool used... eclipse, netbeans, intellij, maven vs gradle...)

$ tree myproject
myproject
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── example
    │   │           └── Main.java
    │   └── resources
    └── test
        └── java

less structured are javascript, golang and python. I don't know them well and I see lot of different approach...

$ mkdir myproject && cd myproject
$ npm init 
$ tree myproject
myproject
└── package.json
$ mkdir myproject && cd myproject
$ go mod init myproject
$ tree myproject
myproject
└── go.mod

in golang are born some defaults, for example here: https://github.com/golang-standards/project-layout
but I don't know if these languages have well accepted tools that enforce a project structure.

@AngeloChecked
Copy link
Contributor Author

If we consider Rust toolchain inspirational for Steel

$ cargo new myproject
$ tree myproject
myproject
├── Cargo.toml
└── src
    └── main.rs

rust is pretty light in the scaffolding.

@AngeloChecked
Copy link
Contributor Author

AngeloChecked commented Sep 19, 2023

For the testing side, I'm super fun of the testing approach used by Golang that enforce test files in the same folder of source file:

├── prune-junit-xml
│   ├── OWNERS
│   ├── prunexml.go
│   └── prunexml_test.go
└── yamlfmt
    ├── OWNERS
    ├── yamlfmt.go
    └── yamlfmt_test.go

instead languages like Rust and Zig tends to put unit tests and sources in the same file...
I don't dislike to have tests in sources, but I have a little preference in the Golang testing approach, no one avoid us to allow both approach.

My final proposal is this one:

myproject
├── cog.scm
└── src
    ├── main.scm
    ├── mysum.scm
    └── mysum-test.scm

Test running is interesting, and I plan to create a new issue for implementing steel test where we can discuss it further.

but do you want keep the file extension .scm?

@mattwparas
Copy link
Owner

Couple points - the way the current library installer works is that it verbatim copies the directory to the $STEEL_HOME prefixed with the package name, so something like

(define package-name 'steel/logging)
(define version "0.1.0")

;; Core library, requires no dependencies
(define dependencies '())

with the structure:

logging
├── cog.scm
└── log.scm

Would then be installed to $STEEL_HOME/steel/logging/log.scm

We could change the behavior to ignore src in that, if we wanted all the files to be packaged under src - it would just need to be changed in the installer, and the existing packages in the SDK will need to be updated accordingly.

Personally I don't feel the need to enforce a src directory, however I'll need to think on that a little bit. I'm inclined okay with it, but if we go that route we'll need to adjust the installer like I mentioned before.

Also - I think tests in libraries and not separate is fine - I like the ability to test private methods as well as public ones. Public ones can be tested externally.

@AngeloChecked
Copy link
Contributor Author

Of course, let me know your decision, and I'm here to help with any fixes if needed.

@mattwparas
Copy link
Owner

I think I quite like the flat structure - this is how racket projects are built with raco pkg new <name>:

├── info.rkt
├── main.rkt
├── README.md
└── scribblings
    └── test.scrbl

So lets go without the src directory for now and a flat structure. I think we can revisit this later if necessary, but for now I think just giving the option of adding the directory yourself is fine if you want to.

@AngeloChecked
Copy link
Contributor Author

AngeloChecked commented Sep 20, 2023

Sure! Do you think the current commit is okay, or should we consider either putting mysum-test.scm inside mysum.scm or using myproject.scm as the root, as specified in the package-name of cog.scm?

@mattwparas
Copy link
Owner

I think the current structure is fine

@kskarthik
Copy link
Contributor

rust project structure is good, I vouch for such project layout!

@AngeloChecked
Copy link
Contributor Author

Hi @mattwparas, does it make sense to refresh this PR, or if it's too early to make a decision, I can close it for now?

@mattwparas
Copy link
Owner

@AngeloChecked If you'd like to refresh the PR that would be fine!

@AngeloChecked
Copy link
Contributor Author

hi @mattwparas,

I added the following to the test:

(define dummy-provide 1)
(provide dummy-provide)

This is just to allow the steel new hello-world && cd hello-world && steel test as first workflow "experience", as tests won’t run without a provided value.

Let me know if you have any new insights or ideas about the starting scaffolding "experience"

@mattwparas
Copy link
Owner

Hi @AngeloChecked - I think I'd like it better if this command were a part of the package manager, akin to cargo new and not as part of the binary for the interpreter.

I'm scaffolding that up now, and will follow up once its ready

@kskarthik
Copy link
Contributor

Hi @AngeloChecked - I think I'd like it better if this command were a part of the package manager, akin to cargo new and not as part of the binary for the interpreter.

I'm scaffolding that up now, and will follow up once its ready

pkg manager will be a part of steel binary? that would be nice. just like go get or deno install

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants