Compare commits

...

41 commits

Author SHA1 Message Date
Thomas
6dd993cd3b
Merge pull request #4 from dukefirehawk/feature/update_links
Updated repository links
2023-12-25 12:40:45 +08:00
thomashii@dukefirehawk.com
91bd1bf314 Updated repository links 2023-12-25 12:40:00 +08:00
Thomas Hii
ff197d984e
Update README.md 2023-10-21 13:35:36 +08:00
thomashii@dukefirehawk.com
383fdfb8f9 Updated README 2023-10-21 10:27:39 +08:00
thomashii@dukefirehawk.com
78c7076745 Updated change log 2023-10-12 22:47:51 +08:00
thomashii@dukefirehawk.com
0137402f89 Added white logo 2023-10-09 23:52:44 +08:00
thomashii@dukefirehawk.com
3b09470606 Updated logo 2023-10-08 23:51:07 +08:00
Thomas Hii
4154deface
Merge pull request #3 from dukefirehawk/feature/v8
Feature/v8
2023-10-08 11:16:01 +08:00
thomashii@dukefirehawk.com
4405b41acd Merge branch 'master' into feature/v8 2023-10-08 11:14:12 +08:00
thomashii@dukefirehawk.com
8682da1aef Ignore .DS_Store 2023-10-08 10:27:09 +08:00
thomashii@dukefirehawk.com
be3e91927d Updated dependencies 2023-10-08 10:25:40 +08:00
thomashii
00b0304af1 Removed deprecated code 2023-06-10 20:28:00 +08:00
thomashii
9619342ab8 Updated dependencies 2023-06-10 20:21:24 +08:00
Thomas Hii
1bc6641651
Merge pull request #2 from dukefirehawk/bug-fix/deprecated
Upgaded libraries
2022-12-03 13:11:11 +08:00
thomashii@dukefirehawk.com
f117469949 Upgaded libraries 2022-12-03 13:09:44 +08:00
thomashii@dukefirehawk.com
883f034140 Updated to version 7.0.0 2022-08-31 00:56:09 +08:00
Thomas Hii
e0548f997a
Merge pull request #1 from dukefirehawk/feature/upgrade-dependencies
Updated dependencies
2022-05-29 08:16:44 +08:00
thomashii@dukefirehawk.com
9123a77057 Updated dependencies 2022-05-29 08:13:58 +08:00
thomashii
b26b5c3054 Updated .pubignore 2022-05-01 18:06:02 +08:00
thomashii
8236775e73 Updated gitignore 2022-05-01 18:02:17 +08:00
thomashii
7e2d693164 Added mysql orm boilerplate 2022-05-01 18:00:33 +08:00
thomashii
d33edd4bb5 Updated ChangeLog 2022-04-26 09:32:24 +08:00
thomashii
9141e0c735 Update to SDK 2.16 2022-04-26 09:29:35 +08:00
thomashii
18ea483330 Added pubignore 2022-01-13 23:03:44 +08:00
thomashii
b9079bbe5f Fixed init 2022-01-13 22:51:04 +08:00
thomashii
f4b38337e0 Updated the SDK 2.14.0 2022-01-13 22:32:40 +08:00
thomashii
64104653a0 Updated gitignore 2021-09-16 10:17:24 +08:00
thomashii
e87d86eece Updated gitignore 2021-09-16 10:15:34 +08:00
thomashii
ac592ceb1a Updated linter 2021-09-16 10:14:04 +08:00
thomashii
422c92098a Fixed NNBD issues 2021-09-07 08:11:42 +08:00
thomashii
3bfdf05c0e Updated analyzer 2021-08-17 15:49:48 +08:00
thomashii
d8efcdef28 Updated README 2021-07-18 16:02:41 +08:00
thomashii
aa57f3b301 Updated CLI 2021-07-18 16:00:08 +08:00
thomashii
fe5b7ecd47 Updated screenshot 2021-07-18 12:34:31 +08:00
thomashii
c1ec1e3966 Updated screenshot 2021-07-18 12:31:03 +08:00
thomashii
5fc441825e Fixed init 2021-07-18 12:22:11 +08:00
thomashii
7e4aa24ce0 Updated NNBD 2021-07-17 13:10:35 +08:00
thomashii
6254a8a471 Updated README 2021-06-13 17:28:15 +08:00
thomashii
ac607e636a Updated README 2021-06-12 12:23:33 +08:00
thomashii
a71e02d7bd Migrated to NNBD 2021-06-12 12:10:34 +08:00
thomashii
dcd001fc65 Migrated to angel3 2021-06-11 13:07:53 +08:00
54 changed files with 980 additions and 653 deletions

BIN
.DS_Store vendored

Binary file not shown.

27
.gitignore vendored
View file

@ -3,38 +3,17 @@
# 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
@ -78,3 +57,7 @@ pubspec.lock
sample_project/
sample-project
.dart_tool
.metals
#.vscode
#!.vscode/settings.json

View file

@ -1,19 +0,0 @@
<?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>

View file

@ -1,8 +0,0 @@
<?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

@ -1,8 +0,0 @@
<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

@ -1,7 +0,0 @@
<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

@ -1,8 +0,0 @@
<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

@ -1,7 +0,0 @@
<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

@ -1,8 +0,0 @@
<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

@ -1,7 +0,0 @@
<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>

3
.pubignore Normal file
View file

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

View file

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

6
.vscode/settings.json vendored Normal file
View file

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

12
AUTHORS.md Normal file
View file

@ -0,0 +1,12 @@
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,8 +1,88 @@
# 2.1.7+1
# 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
* 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`.
@ -10,36 +90,45 @@ 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`.
@ -48,34 +137,43 @@ 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,21 +1,29 @@
MIT License
BSD 3-Clause License
Copyright (c) [year] [fullname]
Copyright (c) 2021, dukefirehawk.com
All rights reserved.
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:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
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.
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.

View file

@ -1,26 +1,31 @@
# angel_cli
# Angel3 CLI
![Screenshot of Terminal](screenshots/screenshot.png)
[![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:
Command-line tools for the Angel framework.
Includes functionality such as:
* Project scaffolding
* Generating service models, plugins, tests and more
* Renaming projects
* Much more...
* To install:
## Installation
```bash
$ pub global activate angel_cli
dart pub global activate angel3_cli
```
* Install development version
`dart pub global activate --source path ./packages/cli`
`dart pub global activate --source git https://github.com/dukefirehawk/angel/packages/cli`
## Help
And then, for information on each command:
For information on the available options:
```bash
$ angel help
angel3 help
```
[![Screenshot of Terminal](screenshots/angel3-screenshot.png)](https://github.com/dart-backend/angel3-cli)

View file

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

View file

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

BIN
angel3_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

135
archived/logo128.svg Normal file
View file

@ -0,0 +1,135 @@
<?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>

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
archived/logo3.xcf Normal file

Binary file not shown.

View file

@ -1,55 +0,0 @@
#!/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 = '''
____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \____/ /_____/ /_____/
''';

76
bin/angel3.dart Normal file
View file

@ -0,0 +1,76 @@
#!/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 angel_cli;
library angel3_cli;
export 'src/commands/commands.dart';

View file

@ -1,9 +1,9 @@
library angel_cli.commands;
library angel3_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
run() async {
Future 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 Angel server
try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel3 server
}
location @proxy {
@ -39,10 +39,10 @@ server {
'''
.trim();
if (!argResults.wasParsed('out')) {
if (!argResults!.wasParsed('out')) {
print(nginxText);
} else {
var file = new File(argResults['out'] as String);
var file = 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
run() async {
Future 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,15 +47,16 @@ WantedBy=multi-user.target
'''
.trim();
if (!argResults.wasParsed('out') && !argResults.wasParsed('install')) {
if (argResults?.wasParsed('out') != true &&
argResults?.wasParsed('install') != true) {
print(systemdText);
} else if (argResults.wasParsed('install')) {
var systemdPath = argResults.wasParsed('out')
? argResults['out'] as String
} else if (argResults?.wasParsed('install') == true) {
var systemdPath = argResults?.wasParsed('out') == true
? (argResults?['out'] as String)
: p.join('etc', 'systemd', 'system');
var serviceFilename = p.join(systemdPath,
p.setExtension(argResults['install'] as String, '.service'));
var file = new File(serviceFilename);
p.setExtension(argResults?['install'] as String, '.service'));
var file = File(serviceFilename);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(
@ -76,7 +77,7 @@ WantedBy=multi-user.target
print(red.wrap('$ballot Failed to install service system-wide.'));
}
} else {
var file = new File(argResults['out'] as String);
var file = File(argResults?['out'] as String);
await file.create(recursive: true);
await file.writeAsString(systemdText);
print(green.wrap(

View file

@ -1,34 +1,35 @@
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 Angel.";
'Ensures that the current system is capable of running Angel3.';
@override
run() async {
print("Checking your system for dependencies...");
Future run() async {
print('Checking your system for dependencies...');
await _checkForGit();
}
_checkForGit() async {
Future _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,18 +8,17 @@ 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 Angel project in the current directory.";
'Initializes a new Angel3 project in the current directory.';
InitCommand() {
argParser
@ -33,10 +32,15 @@ class InitCommand extends Command {
}
@override
run() async {
Directory projectDir =
Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]);
print("Creating new Angel project in ${projectDir.absolute.path}...");
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}...');
await _cloneRepo(projectDir);
// await preBuild(projectDir);
var secret = rs.randomAlphaNumeric(32);
@ -49,8 +53,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());
@ -58,50 +62,57 @@ 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 pub get...');
if (argResults!['pub-get'] != false && argResults!['offline'] == false) {
print('Now running dart pub get...');
await _pubGet(projectDir);
}
print(green.wrap("$checkmark Successfully initialized Angel project."));
print(green.wrap('$checkmark Successfully initialized Angel3 project.'));
stdout
..writeln()
..writeln(
'Congratulations! You are ready to start developing with Angel!')
'Congratulations! You are ready to start developing with Angel3!')
..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 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('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()
..writeln('Happy coding!');
}
_deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
Future _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) {}
} catch (e) {
print(e);
}
}
try {
if (self != false) await entity.delete(recursive: true);
} catch (e) {}
} catch (e) {
print(e);
}
} else if (entity is File) {
try {
await entity.delete(recursive: true);
} catch (e) {}
} catch (e) {
print(e);
}
} else if (entity is Link) {
var path = await entity.resolveSymbolicLinks();
var stat = await FileStat.stat(path);
@ -117,42 +128,49 @@ class InitCommand extends Command {
}
}
_cloneRepo(Directory projectDir) async {
Directory boilerplateDir;
Future _cloneRepo(Directory projectDir) async {
Directory boilerplateDir = Directory("./empty");
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);
'Choose a project type before continuing', boilerplates) ??
basicBoilerplate;
// 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 != null) boilerplateBasename += '.${boilerplate.ref}';
if (boilerplate.ref != '') {
boilerplateBasename += '.${boilerplate.ref}';
}
boilerplateDir =
Directory(p.join(boilerplateRootDir.path, boilerplateBasename));
await boilerplateRootDir.create(recursive: true);
var branch = boilerplate.ref ?? 'master';
var branch = boilerplate.ref;
if (branch == '') {
branch = '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.');
}
@ -161,15 +179,15 @@ class InitCommand extends Command {
'Cloning "${boilerplate.name}" boilerplate from "${boilerplate.url}"...');
Process git;
if (boilerplate.ref == null) {
if (boilerplate.ref == '') {
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
],
@ -180,13 +198,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
@ -196,19 +214,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(
@ -222,37 +240,39 @@ 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).catchError((_) => null);
await boilerplateDir.delete(recursive: true);
//await boilerplateDir.delete(recursive: true).catchError((e) {
// print('Got error: ${e.error}');
//});
if (e is! String) {
print(red.wrap("$ballot Could not initialize Angel project."));
print(red.wrap('$ballot Could not initialize Angel3 project.'));
}
rethrow;
}
}
_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"],
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'],
workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio);
var code = await pub.exitCode;
print("Pub process exited with code $code");
var code = await dart.exitCode;
print('Dart process exited with code $code');
}
}
Future preBuild(Directory projectDir) async {
// Run build
// print('Running `pub run build_runner build`...');
print(darkGray.wrap('\$ pub run build_runner build'));
// print('Running `dart run build_runner build`...');
print(darkGray.wrap('\$ dart run build_runner build'));
var build = await Process.start(
resolvePub(), ['run', 'build_runner', 'build'],
var build = await Process.start("dart", ['run', 'build_runner', 'build'],
workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio);
@ -261,63 +281,63 @@ Future preBuild(Directory projectDir) async {
if (buildCode != 0) throw Exception('Failed to pre-build resources.');
}
const RepoArchiveLocation = "https://github.com/angel-dart";
const RepoLocation = "https://github.com/dukefirehawk";
const repoLocation = 'https://github.com/dart-backend';
const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo(
const BoilerplateInfo graphQLBoilerplate = BoilerplateInfo(
'GraphQL',
"A starting point for GraphQL API servers.",
'${RepoLocation}/boilerplates.git',
ref: 'graphql-sdk-2.12.x',
'A starter application with GraphQL support.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-graphql',
);
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 ormBoilerplate = BoilerplateInfo(
'ORM for PostgreSQL',
'A starter application with ORM support for PostgreSQL.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-orm',
);
const BoilerplateInfo basicBoilerplate = const BoilerplateInfo(
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(
'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');
'A basic starter application with minimal packages.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-basic');
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(
const BoilerplateInfo sharedBoilerplate = BoilerplateInfo(
'Shared',
'Holds common models and files shared across multiple Dart projects.',
'${RepoLocation}/boilerplate_shared.git');
'$repoLocation/boilerplate_shared.git');
const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo(
const BoilerplateInfo sharedOrmBoilerplate = 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 [
const List<BoilerplateInfo> boilerplates = [
basicBoilerplate,
//legacyBoilerplate,
ormBoilerplate,
ormMySqlBoilerplate,
graphQLBoilerplate,
//sharedBoilerplate,
//sharedOrmBoilerplate,
];
class BoilerplateInfo {
final String name, description, url, ref;
final String name, description, url;
final String 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,7 +3,8 @@ 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:mustache4dart2/mustache4dart2.dart' as mustache;
import 'package:mustache_template/mustache_template.dart' as mustache;
import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart';
@ -11,6 +12,7 @@ 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 =
@ -46,62 +48,66 @@ class InstallCommand extends Command {
}
@override
run() async {
Future 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 `angel install --update` first.';
} else if (argResults!.rest.isNotEmpty) {
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel3 install --update` first.';
}
var pubspec = await loadPubspec();
for (var packageName in argResults.rest) {
for (var packageName in argResults?.rest ?? <String>[]) {
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 `angel install --update`.';
if (!await packageDir.exists()) {
throw 'No add-on named "$packageName" is installed. You might need to run `angel3 install --update`.';
}
print('Installing $packageName...');
Map values = {
var values = {
'project_name': pubspec.name,
'pubspec': pubspec,
};
List<Glob> globs = [];
var globs = <Glob>[];
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;
})
.where((d) => d != null)
.whereType<MakerDependency>()
.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;
}).where((d) => d != null));
}).whereType<MakerDependency>());
await depend(deps);
@ -125,11 +131,11 @@ class InstallCommand extends Command {
var desc = val[key]['description'] ?? key;
if (val[key]['type'] == 'prompt') {
values[key] = prompts.get(desc.toString(),
values[key as String] = prompts.get(desc.toString(),
defaultsTo: val[key]['default']?.toString());
} else if (val[key]['type'] == 'choice') {
values[key] = prompts.choose(
desc.toString(), val[key]['choices'] as Iterable);
values[key as String] = prompts.choose(desc.toString(),
(val[key]['choices'] as Iterable) as Iterable<Object>)!;
}
}
}
@ -151,7 +157,7 @@ class InstallCommand extends Command {
var name = p.basename(entity.path);
var target = dst.uri.resolve(name);
var targetFile = File.fromUri(target);
bool allClear = !await targetFile.exists();
var allClear = !await targetFile.exists();
if (!allClear) {
print('The file ${entity.absolute.path} already exists.');
@ -167,8 +173,10 @@ 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 renderer = mustache.compile(contents);
//var generated = renderer(values);
var template = mustache.Template(contents);
var generated = template.renderString(values);
await targetFile.writeAsString(generated.toString());
} else {
print(
@ -197,9 +205,9 @@ class InstallCommand extends Command {
Future<List<Pubspec>> list() async {
if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.';
throw 'No local add-on database exists. Run `angel3 install --update` first.';
} else {
List<Pubspec> repos = [];
var repos = <Pubspec>[];
await for (var entity in installRepo.list()) {
if (entity is Directory) {
@ -236,7 +244,9 @@ 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 `angel_auth` key.';
String get description => 'Generates a new `angel3_auth` key.';
@override
run() async {
Future 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);
}
changeSecret(File file, String secret) async {
Future 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,59 +30,60 @@ class ControllerCommand extends Command {
}
@override
run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
Future run() async {
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults!['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompts.get('Name of controller class');
}
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
];
//${pubspec.name}.src.models.${rc.snakeCase}
var rc = new ReCase(name);
var controllerLib = new Library((controllerLib) {
if (argResults['websocket'] as bool) {
deps.add(const MakerDependency('angel_websocket', '^2.0.0'));
var rc = ReCase(name!);
var controllerLib = Library((controllerLib) {
if (argResults?['websocket'] as bool) {
deps.add(const MakerDependency('angel3_websocket', '^7.0.0'));
controllerLib.directives
.add(new Directive.import('package:angel_websocket/server.dart'));
.add(Directive.import('package:angel3_websocket/server.dart'));
} else {
controllerLib.directives.add(new Directive.import(
'package:angel_framework/angel_framework.dart'));
controllerLib.directives.add(
Directive.import('package:angel3_framework/angel3_framework.dart'));
}
controllerLib.body.add(new Class((clazz) {
controllerLib.body.add(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(new Constructor((b) {
clazz.constructors.add(Constructor((b) {
b
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'ws'
..type = refer('AngelWebSocket')))
..initializers.add(new Code('super(ws)'));
..initializers.add(Code('super(ws)'));
}));
clazz.methods.add(new Method((meth) {
clazz.methods.add(Method((meth) {
meth
..name = 'hello'
..returns = refer('void')
..annotations
.add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')]))
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'socket'
..type = refer('WebSocketContext')))
..body = new Block((block) {
..body = Block((block) {
block.addExpression(refer('socket').property('send').call([
literal('got_${rc.snakeCase}'),
literalMap({'message': literal('Hello, world!')}),
@ -93,7 +94,7 @@ class ControllerCommand extends Command {
clazz
..annotations
.add(refer('Expose').call([literal('/${rc.snakeCase}')]))
..methods.add(new Method((meth) {
..methods.add(Method((meth) {
meth
..name = 'hello'
..returns = refer('String')
@ -106,14 +107,15 @@ class ControllerCommand extends Command {
}));
});
var outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
var controllerFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists())
File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists()) {
await controllerFile.create(recursive: true);
await controllerFile.writeAsString(new DartFormatter()
.format(controllerLib.accept(new DartEmitter()).toString()));
}
await controllerFile.writeAsString(
DartFormatter().format(controllerLib.accept(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,10 +18,11 @@ 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);
@ -51,11 +52,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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart';
@ -28,21 +28,23 @@ class MigrationCommand extends Command {
@override
FutureOr run() async {
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class');
}
var deps = [const MakerDependency('angel_migration', '^2.0.0')];
var rc = new ReCase(name);
var deps = [const MakerDependency('angel3_migration', '^7.0.0')];
var rc = ReCase(name!);
var migrationLib = new Library((migrationLib) {
var migrationLib = Library((migrationLib) {
migrationLib
..directives.add(new Directive.import(
'package:angel_migration.dart/angel_migration.dart'))
..body.add(new Class((migrationClazz) {
..directives.add(Directive.import(
'package:angel3_migration.dart/angel3_migration.dart'))
..body.add(Class((migrationClazz) {
migrationClazz
..name = '${rc.pascalCase}Migration'
..extend = refer('Migration');
@ -50,21 +52,21 @@ class MigrationCommand extends Command {
var tableName = pluralize(rc.snakeCase);
// up()
migrationClazz.methods.add(new Method((up) {
migrationClazz.methods.add(Method((up) {
up
..name = 'up'
..returns = refer('void')
..annotations.add(refer('override'))
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'schema'
..type = refer('Schema')))
..body = new Block((block) {
..body = Block((block) {
// (table) { ... }
var callback = new Method((callback) {
var callback = Method((callback) {
callback
..requiredParameters
.add(new Parameter((b) => b..name = 'table'))
..body = new Block((block) {
.add(Parameter((b) => b..name = 'table'))
..body = Block((block) {
var table = refer('table');
block.addExpression(
@ -95,15 +97,15 @@ class MigrationCommand extends Command {
}));
// down()
migrationClazz.methods.add(new Method((down) {
migrationClazz.methods.add(Method((down) {
down
..name = 'down'
..returns = refer('void')
..annotations.add(refer('override'))
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'schema'
..type = refer('Schema')))
..body = new Block((block) {
..body = Block((block) {
block.addExpression(
refer('schema').property('drop').call([
literal(tableName),
@ -115,15 +117,16 @@ class MigrationCommand extends Command {
});
// Save migration file
var migrationDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var migrationDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
var migrationFile =
new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists())
File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists()) {
await migrationFile.create(recursive: true);
}
await migrationFile.writeAsString(new DartFormatter()
.format(migrationLib.accept(new DartEmitter()).toString()));
await migrationFile.writeAsString(
DartFormatter().format(migrationLib.accept(DartEmitter()).toString()));
print(green.wrap(
'$checkmark Created migration file "${migrationFile.absolute.path}".'));

View file

@ -32,37 +32,39 @@ class ModelCommand extends Command {
}
@override
run() async {
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
Future run() async {
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class');
}
List<MakerDependency> deps = [
const MakerDependency('angel_model', '^1.0.0'),
var deps = <MakerDependency>[
const MakerDependency('angel3_model', '^3.0.0'),
];
var rc = new ReCase(name);
var rc = ReCase(name!);
var modelLib = new Library((modelLib) {
if (argResults['orm'] as bool && argResults['migration'] as bool) {
var modelLib = Library((modelLib) {
if (argResults?['orm'] as bool && argResults?['migration'] as bool) {
modelLib.directives.addAll([
new Directive.import('package:angel_migration/angel_migration.dart'),
Directive.import('package:angel3_migration/angel3_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(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'));
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'));
}
// else {
@ -71,18 +73,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([
new Directive.import('package:angel_orm/angel_orm.dart'),
Directive.import('package:angel3_orm/angel3_orm.dart'),
]);
deps.add(const MakerDependency('angel_orm', '^2.0.0'));
deps.add(const MakerDependency('angel3_orm', '^7.0.0'));
}
modelLib.body.addAll([
new Code("part '${rc.snakeCase}.g.dart';"),
Code("part '${rc.snakeCase}.g.dart';"),
]);
modelLib.body.add(new Class((modelClazz) {
modelLib.body.add(Class((modelClazz) {
modelClazz
..abstract = true
..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
@ -93,8 +95,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(
@ -105,14 +107,13 @@ class ModelCommand extends Command {
});
// Save model file
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'));
var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
var modelFile = File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await modelFile.exists()) await modelFile.create(recursive: true);
await modelFile.writeAsString(new DartFormatter()
.format(modelLib.accept(new DartEmitter()).toString()));
await modelFile.writeAsString(
DartFormatter().format(modelLib.accept(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,27 +25,29 @@ class PluginCommand extends Command {
}
@override
run() async {
Future run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompts.get('Name of plug-in class');
}
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
];
var rc = new ReCase(name);
final pluginDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var rc = ReCase(name!);
final pluginDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
final pluginFile =
new File.fromUri(pluginDir.uri.resolve("${rc.snakeCase}.dart"));
File.fromUri(pluginDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await pluginFile.exists()) await pluginFile.create(recursive: true);
await pluginFile.writeAsString(
new DartFormatter().format(_generatePlugin(pubspec, rc)));
await pluginFile
.writeAsString(DartFormatter().format(_generatePlugin(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps);
@ -57,7 +59,7 @@ class PluginCommand extends Command {
return '''
library ${pubspec.name}.src.config.plugins.${rc.snakeCase};
import 'package:angel_framework/angel_framework.dart';
import 'package:angel3_framework/angel3_framework.dart';
AngelConfigurer ${rc.camelCase}() {
return (Angel app) async {

View file

@ -2,10 +2,9 @@ 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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.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';
@ -32,24 +31,26 @@ class ServiceCommand extends Command {
}
@override
run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
void run() async {
await loadPubspec();
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompts.get('Name of service');
}
List<MakerDependency> deps = [
const MakerDependency('angel_framework', '^2.0.0')
var deps = <MakerDependency>[
const MakerDependency('angel3_framework', '^7.0.0')
];
// '${pubspec.name}.src.services.${rc.snakeCase}'
var rc = new ReCase(name);
var serviceLib = new Library((serviceLib) {
var rc = ReCase(name!);
var serviceLib = 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();
@ -62,56 +63,61 @@ class ServiceCommand extends Command {
if (!deps.any((d) => d.name == dep.name)) deps.add(dep);
}
if (generator.goesFirst) {
if (name != null && generator.goesFirst) {
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
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'));
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'));
generator.applyToLibrary(serviceLib, name, rc.snakeCase);
}
if (argResults['typed'] as bool) {
if (argResults!['typed'] as bool) {
serviceLib.directives
.add(new Directive.import('../models/${rc.snakeCase}.dart'));
.add(Directive.import('../models/${rc.snakeCase}.dart'));
}
// configureServer() {}
serviceLib.body.add(new Method((configureServer) {
serviceLib.body.add(Method((configureServer) {
configureServer
..name = 'configureServer'
..returns = refer('AngelConfigurer');
configureServer.body = new Block((block) {
generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
configureServer.body = Block((block) {
if (name != null) {
generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
}
// return (Angel app) async {}
var closure = new Method((closure) {
var closure = Method((closure) {
closure
..modifier = MethodModifier.async
..requiredParameters.add(new Parameter((b) => b
..requiredParameters.add(Parameter((b) => b
..name = 'app'
..type = refer('Angel')));
closure.body = new Block((block) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
// app.use('/api/todos', new MapService());
var service = generator.createInstance(
serviceLib, closure, name, rc.snakeCase);
closure.body = Block((block) {
if (name != null) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
if (argResults['typed'] as bool) {
var tb = new TypeReference((b) => b
..symbol = 'TypedService'
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]);
// 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,
]));
}
block.addExpression(refer('app').property('use').call([
literal('/api/${pluralize(rc.snakeCase)}'),
service,
]));
});
});
@ -120,13 +126,13 @@ class ServiceCommand extends Command {
}));
});
final outputDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
final outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults!['output-dir'] as String));
final serviceFile =
new File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart"));
File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await serviceFile.exists()) await serviceFile.create(recursive: true);
await serviceFile.writeAsString(new DartFormatter()
.format(serviceLib.accept(new DartEmitter()).toString()));
await serviceFile.writeAsString(
DartFormatter().format(serviceLib.accept(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,37 +28,39 @@ class TestCommand extends Command {
}
@override
run() async {
Future run() async {
var pubspec = await loadPubspec();
String name;
if (argResults.wasParsed('name')) name = argResults['name'] as String;
String? name;
if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) {
name = prompter.get('Name of test');
}
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 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),
];
var rc = new ReCase(name);
final testDir = new Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String));
var rc = ReCase(name!);
final testDir = Directory.fromUri(
Directory.current.uri.resolve(argResults?['output-dir'] as String));
final testFile =
new File.fromUri(testDir.uri.resolve("${rc.snakeCase}_test.dart"));
File.fromUri(testDir.uri.resolve('${rc.snakeCase}_test.dart'));
if (!await testFile.exists()) await testFile.create(recursive: true);
await testFile
.writeAsString(new DartFormatter().format(_generateTest(pubspec, rc)));
.writeAsString(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 = new File.fromUri(Directory.current.uri
if (argResults!['run-configuration'] as bool) {
final runConfig = File.fromUri(Directory.current.uri
.resolve('.idea/runConfigurations/${name}_Tests.xml'));
if (!await runConfig.exists()) await runConfig.create(recursive: true);
@ -85,15 +87,15 @@ class TestCommand extends Command {
return '''
import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart' as ${pubspec.name};
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_test/angel_test.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_test/angel3_test.dart';
import 'package:test/test.dart';
main() async {
TestClient client;
setUp(() async {
var app = new Angel();
var app = Angel();
await app.configure(${pubspec.name}.configureServer);
client = await connectTo(app);
});

View file

@ -2,11 +2,13 @@ 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,8 +8,6 @@ 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
@ -22,16 +20,16 @@ class RenameCommand extends Command {
String get invocation => '$name <new name>';
@override
run() async {
String newName;
Future run() async {
String? newName;
if (argResults.rest.isNotEmpty)
newName = argResults.rest.first;
else {
if (argResults?.rest.isNotEmpty == true) {
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`?');
@ -63,7 +61,7 @@ class RenameCommand extends Command {
}
}
renamePubspec(Directory dir, String oldName, String newName) async {
Future renamePubspec(Directory dir, String oldName, String newName) async {
// var pubspec = await loadPubspec(dir);
print(cyan.wrap('Renaming your project to `$newName.`'));
@ -86,13 +84,13 @@ renamePubspec(Directory dir, String oldName, String newName) async {
// await newPubspec.save(dir);
}
renameDartFiles(Directory dir, String oldName, String newName) async {
Future renameDartFiles(Directory dir, String oldName, String newName) async {
if (!await dir.exists()) return;
// Try to replace MongoDB URL
var configGlob = Glob('config/**/*.yaml');
// Replace name in config directory
try {
var configGlob = Glob('config/**/*.yaml');
await for (var yamlFile in configGlob.list(root: dir.absolute.path)) {
if (yamlFile is File) {
print(
@ -113,12 +111,58 @@ 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);
@ -128,7 +172,7 @@ 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);
}
@ -139,6 +183,7 @@ renameDartFiles(Directory dir, String oldName, String newName) async {
}
}
}
*/
}
class RenamingVisitor extends RecursiveAstVisitor {
@ -153,41 +198,49 @@ 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
visitExportDirective(ExportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitImportDirective(ImportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitLibraryDirective(LibraryDirective ctx) {
var name = ctx.name.name;
if (name.startsWith(oldName)) {
replace[[ctx.offset, ctx.end]] =
'library ' + name.replaceFirst(oldName, newName) + ';';
}
}
@override
visitPartOfDirective(PartOfDirective ctx) {
if (ctx.libraryName != null) {
var name = ctx.libraryName.name;
void visitExportDirective(ExportDirective node) {
var uri = node.uri.stringValue;
if (uri != null) {
var 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;
}
}
@override
void visitLibraryDirective(LibraryDirective node) {
var name = node.name2?.name ?? '';
if (name.startsWith(oldName)) {
replace[[node.offset, node.end]] =
'library ${name.replaceFirst(oldName, newName)};';
}
}
@override
void visitPartOfDirective(PartOfDirective node) {
if (node.libraryName != null) {
var name = node.libraryName!.name;
if (name.startsWith(oldName)) {
replace[[ctx.offset, ctx.end]] =
'part of ' + name.replaceFirst(oldName, newName) + ';';
replace[[node.offset, node.end]] =
'part of ${name.replaceFirst(oldName, newName)};';
}
}
}

View file

@ -2,10 +2,8 @@ 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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class FileServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_file_service', '^2.0.0')];
const [MakerDependency('angel3_file_service', '^7.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(new Parameter((b) => b
configureServer.requiredParameters.add(Parameter((b) => b
..name = 'dbDirectory'
..type = refer('Directory')));
}
@ -28,8 +28,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
new Directive.import(
'package:angel_file_service/angel_file_service.dart'),
Directive.import('package:angel3_file_service/angel3_file_service.dart'),
]);
}
@ -37,12 +36,12 @@ class FileServiceGenerator extends ServiceGenerator {
Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder,
String name, String lower) {
library.directives.addAll([
new Directive.import('package:file/file.dart'),
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,21 +8,6 @@ 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,7 +4,6 @@ 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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class MongoServiceGenerator extends ServiceGenerator {
@ -8,9 +8,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_mongo', '^2.0.0')];
const [MakerDependency('angel3_mongo', '^4.0.0')];
@override
bool get createsModel => false;
@override
@ -18,9 +17,9 @@ class MongoServiceGenerator extends ServiceGenerator {
LibraryBuilder library,
MethodBuilder configureServer,
BlockBuilder block,
String name,
String? name,
String lower) {
configureServer.requiredParameters.add(new Parameter((b) => b
configureServer.requiredParameters.add(Parameter((b) => b
..name = 'db'
..type = refer('Db')));
}
@ -28,8 +27,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
new Directive.import('package:angel_mongo/angel_mongo.dart'),
new Directive.import('package:mongo_dart/mongo_dart.dart'),
Directive.import('package:angel3_mongo/angel3_mongo.dart'),
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:inflection2/inflection2.dart';
import 'package:inflection3/inflection3.dart';
import '../make/maker.dart';
class RethinkServiceGenerator extends ServiceGenerator {
@ -8,9 +8,8 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override
List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_rethink', '^2.0.0')];
const [MakerDependency('angel3_rethink', '^4.0.0')];
@override
bool get createsModel => false;
@override
@ -18,13 +17,13 @@ class RethinkServiceGenerator extends ServiceGenerator {
LibraryBuilder library,
MethodBuilder configureServer,
BlockBuilder block,
String name,
String? name,
String lower) {
configureServer.requiredParameters.addAll([
new Parameter((b) => b
Parameter((b) => b
..name = 'connection'
..type = refer('Connection')),
new Parameter((b) => b
Parameter((b) => b
..name = 'r'
..type = refer('Rethinkdb')),
]);
@ -33,9 +32,9 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override
void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([
'package:angel_rethink/angel_rethink.dart',
'package:angel3_rethink/angel3_rethink.dart',
'package:rethinkdb_dart/rethinkdb_dart.dart'
].map((str) => new Directive.import(str)));
].map((str) => Directive.import(str)));
}
@override

View file

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

View file

@ -7,7 +7,7 @@ final Random _rnd = Random.secure();
String randomAlphaNumeric(int length) {
var b = StringBuffer();
for (int i = 0; i < length; i++) {
for (var 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 => new Directory(homeDirPath);
Directory get homeDir => 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 = new File.fromUri(directory.uri.resolve('pubspec.yaml'));
var file = File.fromUri(directory.uri.resolve('pubspec.yaml'));
return file
.readAsString()
.then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri));
.then((yaml) => Pubspec.parse(yaml, sourceUrl: file.uri));
}
// From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a

View file

@ -1,27 +1,29 @@
#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
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
environment:
sdk: ">=2.10.0 <3.0.0"
sdk: '>=3.0.0 <4.0.0'
dependencies:
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
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
executables:
angel: angel
angel3: angel3

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

53
test/replace_name.dart Normal file
View file

@ -0,0 +1,53 @@
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}`.');
}
}
}
}