Code Monkey home page Code Monkey logo

lets's People

Contributors

dependabot[bot] avatar kindermax avatar lmartinez-mirror avatar namelsking avatar olekthunder avatar rkdl avatar vharitonsky avatar vitaly-om 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

Watchers

 avatar  avatar  avatar  avatar  avatar

lets's Issues

add remote mixins

To be able to use shared lets configs we could introduce remote mixins

PoC would look like this

mixins:
 - lets.test.yaml
 - url: https://some.path.com/lets.lint.yaml
   version: v1

This will download this mixin in .lets dir and cache it

Thing to consider:

  • how to version remote url ?
  • do we need to use latest ?
  • how to force download or cleanup remote mixins ?
  • what if network is unavailable ? how long to wait ?
  • terminal progress UI for downloading (--upgrade command would benefit from it too)

Link to online help in error messages

For example:

lets
[ERROR] failed to load config file lets.yaml: open lets.yaml: no such file or directory

<----link on how to create your first lets.yaml --->

go command

Basic built-in command which will generate default lets.yaml with hello world command inside, so it is very easy to introduce lets into a project. We can imagine a wizard asking basic defaults like shell type before generating the file.

usage question: cannot export .env variables using lets

This is probably not an issue with lets-cli, just something I've looked up on stack overflow and cannot get it to work.

I want to export variables in a docker swarm project:

load-env:
    description: Loads environment variables specified in stacks/swarm.env into the current shell.
    cmd: set -a; . stacks/swarm.env; set +a

Running set -a; . stacks/swarm.env; set +a exports the variables in the env file, but running lets load-env does not. I haven't been able to figure out why.

I also tried export $(cat stacks/swarm.env) > /dev/null 2>&1; and it works the same way.

Implement some sort of a clean or on_stop directive

It may be useful to declare cleanup command.

Example:

commands:
  run: 
   cmd: |
     docker-compose up some-service -d
     npm run app
   on_stop:
     docker-compose down

I will allow to explicitly declare what to do when a command stopped either by error or Ctrl+c

number in env must be coerced

commands:
  run:
    env:
      DEBUG: 1
    cmd: echo ${DEBUG}

Got [ERROR] failed to load config file lets.yaml: failed to parse 'run' command: field env.DEBUG: must be a string

Add ability to skip tasks,if checksum for this traks was not changed

Sometimes I want to skip execution of some tasks, if command's checksum from last run is not changed.
Example: before each npm run smth I want to run npm i. But if package.json and package.lock is not changed, I do not need to run npm i

So, in lets.yaml I want to past smth like this and as a result, omit running task

New lets.yaml

install_deps:
  checksum:
    deps: &deps
      - package.json    
      - package-lock.json
  only:
    checksum:
      <<: *deps
  cmd: npm i

run-smth:
  depends: [install_deps]
  cmd: npm run smth

As you can see, in lets.yaml I added in cmd install_deps property only. It will allow to execute install_deps.cmd only if checksum for this cmd changed.

So, what we need to implement:

  • Persistant saving of checksums into file
  • Reading saved checksum for command
  • Updating of after cmd successful execution
  • Skip command invocation, if new and saved checksum are equal

Update to go1.18

Update go runtime and update source code using new go standard library functions

Implement parallel cmds execution

In some cases I need to run two or more jobs in parallel. For ex. compile TS code and serve it over HTTP. Now I need to open two or more terminal sessions and run cmds. It will be great if I will be able to write in lets.yaml like:

commands:
   compile-ts:
      cmd: npm run build
   serve:
      cmd: npm run serve
   serve-compiled:
      cmds:
      - compile-ts
      - serve-compiled

Also It will be great, if lets will decorate each stdout of subproceses like docker-compose:

[compile-ts]: foo
[serve]: bar

Allow to pass non documented options to lets commands

Actual behaviour

For now if I want to pass options to command I must describe them in options property of command block. If I want to pass non documented options to Lets command, I need to write cmd property as array of strings, then Lets will allow me to add any option to cmd. 

Problem description

If my command script is complex and uses if-else bash blocks, it cannot be described using array syntax with the same level of understanding and laconicism as when I use multiline command. 

Feature description

I need to allow to pass non documented options to my command, even if it was written using multiline/singleline style the same as  using list-of-strings style

add settings

Idea to add settings to config.

It then used as LETS_SETTING_<NAME_OF_SETTING>

Settings can be stored in .lets/settings.json

Add new --set and --reset flags.

Example:

settings:
  skip-pull: false

So LETS_SETTING_SKIP_PULL=false will be available in env.

lets --set skip-pull=true will override and persist setting to .lets/settings.json

pass results from depends commands to root command

Example

commands:
  build-image:
    persist_checksum: true
    checksum:
      - requirements.txt
    cmd: docker build -t img:${LETS_CHECKSUM} -f Dockerfile .

  unpack-container:
    depends: [build-image]
    cmd: |
      if [[ ${LETS_BUILD_IMAGE_CHECKSUM_CHANGED} = true ]]; then
        cid=`docker create img:${LETS_BUILD_IMAGE_CHECKSUM}`;
        docker cp ${cid}:/usr/ ./local/usr
        docker rm ${cid}
      fi

In this example, we have build-image command with persist_checksum: true. If this command runs, it will generate env LETS_CHECKSUM_CHANGED and LETS_CHECKSUM.

It would be very convenient to pass this env vars to unpack-container as build-image is in it's depends so we could use those envs in root cmd.

env vars can be named by pattern LETS_<UPPERCASED_AND_UNDERSCORED_CMD_NAME>_CHECKSUM and so on.

Interpolation of command in docopt options

Often we have several almost-identical commands which share most of the body.

But due to constraints to https://github.com/docopt/docopt.go we have to declare Usage with particular command name. Let me show an example:

commands:
  run:
    options: |
      Usage: lets run [--config=<config>]
    env: 
      SOME_SECRET: "123"
    depends: [build-app]
    cmd: docker-compose up app postgres
  
  run-app:
    options: |
      Usage: lets run-app [--config=<config>]
    env: 
      SOME_SECRET: "123"
    cmd: docker-compose up app

  run-debug:
    options: |
      Usage: lets run-debug [--config=<config>]
    env: 
      SOME_SECRET: "123"
    cmd: docker-compose up app-debug

We can get rid of some repetition using yaml features:

commands:
  run: &run
    options: |
      Usage: 
        lets run [--config=<config>]
        lets run-app [--config=<config>]
        lets run-debug [--config=<config>]
    env: 
      SOME_SECRET: "123"
    depends: [build-app]
    cmd: docker-compose up app postgres
  
  run-app:
    <<: *run
    cmd: docker-compose up app

  run-debug:
    <<: *run
    cmd: docker-compose up app-debug

But its still required to enumerate all run run command options in options in run command. Its bad.

What I suggest is:

  1. Add new env - LETS_COMMAND_NAME which is a command name itself.
  2. We can use this env in options and interpolate options string.
commands:
  run: &run
    options: |
      Usage:  lets ${LETS_COMMAND_NAME} [--config=<config>]
    env: 
      SOME_SECRET: "123"
    depends: [build-app]
    cmd: docker-compose up app postgres
  
  run-app:
    <<: *run
    cmd: docker-compose up app

  run-debug:
    <<: *run
    cmd: docker-compose up app-debug

Thus we do not breaking docopt contract and providing absolutely correct docopt string and its cleaner as well.

Add new env mode - ref

Example:

commands:
   show-users:
     cmd: cat users.txt
   
   grant-access-all:
     ADMINS: 
      ref: show-users

We can mimic this behavior like this:

commands:
   show-users:
     cmd: cat users.txt
   
   grant-access-all:
     ADMINS: 
      sh: lets show-users

and while this does not require complex validations, it is a bit slower since requires to start new instance of lets

Validate that:

  • no circular deps created
    • for example command declares env var with ref to itself
    • another example - two commands a and b declares envs that a:env:B depends on b and b:env:A depends on a
  • if command uses global env that depends on the command itself
  • probably do not implement mode: ref for global env in first iteration because it can be hard to deal with circular calls
  • something else ?

Show depends tree for failed command

For commands like these:

commands:
  build-app:
     ...
  run-app:
    depends: [build-app]
    ...

if build-app fails we show:

failed to run command 'build-app': exit status 130
failed to run command 'run-app': exit status 130

But we can make it something like

'run-app' ->
   'build-app' failed: exit status 130
    ^^^^^^^^^

or with more verbosity

'build-app' failed: exit status 130

'run-app' ->
   'build-app'
    ^^^^^^^^^

Allow aliasing commands instead of running lets inside lets

Consider this

commands:
  run:
    depends: [build-img-1, build-img-2]
    cmd: echo Run

  build-img-1:
    cmd: lets _build-image first.Dockerfile


  build-img-2:
    cmd: lets _build-image second.Dockerfile


  _build-image:
    options: |
      Usage: lets _build-image <image>
    cmd: docker build . -f ${LETSOPT_IMAGE}
    

It would be more cool to not run lets-in-lets. Something like this

commands:
  run:
    depends: [build-img-1, build-img-2]
    cmd: echo Run

  build-img-1:
    ref: _build_image 
    args: first.Dockerfile


  build-img-2:
    ref: _build_image 
    args: second.Dockerfile


  _build-image:
    options: |
      Usage: lets _build-image <image>
    cmd: docker build . -f ${LETSOPT_IMAGE}

This way we do not run lets in lets, we just say - reference _build_image and pass args first.Dockerfile

Maybe it makes sense to separate this new ref commands into aliases top level directive or smth like this

Shell "bash" is not executable: No such file or directory on mac os

having example command:

shell: bash
commands:
  push:
    cmd: git push origin master

will give us an error on macOS

Shell "bash" is not executable: No such file or directory
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
failed to run command 'publish': exit status 128

Command aliases

It's quite a nice feature to have an opportunity to make command aliases/command prefix shortcuts. Sometimes lets.yaml may look like this:

shell: bash
commands:
  compile:
    description: Compilation
    cmd: docker run --rm -v ${PWD}:/go/src/app helloworld sh -c "go build -o helloworld main.go"
  format:
    description: Formatting
    cmd: docker run --rm -v ${PWD}:/go/src/app helloworld sh -c "gofmt -w -s ."
  test:
    description: Testing
    cmd: docker run --rm -v ${PWD}:/go/src/app helloworld sh -c "go test"
  lint:
    description: Linting
    cmd: docker run --rm -v ${PWD}:/go/src/app helloworld sh -c "golangci-lint run"
  run:
    description: Execution
    cmd: ./helloworld

In this case command shortcuts would shorten general commands' length, like this:

shell: bash
aliases:
  docker: docker run --rm -v ${PWD}:/go/src/app helloworld
commands:
  compile:
    description: Compilation
    cmd: @docker go build -o helloworld main.go
  format:
    description: Formatting
    cmd: @docker gofmt -w -s .
  test:
    description: Testing
    cmd: @docker go test
  lint:
    description: Linting
    cmd: @docker golangci-lint run
  run:
    description: Execution
    cmd: ./helloworld

Character @ or % or some other one can be used as a placeholder identifier.

Implement command options as map

Allow passing a map to options instead of docopts

Problems need solving:

  • required
  • key/value option
  • default value
  • value type
  • variadic option - like a list of positional args
commands:
  foo:
    options:
      debug:
        required: true

Allow to define global scoupe env vars

Sometimes I need to reuse env vars. Now I need to copy/paste envs from cmd to cmd. I want to be able to define env vars once and than access them in my commands

Allow include mixins which files is not exists

By doing this we can have own lets.my.yaml which will not be pushed to repo.

Example:

  1. touch lets.my.yaml
  2. Add lets.my.yaml to .gitignore
  3. Use lets.my.yaml in mixins.

Now user can add/override commands/env, etc. in his own lets.my.yaml.

P.s. This can be also achieved by adding new flag to lets - something like -f (similar to docker-compose approach)

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.