GithubHelp home page GithubHelp logo

cli's Introduction

@dojo/cli

Build Status Build status codecov npm version

The CLI is the officially supported way to create and maintain Dojo 2 apps.

Why use the CLI?

It is designed to save you time by promoting a standardized workflow and automating away more mundane boilerplate tasks.

Single dependency - instead of having to download and configure multiple tools such as webpack, Intern, and tslint, you can just install the CLI and know that all of these tools will work together.

Make the common tasks simple - because you don't need to install and configure the individual tools yourself, you can be sure that the versions being used all work together and they are running with sensible defaults.

Make the advanced tasks possible - you can eject to a custom setup at any time. When you eject, all the configuration and build dependencies of the included tools will be moved into your project. The development process can then be tailored to the specific needs of your project.

Usage

Prerequisites

You will need node v6+.

Installation

You can install from npm:

npm i @dojo/cli -g

In a terminal, run:

dojo

This should output the following:

dojo help

Usage: dojo <group> <command> [options]

Hey there, here are all the things you can do with @dojo/cli:
...

If you don't see the message above, then check that you have installed the CLI with the -g option.

You can list all your global npm dependencies by running:

npm list -g --depth=0

If you don't see @dojo/cli in the list of global dependencies, verify that the installation runs without errors.

Features

The CLI has the following built-in commands:

  • dojo eject - allows users to configure and run command instead of the cli.
  • dojo version - provides information on the versions of installed commands and the cli itself.
  • dojo validate - validates the .dojorc file for all installed commands

In addition to the built-in commands, additional commands are available and will show up in your command list even if they have not been installed.

  • dojo create - provides scaffolding for new Dojo 2 projects.

  • dojo build - for building Dojo 2 applications and custom elements

  • dojo test - for testing Dojo 2 applications

If you try to use a command that is not installed, the CLI will give you instructions on how to install the command.

If you need help, you can use the -h option.

# print help for the CLI, listing all available commands
$ dojo -h

# print help for a single command
$ dojo create -h

Some additional commands are available but must be installed manually via npm.

  • cli-build-webpack - Legacy Dojo2 build command.
  • cli-test-intern - Legacy Dojo2 testing command.

dojorc

Dojo CLI commands support a JSON configuration file supplied with the --dojorc option; by default, Dojo CLI will look for a file at the root of the project called .dojorc. Each command has a dedicated section in the .dojorc keyed by the command name minus the cli- prefix. For example the command @dojo/cli-build-app has the following section in the .dojorc:

{
	"build-app": {

	}
}

Each command supports different .dojorc configuration but every command supports storing command options in the .dojorc that can be overridden by explicitly passing options on the command line:

{
	"build-app": {
		"build-app-option": "foo"
	}
}

This configuration would automatically pass the build-app-option: foo to the command but is overridden by passing the option on the command line:

$ dojo build app --build-app-option bar

The .dojorc file will be validated whenever dojo validate is run or an installed command is attempted to be run.

A warning on ejecting

Once you run dojo eject, the dependencies required by the bundled tools (webpack, intern, etc.) are included into your project's package.json and the configuration is added to a config directory in your project root.

This action is one-way and you cannot go back to having the tools managed by the CLI.

How can I contribute?

We appreciate your interest! Please see the Dojo 2 Meta Repository for the Contributing Guidelines.

Code Style

This repository uses prettier for code styling rules and formatting. A pre-commit hook is installed automatically and configured to run prettier against all staged files as per the configuration in the project's package.json.

You format all src and test project files by running:

npm run prettier

Installation of source

To start working with this package, clone the repository and run npm install.

In order to build the project run npm run build or to watch files for local development run npm run watch.

Testing

Test cases MUST be written using Intern using the object test interface and assert assertion interface.

90% branch coverage MUST be provided for all code submitted to this repository, as reported by istanbul’s combined coverage results for all supported platforms.

To test locally in node run:

npm run test

Licensing information

© 2018 JS Foundation & contributors. New BSD license.

cli's People

Contributors

agubler avatar bitpshr avatar bryanforbes avatar dylans avatar jameslmilner avatar jdonaghue avatar kanefreeman avatar kitsonk avatar lzhoucs avatar maier49 avatar matt-gadd avatar mwistrand avatar nicknisi avatar rishson avatar rorticus avatar smhigley avatar steveoh avatar tomdye avatar umaar avatar vansimke 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

Watchers

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

cli's Issues

Publish the CLI interfaces

We should probably publish the CLI interfaces somewhere such that they can be used by cli commands.

At the moment a command would need to have a dependency on the cli itself in order to use it's interface and that is less than ideal.

Support multiple groups for a command

Currently a command can only provide for a single group and that group is decided by part of its package name ie dojo-cli-{groupname}-{command}.

it would be nice if in the command interface you can specify multiple groups or aliases. This is needed to support the dev task, which essentially desugars to the build task with some different arguments.

Linking with CLI

Since we agreed to drop support for building packages from source, would it make sense to have a feature that allowed linking to local packages? Either through managing npm link or some other logical fashion.

Cli executes the wrong command when multiple in group

The precedence order should favour local first, which the cli respects if you execute a command fully qualified e.g dojo build webpack. If you execute dojo build though the precedence is incorrect and the first one registered is executed.

Dojo CLI Commands

Dojo CLI Commands

Proposed commands

create

dojo create <appName>

  • Creates a new folder appName and inits a dojo2 application within.
  • Will not proceed if the folder already exists
  • Does not guide the user with a wizard
  • Scaffolds an app with recommended components

test

dojo test [local | remote]

  • Uses the intern test runner
  • Optional arguments of local and remote

run (Not MVP)

dojo run [appName]

  • Compiles code, starts http server, opens default browser
  • Watches for changes and performs live reload?

build

dojo build

  • Performs build
    • JS
    • HTML
    • CSS
  • Creates .tgz file?
  • Builds ready for deployment?
  • watch?
  • serve?

serve ??

dojo serve

  • Runs http-server and opens browser to index.html

Refactor to separate out concerns of 'tty processing', 'loading commands' and 'running commands'

I think it would improve testability if we separated the code into:

  1. tty processing using yargs
  2. installed commands resolution and loading
  3. running commands (in-built and installed)

Commands should not really be aware of their invocation context, i.e. that they are being run in a terminal.
This would make commands easier to test.
At the moment we have:
a command loader implementation (command) that knows about screen width.
a command loader (loadCommands) that knows about yargs
a command runner (registerCommands) that gets passed a command loader implementation for non-loader functionality.

I propose the following refactor:

command -> commandLoader
loadCommands -> runCommandLoader
registerCommands -> runCommands

where

index.ts is the only tty aware module
commandLoader is the only file system aware module
runCommandLoader becomes a simple loader executor
runCommands becomes a simple command executor
in-built commands become async commands in a /commands subdir and simply get added to the list of commands to run.
command specific text is kept with the command, rather than collected up into a cross-command text.ts file.
split commnds/version into the Command and the outdated check.

In addition, unit tests contain a test for index.ts. This is actually a functional test and should be moved into a function test dir, and should be tested against without mocks.

I think this is a cleaner separation of concerns that should be easier to test and extend.

build command

Implement the build command:

dojo build

Building [app name].

dojo build corporate - i.e. non FOSS build task

@rishson commented on Wed Sep 07 2016

The app needs to have a proper build step that produces a production version that is compressed, minified (maybe inlined) and obfuscated.


@kitsonk commented on Wed Sep 07 2016

obfuscated

Why?

compressed

What did you have in mind for this? Usually compression happens via the HTTP server, right?

(maybe inlined)

What did you have in mind for this? Are you suggesting bundled/concatenated into a single file? I would say that we should have a build the produces at least a base plus at least one layer/dynamically loaded bundle to prove out the build theories.


@rishson commented on Wed Sep 07 2016

Yep - I'm just thinking of the classic build steps. You're right, compression should really be minification in this example. You'd want to obfuscate so its harder to 'borrow' parts of your app, and minifiy for perf reasons. I agree about creating a layer file to test the build.


@rishson commented on Wed Sep 07 2016

Later on, we can do more advanced build steps, image compression, sprite generation from base images (for app icons etc), css minification...


@kitsonk commented on Wed Sep 07 2016

You'd want to obfuscate so its harder to 'borrow' parts of your app...

While I understand the potential corporate requirements for such things, I find that in open source software, promoting such practices as morally objectionable personally. Of course people are going to use obfuscators, but I think it really sends the wrong message if we actively enable or promote such activities. We get our strength from doing these sorts of things out in the open, and while we have chosen licensing that doesn't "infect" others with our philosophy (e.g. the GPL), I would prefer not to condone such practices.


@rishson commented on Wed Sep 07 2016

Depends who the majority users of D2 will be. If corporates, then they would expect some kind of uglification, because their app won't be FOSS. The more philosophical question is "is D2 FOSS that helps people primarily write FOSS, or closed source?" We can be both, but the build should default to one or the other. FWIW, the only closed source build steps I can think of right now are uglify and add license header to built assets.


@rishson commented on Wed Sep 07 2016

Maybe the build defaults to FOSS and we add an extra cli module that targets closed source? It could uglify, add license, check dependency tree for incompatible licenses ...


@kitsonk commented on Wed Sep 07 2016

UglifyJS I have no issues with, as it isn't really an obfuscator, but a minifier... To quote:

UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.

Just because that code is hard to unpick is a side-effect, versus an intent. I also would expect our build process to generate source maps though that go back to the original source for debugging purposes.

As far as "is D2 FOSS that helps people primarily write FOSS, or closed source?", my response to that Dojo Toolkit has been, and will continue to be, focused on developing open source software, which has flexible licensing that does not hinder further commercial use. I don't think we need to make a statement about the primary target of solutions written in Dojo 2. It isn't a binary decision and in my opinion isn't required to provide context to the development of Dojo 2.

We have seen many commercial organisation be able to build viable commercial business by being wholly open with their software, including Microsoft and TypeScript which we have built Dojo 2 on. Promoting or enabling patterns of being closed is not in the wider interest of the community. Actively hindering commercial reuse though, is in my opinion as closed as being closed source.

There are plenty of commercial organisation that will sell obfuscation solutions to enterprises. They are much better placed to assist organisations wishing to do so than the Dojo Toolkit.


@rishson commented on Wed Sep 07 2016

uglify -mangle -compress is very much obfuscation.
I'd agree on the sourcemaps though.

I'm fine with the default build being the best for FOSS, but still think there is a need for a more corporate focused alternative that does the tasks listed above + obfuscation.
It could be as simple as:

> uglify -mangle -compress -banner 'Some copyright statement with year indicator set automatically'
> [some check for copyleft licenses in the deployed app's dependency tree]

@rishson commented on Wed Sep 07 2016

@kitsonk I'm going to split this issue (turn this into a dojo build corporate issue, and create another issue that is the immediate build steps for the example app.

Alias "build -w" with "dev" command

Implement the run command:

[inside the application dir]
dojo run

Running [app name] on http://localhost:[somePort]

[any important run info goes here, e.g. when a watch detects changes, recompilation errors]

Lint Command (tslint)

As our configs are to be kept internally when creating an app, we should add a lint command which runs tslint with a recommended set of config and output the results.
This can then be used as part of other commands.

Initial thoughts:

  • The -eject functionality will spit out the tslint.json file
  • The initial call to dojo lint will check for the existence of a tslint.json file and call it's own eject command if it does not exist.

cli should be able to store basic config on a per command basis

Although the cli commands are designed to be mostly config free, it seems like in quite a few cases some basic preferences are desirable. An example of this would be the locale in cli-build, or the functional or unit test modes in cli-test

A command would be able to persist preferences for itself via a cli setter api - which would be then stored in a .dojorc at the project level. The command would receive preferences on load (and/or a getter api)

Allow the CLI to load esModules

Commands written in TypeScript or Babel or similar add __esModule to the module to indicate that it came from an ESM module format. When this is present, load the .default command.

version command

This should output the versions of all registered groups, e.g.

dojo version

The currently installed groups are:

build (dojo/cli-build-webpack) 0.23.121
build (someAuthor/dojo-cli-MyBuildCommand) 1.2.3
test (dojo/cli-test) 0.3.22
...

You are currently running dojo-cli 2.1.223

Users can then copy and paste this info into issues raised on GH. This allows a user to provide version information as easily as possible, thus increasing the likelihood that they will include this information in GH issues.

Add verbose mode to 'dojo version'

Under --verbose or similar, output the physical location of each installed command.
We should also update the dojo help text to include a section on command loading precedence (and add to the enhanced version command)

e.g.

$ dojo version -verbose

build (dojo-cli-build-webpack) 2.0.0 (global)
anothercommand (dojo-cli-another-command) 2.0.0 (/path/to/pwd/node_modules)

You are currently running dojo-cli 2.0.0

Command loading
------------------
Bit about where we look for commands and the resolution order...

test command

Implement the test command.

Options
None

Purpose
Runs all tests that have been created for a dojo application and outputs the results.

dojo test

Running tests..
Test results:

[test results go here]

CLI is too aggressive with empty directory detection

The cli should not include dotfiles when doing empty directory detection.

Example:

$ git init my-project
$ cd my-project
$ dojo new my-project

see Error: Directory is not empty even though all that is inside is the .git folder

Create example command for dojo-cli

To show potential users how to create a command we should create an example.
This will also help to prove the cli implementation approach.

Eject command

Our cli commands are meant to make the consumers code config free by internalising the config/config generation into the command itself. Given this, if a user needs more flexibility than the basic setup, we should allow them to "eject" those configs from the cli so they can use as a base for them to build on. This is an idea implemented in create-react-app.

The easiest way to implement this would just be to add an additional function to the command interface named eject, it is then up to the command to dump whatever config it has in files to the project.

Additional thoughts:

  • Nearly all eject commands are going to want to add dependencies to the package.json, so we might want to implement a helper to do that.
  • dojo eject seems like it should be an internal command to the cli. We don't have the concept of internal commands at the moment.

Semantics of dojo new

Currently dojo new takes a single param of appname, perhaps we should create a directory of appname.

Consider also adding dojo init which takes no params and inits a project in the current directory.

create command

Create a new application:

dojo create myApp

Creating 'myApp'..
Doing something..
Doing something else..

All done! 
Why not try running your new app: 
cd myApp
dojo run

Hide built-in groups such as 'versions` from being listed in the installed commands.

We should hide built in groups such as versions so that we see:

$ dojo
dojo help

Usage: dojo <group> <command> [options]

Hey there, here are all the things you can do with dojo-cli:

Commands:
  build    create a build of your application

Options:
  -h, --help     Show help                                             [boolean]
  -v, --version  Show version number                                   [boolean]

For more information on any of these commands just run them with '-h'.

e.g. 'dojo run -h' will give you the help for the 'run' group of commands.

instead of:

$ dojo
dojo help

Usage: dojo <group> <command> [options]

Hey there, here are all the things you can do with dojo-cli:

Commands:
  build    create a build of your application
  version  List versions of registered commands

Options:
  -h, --help     Show help                                             [boolean]
  -v, --version  Show version number                                   [boolean]

For more information on any of these commands just run them with '-h'.

e.g. 'dojo run -h' will give you the help for the 'run' group of commands.

CLI - MVP

cli is to be written in TS2 - including readOnly syntax.

Things to do first:

  • document what @matt-gadd 's poc is doing. Document how we (sitepen) will write a new command, document how a 3rd party developer will write a new command.
  • vertical slice: get create command to output its help text when dojo create -h is run.

Automagically update commands

Extends #11

We should display which commands can be updated (where a more recent version is available):

dojo version

You are currently running:

dojo-cli-build-webpack 0.23.121 (can be updated)
dojo-cli-test 0.3.22 (can be updated)
...

On dojo-cli 2.1.223

Run 'dojo update' to update all commands to the latest versions.
Run 'dojo update -h' to see all the update options.

We will need to provide dojo update alongside this feature.

Documentation and Design of CLI

Dojo CLI

Purpose

The purpose of the cli is to enable users to get up and running as quickly as possible with dojo 2. It will provide project scaffolding and tasks commonly used during the development lifecycle. The cli will work based on providing it's users with a highly opinionated project structure utilising grunt, intern, typescript and stylus.

Install

To be installed globally via

npm install -g dojo-cli

Architecture

  • The main module dojo-cli will be installed globally via npm and is essentially a task runner.
  • The tasks will live in separate modules prefixed by dojo-cli-
  • The dojo-cli module will search for tasks in the following locations:
    • dojo-cli’s node modules directory.
    • globally installed node_modules directory.
    • the consumer project's node_modules directory.
  • This order ensures that tasks installed locally will take precedence over those which are globally installed or packaged within the cli.

Registering Tasks

Tasks must implement the task API.

Task Naming

Tasks will be implemented based on a strict package naming policy. Files will be named dojo-cli-<task>-<subtask>. eg. dojo-cli-build-rjs.

  • There are no restrictions to the number or type of tasks and sub-tasks that can be registered.
  • When only one sub-task is registered for a task type, it will be rolled up, ie. registering only dojo-cli-create-app will run when you enter dojo create.
  • Registering multiple tasks of the same task type ie. dojo-cli-build-webpack and dojo-cli-build-rjs will generate two sub tasks under dojo build. They can be run with dojo build webpack and dojo build rjs respectively. Typing dojo build will display the list of available subtasks. ie.
You asked for 'build'. We found 2 'build' tasks: 'rjs' and 'webpack'.
You can run either 'dojo build rjs' or 'dojo build webpack'.

Arguments

Calling a task via dojo-cli will call the run function on the specified task. Any specified arguments will be passed through to the run function.

dojo test mocha --timeout=20000 === dojo-cli-test-mocha.run({timeout: 20000}

Default tasks (Not MVP)

Default tasks can be set using the dojo config command and are global defaults.
This could be used to define which subtask is ran when there are multiple under the same task type. ie. dojo config build.default rjs would ensure that dojo build ran the rjs task rather than showing the user available options.

Task API

description

Provides a description of the sub task to be displayed to the user.

name

Provides a name to be displayed to the user.

register

Registers the arguments that the sub task will accept and provides hints for those tasks to be displayed when --help is called.

run

The function to be ran when the task is executed. Will be passed the command line arguments.

options - Is this needed?

Updates

The CLI will inform the user when there is an update available to the dojo-cli core package.
Furthermore the user should be informed of any updates to it's installed tasks

help command

Implement the help command.

This command should aggregate all the available commands and output a list of available commands:

dojo help

Hey there, here are all the things you can do with dojo-cli:

help - shows all the available commands
create - creates a new dojo application
run - ...

For more information on any of these commands just run them with '-h',
e.g. 'dojo run -h' will give you the help for the 'run' command. 

(You are running dojo-cli 2.3.20)

It shouldn't output the full help for every command as that will get too verbose. The top level help command is basically a command discovery point.

Help options misleading when more than one command for a group

If there are more than one command for a group the options reflect just one of the commands when using the dojo group -h, this is misleading.

Example, the first help output shows the two commands available under build but the options are only valid for the dojo build.

Command: dojo build -h

dojo build

Commands:
  dojo     Build dojo2 packages
  webpack  create a build of your application

Options:
  -h, --help     Show help                                             [boolean]
  -t, --type     type of build         [choices: "dev", "dist"] [default: "dev"]
  -v, --version  Show version number                                   [boolean]

Command: dojo build webpack -h

dojo build webpack

Options:
  -h, --help     Show help                                             [boolean]
  -w, --watch    watch and serve
  -p, --port     port to serve on when using --serve                    [number]
  -v, --version  Show version number                                   [boolean]

Command: dojo build dojo -h

dojo build dojo

Options:
  -h, --help     Show help                                             [boolean]
  -t, --type     type of build         [choices: "dev", "dist"] [default: "dev"]
  -v, --version  Show version number                                   [boolean]

Fix the precedence ordering

Currently its possible to register multiple of the same command via global node_modules, the cli's node_modules, and the local projects node_modules. There is no distinguishing between what is registered when displayed either.

We should only support registering/displaying one command per namespace. And the precedence ordering should probably be: cli, global, local with local having the most precedence?

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.