Compare commits

..

No commits in common. "master" and "sdk-2.10.x" have entirely different histories.

54 changed files with 642 additions and 969 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

29
.gitignore vendored
View file

@ -3,17 +3,38 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle:
.idea/gradle.xml
.idea/libraries
# Mongo Explorer plugin:
.idea/mongoSettings.xml
## File-based project format:
*.iws
.DS_Store
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
@ -56,8 +77,4 @@ pubspec.lock
/sample_project/
sample_project/
sample-project
.dart_tool
.metals
#.vscode
#!.vscode/settings.json
.dart_tool

19
.idea/angel_cli.iml Normal file
View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/sample_project/.pub" />
<excludeFolder url="file://$MODULE_DIR$/sample_project/build" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/angel_cli.iml" filepath="$PROJECT_DIR$/.idea/angel_cli.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Controller" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="controller" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$/sample_project" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Doctor" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="doctor" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Init" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="init sample_project" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Show Help" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="--help" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Update" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="update" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Version" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="version" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

View file

@ -1,3 +0,0 @@
# Pub Ignore
.vscode

1
.travis.yml Normal file
View file

@ -0,0 +1 @@
language: dart

View file

@ -1,6 +0,0 @@
{
"files.watcherExclude": {
"**/target": true
},
"cmake.configureOnOpen": false
}

View file

@ -1,12 +0,0 @@
Primary Authors
===============
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__
Tobe has written much of the original code prior to NNBD migration. He has moved on and
is no longer involved with the project.

View file

@ -1,88 +1,8 @@
# Change Log
## 8.2.0
* Updated to `analyzer` 6.3.x
* Updated repository link
* Updated `lints` to 3.0.0
## 8.1.1
* Updated README
* Updated to logo
## 8.1.0
* Updated README
* Updated to logo
* Updated to `analyzer` 6.2.x
* Updated to support Dart SDK 3.1.x
## 8.0.0
* Required Dart SDK > 3.0.x
* Updated to `analyzer` 5.0.x
## 7.0.0
* Skipped release
## 6.0.0
* Updated Dart SDK to 2.16.x
## 5.0.0
* Skipped release
## 4.0.0
* Changed `pub` to `dart pub`
* Changed `pub build` to `dart build`
* Updated Dart SDK to 2.14.0
## 3.2.0
* Upgraded from `pedantic` to `lints` linter
## 3.1.1
* Fixed NNBD issues
## 3.1.0
* Upgraded to support `analyzer` 2.0.0
## 3.0.1
* Updated help to use `angel3`
* Updated to use `angel3` packages
* Updated screenshot
## 3.0.0
* Fixed NNBD issues
* Updated to use `angel3` packages
* Fixed incorrect import for new project
* Updated screenshot
## 3.0.0-beta.2
* Updated README
## 3.0.0-beta.1
* Migrated to work with Dart SDK 2.12.x Non NNBD
* Replaced `mustache4dart2` with `mustache_template`
* Replaced `inflection2` with `inflection3`
## 2.1.7+1
# 2.1.7+1
* Fix a bug where new directories were not being created in
`init`.
## 2.1.7
# 2.1.7
* Fix a bug where `ArgResults.arguments` was used in `init` instead of the
intended `ArgResults.rest`.
* Stop including `package:angel_model` imports in `make model`.
@ -90,45 +10,36 @@ intended `ArgResults.rest`.
* Fix `make model` to generate ORM + migration by default.
* Fix `MakerDependency` logic to print missing dependencies.
## 2.1.6
# 2.1.6
* Fix a bug where models always defaulted to ORM.
* Add GraphQL boilerplate.
* Automatically restore terminal colors on shutdown.
## 2.1.5+1
# 2.1.5+1
* Update to `inflection2`.
## 2.1.5
# 2.1.5
* Add `shared` boilerplates.
* Remove uncecessary `angel_model` imports.
## 2.1.4+1
# 2.1.4+1
* Patch `part of 'path'` renames.
## 2.1.4
# 2.1.4
* The `migration` argument to `model` just emits an annotation now.
* Add the ORM boilerplate.
## 2.1.3
# 2.1.3
* Fix generation of ORM models.
* A `--project-name` to `init` command.
## 2.1.2
# 2.1.2
* No migrations-by-default.
## 2.1.1
# 2.1.1
* Edit the way `rename` runs, leaving no corner unturned.
## 2.1.0
# 2.1.0
* Deprecate `angel install`.
* Rename projects using `snake_case`.
* `init` now fetches from `master`.
@ -137,43 +48,34 @@ intended `ArgResults.rest`.
* Replace `{{oldName}}` in the `rename` command.
* `pub get` now runs with `inheritStdio`.
## 2.0.1
# 2.0.1
* `deploy systemd` now has an `--install` option, where you can immediately
spawn the service.
## 2.0.0
# 2.0.0
* `init` can now produce either 1.x or 2.x projects.
* Fixed deps for compatibility with Dart2 stable.
## 1.3.4
# 1.3.4
* Fix another typo.
## 1.3.3
# 1.3.3
* Fix a small typo in the model generator.
## 1.3.2
# 1.3.2
* Restore `part` directives in generated models.
## 1.3.1
# 1.3.1
* Add `deploy nginx` and `deploy systemd`.
## 1.3.0
# 1.3.0
* Focus on Dart2 from here on out.
* Update `code_builder`.
* More changes...
## 1.1.5
# 1.1.5
Deprecated several commands, in favor of the `make`
command:
* `controller`
* `plugin`
* `service`

42
LICENSE
View file

@ -1,29 +1,21 @@
BSD 3-Clause License
MIT License
Copyright (c) 2021, dukefirehawk.com
All rights reserved.
Copyright (c) [year] [fullname]
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,31 +1,26 @@
# Angel3 CLI
# angel_cli
[![Angel3 Logo](angel3_logo.png)](https://github.com/dart-backend/angel3-cli)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_cli?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dart-backend/angel3-cli)](https://github.com/dart-backend/angel3-cli/blob/master/LICENSE)
The command line interface for buidling dart backend in [Angel3 framework](https://pub.dev/packages/angel3_framework) that provides the following functionalities:
![Screenshot of Terminal](screenshots/screenshot.png)
Command-line tools for the Angel framework.
Includes functionality such as:
* Project scaffolding
* Generating service models, plugins, tests and more
* Renaming projects
* Much more...
## Installation
* To install:
```bash
dart pub global activate angel3_cli
$ pub global activate angel_cli
```
## Help
* Install development version
`dart pub global activate --source path ./packages/cli`
`dart pub global activate --source git https://github.com/dukefirehawk/angel/packages/cli`
For information on the available options:
And then, for information on each command:
```bash
angel3 help
$ angel help
```
[![Screenshot of Terminal](screenshots/angel3-screenshot.png)](https://github.com/dart-backend/angel3-cli)

7
TODO.md Normal file
View file

@ -0,0 +1,7 @@
# Todo
* `service`
* Add tests
* `migration`
* `deploy`
* Call these from Grinder script :)

View file

@ -1 +1,3 @@
include: package:lints/recommended.yaml
analyzer:
strong-mode:
implicit-casts: false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -1,135 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="128"
height="128"
viewBox="0 0 128 128"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed, 2023-07-21)"
sodipodi:docname="logo128.svg"
inkscape:export-filename="logo_icon_128.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="true"
inkscape:zoom="1.5862247"
inkscape:cx="58.629776"
inkscape:cy="90.466375"
inkscape:window-width="1312"
inkscape:window-height="738"
inkscape:window-x="128"
inkscape:window-y="111"
inkscape:window-maximized="0"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1">
<linearGradient
id="linearGradient15"
inkscape:collect="always">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop15" />
<stop
style="stop-color:#d81c1c;stop-opacity:0;"
offset="1"
id="stop16" />
</linearGradient>
<linearGradient
id="swatch13"
inkscape:swatch="solid">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop14" />
</linearGradient>
<linearGradient
id="swatch7"
inkscape:swatch="solid">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop7" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#swatch13"
id="linearGradient14"
x1="76.307388"
y1="264.40897"
x2="425.84061"
y2="264.40897"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15"
id="linearGradient16"
x1="185.07693"
y1="354.51111"
x2="296.18161"
y2="354.51111"
gradientUnits="userSpaceOnUse" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:137.557px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;opacity:1;fill:#d81c1c;fill-opacity:1;stroke-width:0.716443"
x="13.382875"
y="114.63321"
id="text1"
transform="scale(1.0161156,0.98414)"><tspan
sodipodi:role="line"
id="tspan1"
x="13.382875"
y="114.63321"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:137.557px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#d81c1c;fill-opacity:1;stroke-width:0.716443">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:54.9757px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;opacity:1;fill:#d81c1c;fill-opacity:1;stroke:#ffffff;stroke-width:0.725;stroke-dasharray:none;stroke-opacity:1"
x="44.028919"
y="108.3848"
id="text2"
transform="scale(1.1577238,0.86376387)"><tspan
sodipodi:role="line"
id="tspan2"
x="44.028919"
y="108.3848"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:54.9757px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#d81c1c;fill-opacity:1;stroke:#ffffff;stroke-width:0.725;stroke-dasharray:none;stroke-opacity:1">3</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

55
bin/angel.dart Normal file
View file

@ -0,0 +1,55 @@
#!/usr/bin/env dart
library angel_cli.tool;
import "dart:io";
import "package:args/command_runner.dart";
import 'package:angel_cli/angel_cli.dart';
import 'package:io/ansi.dart';
final String DOCTOR = "doctor";
main(List<String> args) async {
var runner = new CommandRunner(
"angel",
asciiArt.trim() +
'\n\n' +
"Command-line tools for the Angel framework." +
'\n\n' +
'https://angel-dart.github.io');
runner.argParser
.addFlag('verbose', help: 'Print verbose output.', negatable: false);
runner
..addCommand(new DeployCommand())
..addCommand(new DoctorCommand())
..addCommand(new KeyCommand())
..addCommand(new InitCommand())
..addCommand(new InstallCommand())
..addCommand(new RenameCommand())
..addCommand(new MakeCommand());
return await runner.run(args).catchError((exc, st) {
if (exc is String) {
stdout.writeln(exc);
} else {
stderr.writeln("Oops, something went wrong: $exc");
if (args.contains('--verbose')) {
stderr.writeln(st);
}
}
exitCode = 1;
}).whenComplete(() {
stdout.write(resetAll.wrap(''));
});
}
const String asciiArt = '''
____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \____/ /_____/ /_____/
''';

View file

@ -1,76 +0,0 @@
#!/usr/bin/env dart
library angel3_cli.tool;
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:angel3_cli/angel3_cli.dart';
import 'package:io/ansi.dart';
void main(List<String> args) async {
var runner = CommandRunner('angel3',
'$asciiArt\n\nCommand-line tools for the Angel3 framework.\n\nhttps://angel3-framework.web.app');
runner.argParser
.addFlag('verbose', help: 'Print verbose output.', negatable: false);
runner
..addCommand(DeployCommand())
..addCommand(DoctorCommand())
..addCommand(KeyCommand())
..addCommand(InitCommand())
// ..addCommand(InstallCommand())
..addCommand(RenameCommand())
..addCommand(MakeCommand());
await runner.run(args).catchError((exc, st) {
if (exc is String) {
stdout.writeln(exc);
} else {
stderr.writeln('Oops, something went wrong: $exc');
if (args.contains('--verbose')) {
stderr.writeln(st);
}
}
exitCode = 1;
}).whenComplete(() {
stdout.write(resetAll.wrap(''));
});
}
const String asciiArt2 = '''
___ _ ________________ _____
/ | / | / / ____/ ____/ / |__ /
/ /| | / |/ / / __/ __/ / / /_ <
/ ___ |/ /| / /_/ / /___/ /______/ /
/_/ |_/_/ |_/\\____/_____/_____/____/
''';
const String asciiArt = '''
_ _ _ ____ _____ _ _____
/ \\ | \\ | |/ ___| ____| | |___ /
/ _ \\ | \\| | | _| _| | | |_ \\
/ ___ \\| |\\ | |_| | |___| |___ ___) |
/_/ \\_\\_| \\_|\\____|_____|_____|____/
''';
const String asciiArt3 = '''
\\ \\ | ___| ____| | ___ /
_ \\ \\ | | __| | _ \\
___ \\ |\\ | | | | | ) |
_/ _\\ _| \\_| \\____| _____| _____| ____/
''';
const String asciiArtOld = '''
____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \\____/ /_____/ /_____/
''';

View file

@ -1,3 +1,3 @@
library angel3_cli;
library angel_cli;
export 'src/commands/commands.dart';

View file

@ -1,9 +1,9 @@
library angel3_cli.commands;
library angel_cli.commands;
export 'deploy.dart';
export 'doctor.dart';
export 'key.dart';
export 'init.dart';
export 'install.dart';
export 'make.dart';
export 'rename.dart';
export "deploy.dart";
export "doctor.dart";
export "key.dart";
export "init.dart";
export "install.dart";
export "make.dart";
export "rename.dart";

View file

@ -20,7 +20,7 @@ class NginxCommand extends Command {
}
@override
Future run() async {
run() async {
var webPath = p.join(p.current, 'web');
var nginxText = '''
server {
@ -28,7 +28,7 @@ server {
root ${p.absolute(webPath)}; # Set to your static files directory
location / {
try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel3 server
try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel server
}
location @proxy {
@ -39,10 +39,10 @@ server {
'''
.trim();
if (!argResults!.wasParsed('out')) {
if (!argResults.wasParsed('out')) {
print(nginxText);
} else {
var file = File(argResults!['out'] as String);
var file = new File(argResults['out'] as String);
await file.create(recursive: true);
await file.writeAsString(nginxText);
print(green.wrap(

View file

@ -27,10 +27,10 @@ class SystemdCommand extends Command {
}
@override
Future run() async {
run() async {
var projectPath = p.absolute(p.current);
var pubspec = await loadPubspec();
var user = argResults?['user'];
var user = argResults['user'];
var systemdText = '''
[Unit]
Description=`${pubspec.name}` server
@ -47,16 +47,15 @@ WantedBy=multi-user.target
'''
.trim();
if (argResults?.wasParsed('out') != true &&
argResults?.wasParsed('install') != true) {
if (!argResults.wasParsed('out') && !argResults.wasParsed('install')) {
print(systemdText);
} else if (argResults?.wasParsed('install') == true) {
var systemdPath = argResults?.wasParsed('out') == true
? (argResults?['out'] as String)
} else if (argResults.wasParsed('install')) {
var systemdPath = argResults.wasParsed('out')
? argResults['out'] as String
: p.join('etc', 'systemd', 'system');
var serviceFilename = p.join(systemdPath,
p.setExtension(argResults?['install'] as String, '.service'));
var file = File(serviceFilename);
p.setExtension(argResults['install'] as String, '.service'));
var file = new File(serviceFilename);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(
@ -77,7 +76,7 @@ WantedBy=multi-user.target
print(red.wrap('$ballot Failed to install service system-wide.'));
}
} else {
var file = File(argResults?['out'] as String);
var file = new File(argResults['out'] as String);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(

View file

@ -1,35 +1,34 @@
import 'dart:convert';
import 'dart:io';
import 'package:args/command_runner.dart';
import "dart:convert";
import "dart:io";
import "package:args/command_runner.dart";
import 'package:io/ansi.dart';
import '../util.dart';
class DoctorCommand extends Command {
@override
String get name => 'doctor';
String get name => "doctor";
@override
String get description =>
'Ensures that the current system is capable of running Angel3.';
"Ensures that the current system is capable of running Angel.";
@override
Future run() async {
print('Checking your system for dependencies...');
run() async {
print("Checking your system for dependencies...");
await _checkForGit();
}
Future _checkForGit() async {
_checkForGit() async {
try {
var git = await Process.start('git', ['--version']);
var git = await Process.start("git", ["--version"]);
if (await git.exitCode == 0) {
var version = await git.stdout.transform(utf8.decoder).join();
print(green.wrap(
"$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}"));
} else {
throw Exception('Git executable exit code not 0');
}
} else
throw Exception("Git executable exit code not 0");
} catch (exc) {
print(red.wrap('$ballot Git executable not found'));
print(red.wrap("$ballot Git executable not found"));
}
}
}

View file

@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'package:args/command_runner.dart';
import "dart:io";
import "package:args/command_runner.dart";
import 'package:io/ansi.dart';
import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts;
@ -8,17 +8,18 @@ import 'package:recase/recase.dart';
import '../random_string.dart' as rs;
import '../util.dart';
import 'key.dart';
import 'pub.dart';
import 'rename.dart';
class InitCommand extends Command {
final KeyCommand _key = KeyCommand();
@override
String get name => 'init';
String get name => "init";
@override
String get description =>
'Initializes a new Angel3 project in the current directory.';
"Initializes a new Angel project in the current directory.";
InitCommand() {
argParser
@ -32,15 +33,10 @@ class InitCommand extends Command {
}
@override
void run() async {
if (argResults == null) {
print('Invalid arguements');
return;
}
var projectDir =
Directory(argResults!.rest.isEmpty ? '.' : argResults!.rest[0]);
print('Creating new Angel3 project in ${projectDir.absolute.path}...');
run() async {
Directory projectDir =
Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]);
print("Creating new Angel project in ${projectDir.absolute.path}...");
await _cloneRepo(projectDir);
// await preBuild(projectDir);
var secret = rs.randomAlphaNumeric(32);
@ -53,8 +49,8 @@ class InitCommand extends Command {
await _key.changeSecret(
File.fromUri(projectDir.uri.resolve('config/production.yaml')), secret);
var name = argResults!.wasParsed('project-name')
? (argResults!['project-name'] as String)
var name = argResults.wasParsed('project-name')
? argResults['project-name'] as String
: p.basenameWithoutExtension(
projectDir.absolute.uri.normalizePath().toFilePath());
@ -62,57 +58,50 @@ class InitCommand extends Command {
print('Renaming project from "angel" to "$name"...');
await renamePubspec(projectDir, 'angel', name);
await renameDartFiles(projectDir, 'angel', name);
// Renaming executable files
if (argResults!['pub-get'] != false && argResults!['offline'] == false) {
print('Now running dart pub get...');
if (argResults['pub-get'] != false && argResults['offline'] == false) {
print('Now running pub get...');
await _pubGet(projectDir);
}
print(green.wrap('$checkmark Successfully initialized Angel3 project.'));
print(green.wrap("$checkmark Successfully initialized Angel project."));
stdout
..writeln()
..writeln(
'Congratulations! You are ready to start developing with Angel3!')
'Congratulations! You are ready to start developing with Angel!')
..write('To start the server (with ')
..write(cyan.wrap('hot-reloading'))
..write('), run ')
..write(magenta.wrap('`dart --observe bin/dev.dart`'))
..writeln(' in your terminal.')
..writeln()
..writeln('Find more documentation about Angel3:')
..writeln(' * https://angel3-framework.web.app')
..writeln(' * https://angel3-docs.dukefirehawk.com')
// ..writeln(
// ' * https://www.youtube.com/playlist?list=PLl3P3tmiT-frEV50VdH_cIrA2YqIyHkkY')
// ..writeln(' * https://medium.com/the-angel-framework')
// ..writeln(' * https://dart.academy/tag/angel')
..writeln('Find more documentation about Angel:')
..writeln(' * https://angel-dart.github.io')
..writeln(' * https://github.com/angel-dart/angel/wiki')
..writeln(
' * https://www.youtube.com/playlist?list=PLl3P3tmiT-frEV50VdH_cIrA2YqIyHkkY')
..writeln(' * https://medium.com/the-angel-framework')
..writeln(' * https://dart.academy/tag/angel')
..writeln()
..writeln('Happy coding!');
}
Future _deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
_deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
if (entity is Directory) {
await for (var entity in entity.list(recursive: true)) {
try {
await _deleteRecursive(entity);
} catch (e) {
print(e);
}
} catch (e) {}
}
try {
if (self != false) await entity.delete(recursive: true);
} catch (e) {
print(e);
}
} catch (e) {}
} else if (entity is File) {
try {
await entity.delete(recursive: true);
} catch (e) {
print(e);
}
} catch (e) {}
} else if (entity is Link) {
var path = await entity.resolveSymbolicLinks();
var stat = await FileStat.stat(path);
@ -128,49 +117,42 @@ class InitCommand extends Command {
}
}
Future _cloneRepo(Directory projectDir) async {
Directory boilerplateDir = Directory("./empty");
_cloneRepo(Directory projectDir) async {
Directory boilerplateDir;
try {
if (await projectDir.exists()) {
var shouldDelete = prompts.getBool(
"Directory '${projectDir.absolute.path}' already exists. Overwrite it?");
if (!shouldDelete) {
throw 'Chose not to overwrite existing directory.';
} else if (projectDir.absolute.uri.normalizePath().toFilePath() !=
Directory.current.absolute.uri.normalizePath().toFilePath()) {
if (!shouldDelete)
throw "Chose not to overwrite existing directory.";
else if (projectDir.absolute.uri.normalizePath().toFilePath() !=
Directory.current.absolute.uri.normalizePath().toFilePath())
await projectDir.delete(recursive: true);
} else {
else {
await _deleteRecursive(projectDir, false);
}
}
// var boilerplate = basicBoilerplate;
print('Choose a project type before continuing:');
var boilerplate = prompts.choose(
'Choose a project type before continuing', boilerplates) ??
basicBoilerplate;
'Choose a project type before continuing', boilerplates);
// Ultimately, we want a clone of every boilerplate locally on the system.
var boilerplateRootDir = Directory(p.join(angelDir.path, 'boilerplates'));
var boilerplateBasename = p.basenameWithoutExtension(boilerplate.url);
if (boilerplate.ref != '') {
boilerplateBasename += '.${boilerplate.ref}';
}
if (boilerplate.ref != null) boilerplateBasename += '.${boilerplate.ref}';
boilerplateDir =
Directory(p.join(boilerplateRootDir.path, boilerplateBasename));
await boilerplateRootDir.create(recursive: true);
var branch = boilerplate.ref;
if (branch == '') {
branch = 'master';
}
var branch = boilerplate.ref ?? 'master';
// If there is no clone existing, clone it.
if (!await boilerplateDir.exists()) {
if (argResults!['offline'] as bool) {
if (argResults['offline'] as bool) {
throw Exception(
'--offline was selected, but the "${boilerplate.name}" boilerplate has not yet been downloaded.');
}
@ -179,15 +161,15 @@ class InitCommand extends Command {
'Cloning "${boilerplate.name}" boilerplate from "${boilerplate.url}"...');
Process git;
if (boilerplate.ref == '') {
if (boilerplate.ref == null) {
print(darkGray.wrap(
'\$ git clone --depth 1 ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start(
'git',
"git",
[
'clone',
'--depth',
'1',
"clone",
"--depth",
"1",
boilerplate.url,
boilerplateDir.absolute.path
],
@ -198,13 +180,13 @@ class InitCommand extends Command {
print(darkGray.wrap(
'\$ git clone --depth 1 --single-branch -b ${boilerplate.ref} ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start(
'git',
"git",
[
'clone',
'--depth',
'1',
'--single-branch',
'-b',
"clone",
"--depth",
"1",
"--single-branch",
"-b",
boilerplate.ref,
boilerplate.url,
boilerplateDir.absolute.path
@ -214,19 +196,19 @@ class InitCommand extends Command {
}
if (await git.exitCode != 0) {
throw Exception('Could not clone repo.');
throw Exception("Could not clone repo.");
}
}
// Otherwise, pull from git.
else if (!(argResults!['offline'] as bool)) {
else if (!(argResults['offline'] as bool)) {
print(darkGray.wrap('\$ git pull origin $branch'));
var git = await Process.start('git', ['pull', 'origin', branch],
var git = await Process.start("git", ['pull', 'origin', '$branch'],
mode: ProcessStartMode.inheritStdio,
workingDirectory: boilerplateDir.absolute.path);
if (await git.exitCode != 0) {
print(yellow.wrap(
'Update of $branch failed. Attempting to continue with existing contents.'));
"Update of $branch failed. Attempting to continue with existing contents."));
}
} else {
print(darkGray.wrap(
@ -240,39 +222,37 @@ class InitCommand extends Command {
await preBuild(projectDir).catchError((_) => null);
}
var gitDir = Directory.fromUri(projectDir.uri.resolve('.git'));
var gitDir = Directory.fromUri(projectDir.uri.resolve(".git"));
if (await gitDir.exists()) await gitDir.delete(recursive: true);
} catch (e) {
await boilerplateDir.delete(recursive: true);
//await boilerplateDir.delete(recursive: true).catchError((e) {
// print('Got error: ${e.error}');
//});
await boilerplateDir.delete(recursive: true).catchError((_) => null);
if (e is! String) {
print(red.wrap('$ballot Could not initialize Angel3 project.'));
print(red.wrap("$ballot Could not initialize Angel project."));
}
rethrow;
}
}
Future _pubGet(Directory projectDir) async {
var dartPath = "dart";
print(darkGray.wrap('Running "$dartPath"...'));
print(darkGray.wrap('\$ $dartPath pub get'));
var dart = await Process.start(dartPath, ['pub', 'get'],
_pubGet(Directory projectDir) async {
var pubPath = resolvePub();
print(darkGray.wrap('Running pub at "$pubPath"...'));
print(darkGray.wrap('\$ $pubPath get'));
var pub = await Process.start(pubPath, ["get"],
workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio);
var code = await dart.exitCode;
print('Dart process exited with code $code');
var code = await pub.exitCode;
print("Pub process exited with code $code");
}
}
Future preBuild(Directory projectDir) async {
// Run build
// print('Running `dart run build_runner build`...');
print(darkGray.wrap('\$ dart run build_runner build'));
// print('Running `pub run build_runner build`...');
print(darkGray.wrap('\$ pub run build_runner build'));
var build = await Process.start("dart", ['run', 'build_runner', 'build'],
var build = await Process.start(
resolvePub(), ['run', 'build_runner', 'build'],
workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio);
@ -281,63 +261,63 @@ Future preBuild(Directory projectDir) async {
if (buildCode != 0) throw Exception('Failed to pre-build resources.');
}
const repoLocation = 'https://github.com/dart-backend';
const RepoArchiveLocation = "https://github.com/angel-dart";
const RepoLocation = "https://github.com/dukefirehawk";
const BoilerplateInfo graphQLBoilerplate = BoilerplateInfo(
const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo(
'GraphQL',
'A starter application with GraphQL support.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-graphql',
"A starting point for GraphQL API servers.",
'${RepoLocation}/boilerplates.git',
ref: 'graphql-sdk-2.12.x',
);
const BoilerplateInfo ormBoilerplate = BoilerplateInfo(
'ORM for PostgreSQL',
'A starter application with ORM support for PostgreSQL.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-orm',
const BoilerplateInfo ormBoilerplate = const BoilerplateInfo(
'ORM',
"A starting point for applications that use Angel's ORM.",
'${RepoLocation}/boilerplates.git',
ref: 'orm-sdk-2.12.x',
);
const BoilerplateInfo ormMySqlBoilerplate = BoilerplateInfo(
'ORM for MySQL/MariaDB',
'A starter application with ORM support for MySQL/MariaDB.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-orm-mysql',
);
const BoilerplateInfo basicBoilerplate = BoilerplateInfo(
const BoilerplateInfo basicBoilerplate = const BoilerplateInfo(
'Basic',
'A basic starter application with minimal packages.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-basic');
'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.',
'${RepoLocation}/boilerplates.git',
ref: 'basic-sdk-2.12.x');
const BoilerplateInfo sharedBoilerplate = BoilerplateInfo(
const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo(
'Legacy',
'Minimal starting point for applications running Angel 1.1.x.',
'${RepoArchiveLocation}/angel.git',
ref: '1.1.x',
);
const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo(
'Shared',
'Holds common models and files shared across multiple Dart projects.',
'$repoLocation/boilerplate_shared.git');
'${RepoLocation}/boilerplate_shared.git');
const BoilerplateInfo sharedOrmBoilerplate = BoilerplateInfo(
const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo(
'Shared (ORM)',
'Holds common models and files shared across multiple Dart projects.',
'$repoLocation/boilerplate_shared.git',
'${RepoLocation}/boilerplate_shared.git',
ref: 'orm',
);
const List<BoilerplateInfo> boilerplates = [
const List<BoilerplateInfo> boilerplates = const [
basicBoilerplate,
//legacyBoilerplate,
ormBoilerplate,
ormMySqlBoilerplate,
graphQLBoilerplate,
//sharedBoilerplate,
//sharedOrmBoilerplate,
];
class BoilerplateInfo {
final String name, description, url;
final String ref;
final String name, description, url, ref;
final bool needsPrebuild;
const BoilerplateInfo(this.name, this.description, this.url,
{this.ref = '', this.needsPrebuild = false});
{this.ref, this.needsPrebuild: false});
@override
String toString() => '$name ($description)';

View file

@ -3,8 +3,7 @@ import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:glob/glob.dart';
import 'package:io/ansi.dart';
//import 'package:mustache4dart2/mustache4dart2.dart' as mustache;
import 'package:mustache_template/mustache_template.dart' as mustache;
import 'package:mustache4dart2/mustache4dart2.dart' as mustache;
import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart';
@ -12,7 +11,6 @@ import 'package:yaml/yaml.dart' as yaml;
import '../util.dart';
import 'make/maker.dart';
@Deprecated("No longer needed")
class InstallCommand extends Command {
static const String repo = 'https://github.com/angel-dart/install.git';
static final Directory installRepo =
@ -48,66 +46,62 @@ class InstallCommand extends Command {
}
@override
Future run() async {
run() async {
print(yellow.wrap(
'WARNING: The `install` command is no longer considered necessary, and has been deprecated.\n'
'Expect it to be removed in an upcoming release.\n\n'
'See here: https://github.com/angel-dart/install.git\n\n'
'To stop seeing this, downgrade to `package:angel_cli@<=2.0.0`.'));
if (argResults?['wipe'] as bool) {
if (argResults['wipe'] as bool) {
if (await installRepo.exists()) await installRepo.delete(recursive: true);
} else if (argResults?['list'] as bool) {
} else if (argResults['list'] as bool) {
var addons = await list();
print('${addons.length} add-on(s) installed:');
for (var addon in addons) {
print(' * ${addon.name}@${addon.version}: ${addon.description}');
}
} else if (argResults?['update'] as bool) {
} else if (argResults['update'] as bool) {
await update();
} else if (argResults!.rest.isNotEmpty) {
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel3 install --update` first.';
}
} else if (argResults.rest.isNotEmpty) {
if (!await installRepo.exists())
throw 'No local add-on database exists. Run `angel install --update` first.';
var pubspec = await loadPubspec();
for (var packageName in argResults?.rest ?? <String>[]) {
for (var packageName in argResults.rest) {
var packageDir =
Directory.fromUri(installRepo.uri.resolve(packageName));
if (!await packageDir.exists()) {
throw 'No add-on named "$packageName" is installed. You might need to run `angel3 install --update`.';
}
if (!await packageDir.exists())
throw 'No add-on named "$packageName" is installed. You might need to run `angel install --update`.';
print('Installing $packageName...');
var values = {
Map values = {
'project_name': pubspec.name,
'pubspec': pubspec,
};
var globs = <Glob>[];
List<Glob> globs = [];
var projectPubspec = await loadPubspec(packageDir);
var deps = projectPubspec.dependencies.keys
.map((k) {
var dep = projectPubspec.dependencies[k];
if (dep is HostedDependency) {
if (dep is HostedDependency)
return MakerDependency(k, dep.version.toString());
}
return null;
})
.whereType<MakerDependency>()
.where((d) => d != null)
.toList();
deps.addAll(projectPubspec.devDependencies.keys.map((k) {
var dep = projectPubspec.devDependencies[k];
if (dep is HostedDependency) {
if (dep is HostedDependency)
return MakerDependency(k, dep.version.toString(), dev: true);
}
return null;
}).whereType<MakerDependency>());
}).where((d) => d != null));
await depend(deps);
@ -131,11 +125,11 @@ class InstallCommand extends Command {
var desc = val[key]['description'] ?? key;
if (val[key]['type'] == 'prompt') {
values[key as String] = prompts.get(desc.toString(),
values[key] = prompts.get(desc.toString(),
defaultsTo: val[key]['default']?.toString());
} else if (val[key]['type'] == 'choice') {
values[key as String] = prompts.choose(desc.toString(),
(val[key]['choices'] as Iterable) as Iterable<Object>)!;
values[key] = prompts.choose(
desc.toString(), val[key]['choices'] as Iterable);
}
}
}
@ -157,7 +151,7 @@ class InstallCommand extends Command {
var name = p.basename(entity.path);
var target = dst.uri.resolve(name);
var targetFile = File.fromUri(target);
var allClear = !await targetFile.exists();
bool allClear = !await targetFile.exists();
if (!allClear) {
print('The file ${entity.absolute.path} already exists.');
@ -173,10 +167,8 @@ class InstallCommand extends Command {
print(
'Rendering Mustache template from ${entity.absolute.path} to ${targetFile.absolute.path}...');
var contents = await entity.readAsString();
//var renderer = mustache.compile(contents);
//var generated = renderer(values);
var template = mustache.Template(contents);
var generated = template.renderString(values);
var renderer = mustache.compile(contents);
var generated = renderer(values);
await targetFile.writeAsString(generated.toString());
} else {
print(
@ -205,9 +197,9 @@ class InstallCommand extends Command {
Future<List<Pubspec>> list() async {
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel3 install --update` first.';
throw 'No local add-on database exists. Run `angel install --update` first.';
} else {
var repos = <Pubspec>[];
List<Pubspec> repos = [];
await for (var entity in installRepo.list()) {
if (entity is Directory) {
@ -244,9 +236,7 @@ class InstallCommand extends Command {
);
}
git
..stdout.listen(stdout.add)
..stderr.listen(stderr.add);
git..stdout.listen(stdout.add)..stderr.listen(stderr.add);
var code = await git.exitCode;

View file

@ -7,10 +7,10 @@ class KeyCommand extends Command {
String get name => 'key';
@override
String get description => 'Generates a new `angel3_auth` key.';
String get description => 'Generates a new `angel_auth` key.';
@override
Future run() async {
run() async {
var secret = rs.randomAlphaNumeric(32);
print('Generated new development JWT secret: $secret');
await changeSecret(File('config/default.yaml'), secret);
@ -20,11 +20,11 @@ class KeyCommand extends Command {
await changeSecret(File('config/production.yaml'), secret);
}
Future changeSecret(File file, String secret) async {
changeSecret(File file, String secret) async {
if (await file.exists()) {
var contents = await file.readAsString();
contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), '');
await file.writeAsString('${contents.trim()}\njwt_secret: "$secret"');
await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"');
}
}
}

View file

@ -30,60 +30,59 @@ class ControllerCommand extends Command {
}
@override
Future run() async {
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults!['name'] as String?;
}
run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompts.get('Name of controller class');
}
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
];
//${pubspec.name}.src.models.${rc.snakeCase}
var rc = ReCase(name!);
var controllerLib = Library((controllerLib) {
if (argResults?['websocket'] as bool) {
deps.add(const MakerDependency('angel3_websocket', '^7.0.0'));
var rc = new ReCase(name);
var controllerLib = new Library((controllerLib) {
if (argResults['websocket'] as bool) {
deps.add(const MakerDependency('angel_websocket', '^2.0.0'));
controllerLib.directives
.add(Directive.import('package:angel3_websocket/server.dart'));
.add(new Directive.import('package:angel_websocket/server.dart'));
} else {
controllerLib.directives.add(
Directive.import('package:angel3_framework/angel3_framework.dart'));
controllerLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
}
controllerLib.body.add(Class((clazz) {
controllerLib.body.add(new Class((clazz) {
clazz
..name = '${rc.pascalCase}Controller'
..extend = refer(argResults?['websocket'] as bool
..extend = refer(argResults['websocket'] as bool
? 'WebSocketController'
: 'Controller');
if (argResults!['websocket'] as bool) {
if (argResults['websocket'] as bool) {
// XController(AngelWebSocket ws) : super(ws);
clazz.constructors.add(Constructor((b) {
clazz.constructors.add(new Constructor((b) {
b
..requiredParameters.add(Parameter((b) => b
..requiredParameters.add(new Parameter((b) => b
..name = 'ws'
..type = refer('AngelWebSocket')))
..initializers.add(Code('super(ws)'));
..initializers.add(new Code('super(ws)'));
}));
clazz.methods.add(Method((meth) {
clazz.methods.add(new Method((meth) {
meth
..name = 'hello'
..returns = refer('void')
..annotations
.add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')]))
..requiredParameters.add(Parameter((b) => b
..requiredParameters.add(new Parameter((b) => b
..name = 'socket'
..type = refer('WebSocketContext')))
..body = Block((block) {
..body = new Block((block) {
block.addExpression(refer('socket').property('send').call([
literal('got_${rc.snakeCase}'),
literalMap({'message': literal('Hello, world!')}),
@ -94,7 +93,7 @@ class ControllerCommand extends Command {
clazz
..annotations
.add(refer('Expose').call([literal('/${rc.snakeCase}')]))
..methods.add(Method((meth) {
..methods.add(new Method((meth) {
meth
..name = 'hello'
..returns = refer('String')
@ -107,15 +106,14 @@ class ControllerCommand extends Command {
}));
});
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
var outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var controllerFile =
File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists()) {
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists())
await controllerFile.create(recursive: true);
}
await controllerFile.writeAsString(
DartFormatter().format(controllerLib.accept(DartEmitter()).toString()));
await controllerFile.writeAsString(new DartFormatter()
.format(controllerLib.accept(new DartEmitter()).toString()));
print(green.wrap(
'$checkmark Created controller file "${controllerFile.absolute.path}"'));

View file

@ -6,7 +6,7 @@ class MakerDependency implements Comparable<MakerDependency> {
final String name, version;
final bool dev;
const MakerDependency(this.name, this.version, {this.dev = false});
const MakerDependency(this.name, this.version, {this.dev: false});
@override
int compareTo(MakerDependency other) => name.compareTo(other.name);
@ -18,11 +18,10 @@ Future depend(Iterable<MakerDependency> deps) async {
for (var dep in deps) {
var isPresent = false;
if (dep.dev) {
if (dep.dev)
isPresent = pubspec.devDependencies.containsKey(dep.name);
} else {
else
isPresent = pubspec.dependencies.containsKey(dep.name);
}
if (!isPresent) {
missing.add(dep);
@ -52,11 +51,11 @@ Future depend(Iterable<MakerDependency> deps) async {
print(yellow.wrap(
'Update your `pubspec.yaml` to add the following dependencies:\n'));
void printMissing(String type, Iterable<MakerDependency?> deps) {
void printMissing(String type, Iterable<MakerDependency> deps) {
if (deps.isNotEmpty) {
print(yellow.wrap(' $type:'));
for (var dep in deps) {
print(yellow.wrap(' ${dep!.name}: ${dep.version}'));
print(yellow.wrap(' ${dep.name}: ${dep.version}'));
}
}
}

View file

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'package:inflection3/inflection3.dart';
import 'package:inflection2/inflection2.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart';
@ -28,23 +28,21 @@ class MigrationCommand extends Command {
@override
FutureOr run() async {
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class');
}
var deps = [const MakerDependency('angel3_migration', '^7.0.0')];
var rc = ReCase(name!);
var deps = [const MakerDependency('angel_migration', '^2.0.0')];
var rc = new ReCase(name);
var migrationLib = Library((migrationLib) {
var migrationLib = new Library((migrationLib) {
migrationLib
..directives.add(Directive.import(
'package:angel3_migration.dart/angel3_migration.dart'))
..body.add(Class((migrationClazz) {
..directives.add(new Directive.import(
'package:angel_migration.dart/angel_migration.dart'))
..body.add(new Class((migrationClazz) {
migrationClazz
..name = '${rc.pascalCase}Migration'
..extend = refer('Migration');
@ -52,21 +50,21 @@ class MigrationCommand extends Command {
var tableName = pluralize(rc.snakeCase);
// up()
migrationClazz.methods.add(Method((up) {
migrationClazz.methods.add(new Method((up) {
up
..name = 'up'
..returns = refer('void')
..annotations.add(refer('override'))
..requiredParameters.add(Parameter((b) => b
..requiredParameters.add(new Parameter((b) => b
..name = 'schema'
..type = refer('Schema')))
..body = Block((block) {
..body = new Block((block) {
// (table) { ... }
var callback = Method((callback) {
var callback = new Method((callback) {
callback
..requiredParameters
.add(Parameter((b) => b..name = 'table'))
..body = Block((block) {
.add(new Parameter((b) => b..name = 'table'))
..body = new Block((block) {
var table = refer('table');
block.addExpression(
@ -97,15 +95,15 @@ class MigrationCommand extends Command {
}));
// down()
migrationClazz.methods.add(Method((down) {
migrationClazz.methods.add(new Method((down) {
down
..name = 'down'
..returns = refer('void')
..annotations.add(refer('override'))
..requiredParameters.add(Parameter((b) => b
..requiredParameters.add(new Parameter((b) => b
..name = 'schema'
..type = refer('Schema')))
..body = Block((block) {
..body = new Block((block) {
block.addExpression(
refer('schema').property('drop').call([
literal(tableName),
@ -117,16 +115,15 @@ class MigrationCommand extends Command {
});
// Save migration file
var migrationDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
var migrationDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var migrationFile =
File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists()) {
new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists())
await migrationFile.create(recursive: true);
}
await migrationFile.writeAsString(
DartFormatter().format(migrationLib.accept(DartEmitter()).toString()));
await migrationFile.writeAsString(new DartFormatter()
.format(migrationLib.accept(new DartEmitter()).toString()));
print(green.wrap(
'$checkmark Created migration file "${migrationFile.absolute.path}".'));

View file

@ -32,39 +32,37 @@ class ModelCommand extends Command {
}
@override
Future run() async {
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
run() async {
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class');
}
var deps = <MakerDependency>[
const MakerDependency('angel3_model', '^3.0.0'),
List<MakerDependency> deps = [
const MakerDependency('angel_model', '^1.0.0'),
];
var rc = ReCase(name!);
var rc = new ReCase(name);
var modelLib = Library((modelLib) {
if (argResults?['orm'] as bool && argResults?['migration'] as bool) {
var modelLib = new Library((modelLib) {
if (argResults['orm'] as bool && argResults['migration'] as bool) {
modelLib.directives.addAll([
Directive.import('package:angel3_migration/angel3_migration.dart'),
new Directive.import('package:angel_migration/angel_migration.dart'),
]);
}
var needsSerialize =
argResults?['serializable'] as bool || argResults?['orm'] as bool;
argResults['serializable'] as bool || argResults['orm'] as bool;
// argResults['migration'] as bool;
if (needsSerialize) {
modelLib.directives.add(
Directive.import('package:angel3_serialize/angel3_serialize.dart'));
deps.add(const MakerDependency('angel3_serialize', '^7.0.0'));
deps.add(const MakerDependency('angel3_serialize_generator', '^7.0.0'));
deps.add(const MakerDependency('build_runner', '^2.2.0'));
modelLib.directives.add(new Directive.import(
'package:angel_serialize/angel_serialize.dart'));
deps.add(const MakerDependency('angel_serialize', '^2.0.0'));
deps.add(const MakerDependency('angel_serialize_generator', '^2.0.0'));
deps.add(const MakerDependency('build_runner', '^1.0.0'));
}
// else {
@ -73,18 +71,18 @@ class ModelCommand extends Command {
// deps.add(const MakerDependency('angel_model', '^1.0.0'));
// }
if (argResults?['orm'] as bool) {
if (argResults['orm'] as bool) {
modelLib.directives.addAll([
Directive.import('package:angel3_orm/angel3_orm.dart'),
new Directive.import('package:angel_orm/angel_orm.dart'),
]);
deps.add(const MakerDependency('angel3_orm', '^7.0.0'));
deps.add(const MakerDependency('angel_orm', '^2.0.0'));
}
modelLib.body.addAll([
Code("part '${rc.snakeCase}.g.dart';"),
new Code("part '${rc.snakeCase}.g.dart';"),
]);
modelLib.body.add(Class((modelClazz) {
modelLib.body.add(new Class((modelClazz) {
modelClazz
..abstract = true
..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
@ -95,8 +93,8 @@ class ModelCommand extends Command {
modelClazz.annotations.add(refer('serializable'));
}
if (argResults?['orm'] as bool) {
if (argResults?['migration'] as bool) {
if (argResults['orm'] as bool) {
if (argResults['migration'] as bool) {
modelClazz.annotations.add(refer('orm'));
} else {
modelClazz.annotations.add(
@ -107,13 +105,14 @@ class ModelCommand extends Command {
});
// Save model file
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
var modelFile = File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
var outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var modelFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await modelFile.exists()) await modelFile.create(recursive: true);
await modelFile.writeAsString(
DartFormatter().format(modelLib.accept(DartEmitter()).toString()));
await modelFile.writeAsString(new DartFormatter()
.format(modelLib.accept(new DartEmitter()).toString()));
print(green
.wrap('$checkmark Created model file "${modelFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class PluginCommand extends Command {
@override
String get name => 'plugin';
String get name => "plugin";
@override
String get description => 'Creates a new plug-in within the given project.';
String get description => "Creates a new plug-in within the given project.";
PluginCommand() {
argParser
@ -25,29 +25,27 @@ class PluginCommand extends Command {
}
@override
Future run() async {
run() async {
var pubspec = await loadPubspec();
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompts.get('Name of plug-in class');
}
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
];
var rc = ReCase(name!);
final pluginDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
var rc = new ReCase(name);
final pluginDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final pluginFile =
File.fromUri(pluginDir.uri.resolve('${rc.snakeCase}.dart'));
new File.fromUri(pluginDir.uri.resolve("${rc.snakeCase}.dart"));
if (!await pluginFile.exists()) await pluginFile.create(recursive: true);
await pluginFile
.writeAsString(DartFormatter().format(_generatePlugin(pubspec, rc)));
await pluginFile.writeAsString(
new DartFormatter().format(_generatePlugin(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps);
@ -59,7 +57,7 @@ class PluginCommand extends Command {
return '''
library ${pubspec.name}.src.config.plugins.${rc.snakeCase};
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel_framework/angel_framework.dart';
AngelConfigurer ${rc.camelCase}() {
return (Angel app) async {

View file

@ -2,9 +2,10 @@ import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'package:inflection3/inflection3.dart';
import 'package:inflection2/inflection2.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart';
import '../service_generators/service_generators.dart';
import '../../util.dart';
@ -31,26 +32,24 @@ class ServiceCommand extends Command {
}
@override
void run() async {
await loadPubspec();
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompts.get('Name of service');
}
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
];
// '${pubspec.name}.src.services.${rc.snakeCase}'
var rc = ReCase(name!);
var serviceLib = Library((serviceLib) {
var rc = new ReCase(name);
var serviceLib = new Library((serviceLib) {
var generator = prompts.choose(
'Choose which type of service to create', serviceGenerators)!;
'Choose which type of service to create', serviceGenerators);
// if (generator == null) {
// _pen.red();
@ -63,61 +62,56 @@ class ServiceCommand extends Command {
if (!deps.any((d) => d.name == dep.name)) deps.add(dep);
}
if (name != null && generator.goesFirst) {
if (generator.goesFirst) {
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
serviceLib.directives.add(
Directive.import('package:angel3_framework/angel3_framework.dart'));
} else if (name != null) {
serviceLib.directives.add(
Directive.import('package:angel3_framework/angel3_framework.dart'));
serviceLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
} else {
serviceLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
}
if (argResults!['typed'] as bool) {
if (argResults['typed'] as bool) {
serviceLib.directives
.add(Directive.import('../models/${rc.snakeCase}.dart'));
.add(new Directive.import('../models/${rc.snakeCase}.dart'));
}
// configureServer() {}
serviceLib.body.add(Method((configureServer) {
serviceLib.body.add(new Method((configureServer) {
configureServer
..name = 'configureServer'
..returns = refer('AngelConfigurer');
configureServer.body = Block((block) {
if (name != null) {
generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
}
configureServer.body = new Block((block) {
generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
// return (Angel app) async {}
var closure = Method((closure) {
var closure = new Method((closure) {
closure
..modifier = MethodModifier.async
..requiredParameters.add(Parameter((b) => b
..requiredParameters.add(new Parameter((b) => b
..name = 'app'
..type = refer('Angel')));
closure.body = new Block((block) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
closure.body = Block((block) {
if (name != null) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
// app.use('/api/todos', new MapService());
var service = generator.createInstance(
serviceLib, closure, name, rc.snakeCase);
// app.use('/api/todos', new MapService());
var service = generator.createInstance(
serviceLib, closure, name, rc.snakeCase);
if (argResults!['typed'] as bool) {
var tb = TypeReference((b) => b
..symbol = 'TypedService'
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]);
}
block.addExpression(refer('app').property('use').call([
literal('/api/${pluralize(rc.snakeCase)}'),
service,
]));
if (argResults['typed'] as bool) {
var tb = new TypeReference((b) => b
..symbol = 'TypedService'
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]);
}
block.addExpression(refer('app').property('use').call([
literal('/api/${pluralize(rc.snakeCase)}'),
service,
]));
});
});
@ -126,13 +120,13 @@ class ServiceCommand extends Command {
}));
});
final outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
final outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final serviceFile =
File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
new File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart"));
if (!await serviceFile.exists()) await serviceFile.create(recursive: true);
await serviceFile.writeAsString(
DartFormatter().format(serviceLib.accept(DartEmitter()).toString()));
await serviceFile.writeAsString(new DartFormatter()
.format(serviceLib.accept(new DartEmitter()).toString()));
print(green.wrap(
'$checkmark Successfully generated service file "${serviceFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class TestCommand extends Command {
@override
String get name => 'test';
String get name => "test";
@override
String get description => 'Creates a new test within the given project.';
String get description => "Creates a new test within the given project.";
TestCommand() {
argParser
@ -28,39 +28,37 @@ class TestCommand extends Command {
}
@override
Future run() async {
run() async {
var pubspec = await loadPubspec();
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
if (name?.isNotEmpty != true) {
name = prompter.get('Name of test');
}
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0'),
const MakerDependency('angel3_test', '^7.0.0', dev: true),
const MakerDependency('test', '^1.21.0', dev: true),
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0'),
const MakerDependency('angel_test', '^2.0.0', dev: true),
const MakerDependency('test', '^1.0.0', dev: true),
];
var rc = ReCase(name!);
final testDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
var rc = new ReCase(name);
final testDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final testFile =
File.fromUri(testDir.uri.resolve('${rc.snakeCase}_test.dart'));
new File.fromUri(testDir.uri.resolve("${rc.snakeCase}_test.dart"));
if (!await testFile.exists()) await testFile.create(recursive: true);
await testFile
.writeAsString(DartFormatter().format(_generateTest(pubspec, rc)));
.writeAsString(new DartFormatter().format(_generateTest(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps);
print(green.wrap(
'$checkmark Successfully generated test file "${testFile.absolute.path}".'));
if (argResults!['run-configuration'] as bool) {
final runConfig = File.fromUri(Directory.current.uri
if (argResults['run-configuration'] as bool) {
final runConfig = new File.fromUri(Directory.current.uri
.resolve('.idea/runConfigurations/${name}_Tests.xml'));
if (!await runConfig.exists()) await runConfig.create(recursive: true);
@ -87,15 +85,15 @@ class TestCommand extends Command {
return '''
import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart' as ${pubspec.name};
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_test/angel3_test.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_test/angel_test.dart';
import 'package:test/test.dart';
main() async {
TestClient client;
setUp(() async {
var app = Angel();
var app = new Angel();
await app.configure(${pubspec.name}.configureServer);
client = await connectTo(app);
});

View file

@ -2,13 +2,11 @@ import 'dart:io';
final RegExp _leadingSlashes = RegExp(r'^/+');
@Deprecated("Replaced by dart pub")
String resolvePub() {
var exec = File(Platform.resolvedExecutable);
var pubPath = exec.parent.uri.resolve('pub').path;
if (Platform.isWindows) {
pubPath = '${pubPath.replaceAll(_leadingSlashes, '')}.bat';
}
if (Platform.isWindows)
pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat';
pubPath = Uri.decodeFull(pubPath);
return pubPath;
}

View file

@ -8,6 +8,8 @@ import 'package:glob/list_local_fs.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart';
import '../util.dart';
import 'pub.dart';
class RenameCommand extends Command {
@override
@ -20,16 +22,16 @@ class RenameCommand extends Command {
String get invocation => '$name <new name>';
@override
Future run() async {
String? newName;
run() async {
String newName;
if (argResults?.rest.isNotEmpty == true) {
newName = argResults?.rest.first;
} else {
if (argResults.rest.isNotEmpty)
newName = argResults.rest.first;
else {
newName = prompts.get('Rename project to');
}
newName = ReCase(newName!).snakeCase;
newName = ReCase(newName).snakeCase;
var choice = prompts.getBool('Rename the project to `$newName`?');
@ -61,7 +63,7 @@ class RenameCommand extends Command {
}
}
Future renamePubspec(Directory dir, String oldName, String newName) async {
renamePubspec(Directory dir, String oldName, String newName) async {
// var pubspec = await loadPubspec(dir);
print(cyan.wrap('Renaming your project to `$newName.`'));
@ -84,13 +86,13 @@ Future renamePubspec(Directory dir, String oldName, String newName) async {
// await newPubspec.save(dir);
}
Future renameDartFiles(Directory dir, String oldName, String newName) async {
renameDartFiles(Directory dir, String oldName, String newName) async {
if (!await dir.exists()) return;
// Try to replace MongoDB URL
// Replace name in config directory
var configGlob = Glob('config/**/*.yaml');
try {
var configGlob = Glob('config/**/*.yaml');
await for (var yamlFile in configGlob.list(root: dir.absolute.path)) {
if (yamlFile is File) {
print(
@ -111,58 +113,12 @@ Future renameDartFiles(Directory dir, String oldName, String newName) async {
print('Renaming library file `${entry.absolute.path}`...');
}
// Replace package:oldName/oldName.dart with package:newName/newName.dart
// Replace package:oldName/ with package:newName/
String updateImport(String content, String oldName, String newName) {
if (!content.startsWith('import')) {
return content;
}
if (content.contains('package:$oldName/$oldName.dart')) {
return content.replaceFirst(
'package:$oldName/$oldName.dart', 'package:$newName/$newName.dart');
}
if (content.contains('package:$oldName/')) {
return content.replaceFirst('package:$oldName/', 'package:$newName/');
}
return content;
}
// Replace mustache {{oldName}} with newName
String updateMustacheBinding(String content, String oldName, String newName) {
if (content.contains('{{$oldName}}')) {
return content.replaceAll('{{$oldName}}', newName);
}
return content;
}
var fmt = DartFormatter();
await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) {
var lineList = await file.readAsLines();
if (oldName.isNotEmpty && newName.isNotEmpty) {
var contents = lineList.fold<String>('', (prev, cur) {
var updatedCur = updateImport(cur, oldName, newName);
updatedCur = updateMustacheBinding(updatedCur, oldName, newName);
return '$prev\n$updatedCur';
});
await file.writeAsString(fmt.format(contents));
print('Updated file `${file.absolute.path}`.');
}
}
}
/* Deprecated, Not working
var fmt = DartFormatter();
await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) {
var contents = await file.readAsString();
// TODO: Issue to be fixed: parseCompilationUnit uses Hubbub library which uses discontinued Google front_end library
// front_end package. Temporarily commeted out
//var ast = parseCompilationUnit(contents);
var visitor = RenamingVisitor(oldName, newName);
@ -172,7 +128,7 @@ Future renameDartFiles(Directory dir, String oldName, String newName) async {
visitor.replace.forEach((range, replacement) {
if (range.first is int) {
contents = contents.replaceRange(
range.first as int, range.last as int?, replacement);
range.first as int, range.last as int, replacement);
} else if (range.first is String) {
contents = contents.replaceAll(range.first as String, replacement);
}
@ -183,7 +139,6 @@ Future renameDartFiles(Directory dir, String oldName, String newName) async {
}
}
}
*/
}
class RenamingVisitor extends RecursiveAstVisitor {
@ -198,49 +153,41 @@ class RenamingVisitor extends RecursiveAstVisitor {
if (uri == 'package:$oldName/$oldName.dart') {
return 'package:$newName/$newName.dart';
} else if (uri.startsWith('package:$oldName/')) {
return 'package:$newName/${uri.replaceFirst('package:$oldName/', '')}';
} else {
return 'package:$newName/' + uri.replaceFirst('package:$oldName/', '');
} else
return uri;
}
}
@override
void visitExportDirective(ExportDirective node) {
var uri = node.uri.stringValue;
if (uri != null) {
var updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
visitExportDirective(ExportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
void visitImportDirective(ImportDirective node) {
var uri = node.uri.stringValue;
if (uri != null) {
var updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
visitImportDirective(ImportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
void visitLibraryDirective(LibraryDirective node) {
var name = node.name2?.name ?? '';
visitLibraryDirective(LibraryDirective ctx) {
var name = ctx.name.name;
if (name.startsWith(oldName)) {
replace[[node.offset, node.end]] =
'library ${name.replaceFirst(oldName, newName)};';
replace[[ctx.offset, ctx.end]] =
'library ' + name.replaceFirst(oldName, newName) + ';';
}
}
@override
void visitPartOfDirective(PartOfDirective node) {
if (node.libraryName != null) {
var name = node.libraryName!.name;
visitPartOfDirective(PartOfDirective ctx) {
if (ctx.libraryName != null) {
var name = ctx.libraryName.name;
if (name.startsWith(oldName)) {
replace[[node.offset, node.end]] =
'part of ${name.replaceFirst(oldName, newName)};';
replace[[ctx.offset, ctx.end]] =
'part of ' + name.replaceFirst(oldName, newName) + ';';
}
}
}

View file

@ -2,8 +2,10 @@ import 'package:code_builder/code_builder.dart';
import 'generator.dart';
class CustomServiceGenerator extends ServiceGenerator {
@override
bool get createsModel => false;
@override
bool get createsValidator => false;
const CustomServiceGenerator() : super('Custom');

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection3/inflection3.dart';
import 'package:inflection2/inflection2.dart';
import '../make/maker.dart';
class FileServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [MakerDependency('angel3_file_service', '^7.0.0')];
const [const MakerDependency('angel_file_service', '^2.0.0')];
@override
bool get goesFirst => true;
@ -18,9 +18,9 @@ class FileServiceGenerator extends ServiceGenerator {
LibraryBuilder library,
MethodBuilder configureServer,
BlockBuilder block,
String? name,
String name,
String lower) {
configureServer.requiredParameters.add(Parameter((b) => b
configureServer.requiredParameters.add(new Parameter((b) => b
..name = 'dbDirectory'
..type = refer('Directory')));
}
@ -28,7 +28,8 @@ class FileServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
Directive.import('package:angel3_file_service/angel3_file_service.dart'),
new Directive.import(
'package:angel_file_service/angel_file_service.dart'),
]);
}
@ -36,12 +37,12 @@ class FileServiceGenerator extends ServiceGenerator {
Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder,
String name, String lower) {
library.directives.addAll([
Directive.import('package:file/file.dart'),
new Directive.import('package:file/file.dart'),
]);
return refer('JsonFileService').newInstance([
refer('dbDirectory')
.property('childFile')
.call([literal('${pluralize(lower)}_db.json')])
.call([literal(pluralize(lower) + '_db.json')])
]);
}
}

View file

@ -8,6 +8,21 @@ class ServiceGenerator {
List<MakerDependency> get dependencies => [];
@deprecated
bool get createsModel => true;
@deprecated
bool get createsValidator => true;
@deprecated
bool get exportedInServiceLibrary => true;
@deprecated
bool get injectsSingleton => false;
@deprecated
bool get shouldRunBuild => false;
bool get goesFirst => false;
void applyToLibrary(LibraryBuilder library, String name, String lower) {}

View file

@ -4,6 +4,7 @@ import 'package:code_builder/code_builder.dart';
class MapServiceGenerator extends ServiceGenerator {
const MapServiceGenerator() : super('In-Memory');
@override
bool get createsModel => false;
@override

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection3/inflection3.dart';
import 'package:inflection2/inflection2.dart';
import '../make/maker.dart';
class MongoServiceGenerator extends ServiceGenerator {
@ -8,8 +8,9 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [MakerDependency('angel3_mongo', '^4.0.0')];
const [const MakerDependency('angel_mongo', '^2.0.0')];
@override
bool get createsModel => false;
@override
@ -17,9 +18,9 @@ class MongoServiceGenerator extends ServiceGenerator {
LibraryBuilder library,
MethodBuilder configureServer,
BlockBuilder block,
String? name,
String name,
String lower) {
configureServer.requiredParameters.add(Parameter((b) => b
configureServer.requiredParameters.add(new Parameter((b) => b
..name = 'db'
..type = refer('Db')));
}
@ -27,8 +28,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
Directive.import('package:angel3_mongo/angel3_mongo.dart'),
Directive.import('package:mongo_dart/mongo_dart.dart'),
new Directive.import('package:angel_mongo/angel_mongo.dart'),
new Directive.import('package:mongo_dart/mongo_dart.dart'),
]);
}

View file

@ -1,6 +1,6 @@
import 'generator.dart';
import 'package:code_builder/code_builder.dart';
import 'package:inflection3/inflection3.dart';
import 'package:inflection2/inflection2.dart';
import '../make/maker.dart';
class RethinkServiceGenerator extends ServiceGenerator {
@ -8,8 +8,9 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [MakerDependency('angel3_rethink', '^4.0.0')];
const [const MakerDependency('angel_rethink', '^2.0.0')];
@override
bool get createsModel => false;
@override
@ -17,13 +18,13 @@ class RethinkServiceGenerator extends ServiceGenerator {
LibraryBuilder library,
MethodBuilder configureServer,
BlockBuilder block,
String? name,
String name,
String lower) {
configureServer.requiredParameters.addAll([
Parameter((b) => b
new Parameter((b) => b
..name = 'connection'
..type = refer('Connection')),
Parameter((b) => b
new Parameter((b) => b
..name = 'r'
..type = refer('Rethinkdb')),
]);
@ -32,9 +33,9 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
'package:angel3_rethink/angel3_rethink.dart',
'package:angel_rethink/angel_rethink.dart',
'package:rethinkdb_dart/rethinkdb_dart.dart'
].map((str) => Directive.import(str)));
].map((str) => new Directive.import(str)));
}
@override

View file

@ -6,10 +6,10 @@ import 'mongo.dart';
import 'rethink.dart';
export 'generator.dart';
const List<ServiceGenerator> serviceGenerators = [
MapServiceGenerator(),
FileServiceGenerator(),
MongoServiceGenerator(),
RethinkServiceGenerator(),
CustomServiceGenerator()
const List<ServiceGenerator> serviceGenerators = const [
const MapServiceGenerator(),
const FileServiceGenerator(),
const MongoServiceGenerator(),
const RethinkServiceGenerator(),
const CustomServiceGenerator()
];

View file

@ -7,7 +7,7 @@ final Random _rnd = Random.secure();
String randomAlphaNumeric(int length) {
var b = StringBuffer();
for (var i = 0; i < length; i++) {
for (int i = 0; i < length; i++) {
b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length)));
}

View file

@ -10,18 +10,18 @@ final String checkmark = ansiOutputEnabled ? '\u2714' : '[Success]';
final String ballot = ansiOutputEnabled ? '\u2717' : '[Failure]';
String get homeDirPath =>
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'] ?? '.';
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
Directory get homeDir => Directory(homeDirPath);
Directory get homeDir => new Directory(homeDirPath);
Directory get angelDir => Directory(p.join(homeDir.path, '.angel'));
Future<Pubspec> loadPubspec([Directory? directory]) {
Future<Pubspec> loadPubspec([Directory directory]) {
directory ??= Directory.current;
var file = File.fromUri(directory.uri.resolve('pubspec.yaml'));
var file = new File.fromUri(directory.uri.resolve('pubspec.yaml'));
return file
.readAsString()
.then((yaml) => Pubspec.parse(yaml, sourceUrl: file.uri));
.then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri));
}
// From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a

View file

@ -1,29 +1,27 @@
name: angel3_cli
version: 8.2.0
description: The command line interface for building dart backend in Angel3 framework.
homepage: https://angel3-framework.web.app/
repository: https://github.com/dart-backend/angel3-cli
#author: Tobe O <thosakwe@gmail.com>
description: Command-line tools for the Angel framework, including scaffolding.
homepage: https://github.com/dukefirehawk/angel/packages/angel_cli
name: angel_cli
version: 3.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
sdk: ">=2.10.0 <3.0.0"
dependencies:
analyzer: ^6.3.0
args: ^2.4.0
code_builder: ^4.5.0
dart_style: ^2.3.0
glob: ^2.1.0
http: ^1.0.0
io: ^1.0.0
inflection3: ^0.5.3+2
mustache_template: ^2.0.0
path: ^1.9.0
prompts: ^2.0.0
pubspec_parse: ^1.2.0
quiver: ^3.2.0
recase: ^4.1.0
shutdown: ^0.4.3
watcher: ^1.1.0
yaml: ^3.1.0
dev_dependencies:
lints: ^3.0.0
analyzer: ^1.1.0
args: ^2.0.0
code_builder: ^3.0.0
dart_style: ^1.0.0
glob: ^2.0.0
http: ^0.13.0
io: ^0.3.5
inflection2: ^0.4.2
mustache4dart2: ^0.1.0
path: ^1.0.0
prompts: ^1.3.1
pubspec_parse: ^1.0.0
quiver: ^3.0.0
recase: ^3.0.1
shutdown: ^0.4.0
watcher: ^1.0.0
yaml: ^3.0.0
executables:
angel3: angel3
angel: angel

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
screenshots/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -1,53 +0,0 @@
import 'dart:io';
import 'package:dart_style/dart_style.dart';
void main() async {
String updateImport(String content, String oldName, String newName) {
if (!content.startsWith('import')) {
return content;
}
if (content.contains('package:$oldName/$oldName.dart')) {
return content.replaceFirst(
'package:$oldName/$oldName.dart', 'package:$newName/$newName.dart');
}
if (content.contains('package:$oldName/')) {
return content.replaceFirst('package:$oldName/', 'package:$newName/');
}
return content;
}
String updateMustacheBinding(String content, String oldName, String newName) {
if (content.contains('{{$oldName}}')) {
return content.replaceAll('{{$oldName}}', newName);
}
return content;
}
var fmt = DartFormatter();
var dir = Directory('graph');
await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) {
var lineList = await file.readAsLines();
var oldName = 'angel';
var newName = 'graph';
var replace = {oldName: newName};
if (replace.isNotEmpty) {
var contents = lineList.fold<String>('', (prev, cur) {
var updatedCur = updateImport(cur, oldName, newName);
updatedCur = updateMustacheBinding(updatedCur, oldName, newName);
return '$prev\n$updatedCur';
});
await file.writeAsString(fmt.format(contents));
print('Updated file `${file.absolute.path}`.');
}
}
}
}