Merge pull request #3966 from zexi/feature/list-base-input

add list input and rewrite codegen use python
This commit is contained in:
yunion-ci-robot
2019-11-29 10:27:29 +08:00
committed by GitHub
11 changed files with 434 additions and 124 deletions
+4 -4
View File
@@ -240,7 +240,7 @@ gen-model-api-check:
which swagger-gen || (GO111MODULE=off go get -u github.com/yunionio/code-generator/cmd/model-api-gen)
gen-model-api:
./scripts/codegen.sh model_api
./scripts/codegen.py model-api
gen-swagger-check:
which swagger || (GO111MODULE=off go get -u github.com/go-swagger/go-swagger/cmd/swagger)
@@ -248,8 +248,8 @@ gen-swagger-check:
which swagger-serve || (GO111MODULE=off go get -u github.com/yunionio/code-generator/cmd/swagger-serve)
gen-swagger: gen-swagger-check
./scripts/codegen.sh swagger_spec
./scripts/codegen.sh swagger_yaml
./scripts/codegen.py swagger-code
./scripts/codegen.py swagger-yaml
swagger-serve: gen-swagger
./scripts/codegen.sh swagger_serve
./scripts/codegen.py swagger-serve
+1
View File
@@ -46,5 +46,6 @@ type BucketCreateInput struct {
}
type BucketDetail struct {
apis.Meta
SBucket
}
+49
View File
@@ -18,6 +18,55 @@ import (
"yunion.io/x/onecloud/pkg/apis"
)
type ServerListInput struct {
apis.BaseListInput
// 过滤可用区底下的资源
Zone string `json:"zone"`
// 过滤连接此二层网络的资源
Wire string `json:"wire"`
// 过滤关联此网络的资源
Network string `json:"network"`
// Disk ID or Name
Disk string `json:"disk"`
// Host ID or Name
Host string `json:"host"`
// Show baremetal servers
Baremetal *bool `json:"baremetal"`
// Show gpu servers
Gpu *bool `json:"gpu"`
// Secgroup ID or Name
Secgroup string `json:"secgroup"`
// AdminSecgroup ID or Name
AdminSecgroup string `json:"admin_security"`
// Show server of hypervisor choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack|openstack"`
Hypervisor string `json:"hypervisor"`
// Show servers in cloudregion
Region string `json:"region"`
// Show Servers with EIP
WithEip *bool `json:"with_eip"`
// Show Servers without EIP
WithoutEip *bool `json:"without_eip"`
// OS Type choices:"linux|windows|vmware"`
OsType string `json:"os_type"`
// Order by disk size choices:"asc|desc"
OrderByDisk string `json:"order_by_disk"`
// Order by host name choices:"asc|desc"
OrderByHost string `json:"order_by_host"`
// Vpc id or name
Vpc string `json:"vpc"`
// Eip id or name
UsableServerForEip string `json:"usable_server_for_eip"`
// Show Servers without user metadata
WithoutUserMeta *bool `json:"without_user_meta"`
// Instance Group ID or Name
Group string `json:"group"`
// Resource type choices:"shared|prepaid|dedicated"
ResourceType string `json:"resource_type"`
// Billing type choices:"postpaid|prepaid"
BillingType string `json:"billing_type"`
}
type ServerRebuildRootInput struct {
apis.Meta
+22
View File
@@ -0,0 +1,22 @@
package compute
import "yunion.io/x/onecloud/pkg/apis"
type InstanceGroupListInput struct {
apis.BaseListInput
// Filter by service type
ServiceType string `json:"service_type"`
// Filter by parent id
ParentId string `json:"parent_id"`
// Filter by zone id
ZoneId string `json:"zone_id"`
// Filter by guest id or name
Guest string `json:"guest"`
}
type InstanceGroupDetail struct {
apis.Meta
SGroup
GuestCount int64 `json:"guest_count"`
}
+25 -5
View File
@@ -190,7 +190,7 @@ type SDBInstance struct {
SManagedResourceBase
SBillingResourceBase
SCloudregionResourceBase
DisableDelete *bool `json:"disable_delete,omitempty"`
SDeletePreventableResourceBase
MasterInstanceId string `json:"master_instance_id"`
VcpuCount int `json:"vcpu_count"`
VmemSizeMb int `json:"vmem_size_mb"`
@@ -214,7 +214,7 @@ type SDBInstance struct {
// SDBInstanceAccount is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SDBInstanceAccount.
type SDBInstanceAccount struct {
apis.SVirtualResourceBase
apis.SStatusStandaloneResourceBase
apis.SExternalizedResourceBase
Secret string `json:"secret"`
DBInstanceId string `json:"db_instance_id"`
@@ -238,7 +238,7 @@ type SDBInstanceBackup struct {
// SDBInstanceDatabase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SDBInstanceDatabase.
type SDBInstanceDatabase struct {
apis.SVirtualResourceBase
apis.SStatusStandaloneResourceBase
apis.SExternalizedResourceBase
CharacterSet string `json:"character_set"`
DBInstanceId string `json:"db_instance_id"`
@@ -301,6 +301,11 @@ type SDBInstanceSku struct {
ZoneId string `json:"zone_id"`
}
// SDeletePreventableResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SDeletePreventableResourceBase.
type SDeletePreventableResourceBase struct {
DisableDelete *bool `json:"disable_delete,omitempty"`
}
// SDisk is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SDisk.
type SDisk struct {
apis.SSharableVirtualResourceBase
@@ -340,10 +345,10 @@ type SElasticcache struct {
apis.SExternalizedResourceBase
SBillingResourceBase
SManagedResourceBase
SDeletePreventableResourceBase
SCloudregionResourceBase
SZoneResourceBase
SlaveZones string `json:"slave_zones"`
DisableDelete *bool `json:"disable_delete,omitempty"`
InstanceType string `json:"instance_type"`
CapacityMB int `json:"capacity_mb"`
LocalCategory string `json:"local_category"`
@@ -466,6 +471,21 @@ type SExternalProject struct {
apis.SExternalizedResourceBase
}
// SGlobalNetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGlobalNetwork.
type SGlobalNetwork struct {
apis.SEnabledStatusStandaloneResourceBase
apis.SExternalizedResourceBase
SManagedResourceBase
Provider string `json:"provider"`
}
// SGlobalnetworkVpc is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGlobalnetworkVpc.
type SGlobalnetworkVpc struct {
apis.SJointResourceBase
GlobalnetworkId string `json:"globalnetwork_id"`
VpcId string `json:"vpc_id"`
}
// SGroup is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGroup.
type SGroup struct {
apis.SVirtualResourceBase
@@ -505,10 +525,10 @@ type SGuest struct {
apis.SVirtualResourceBase
apis.SExternalizedResourceBase
SBillingResourceBase
SDeletePreventableResourceBase
VcpuCount int `json:"vcpu_count"`
VmemSize int `json:"vmem_size"`
BootOrder string `json:"boot_order"`
DisableDelete *bool `json:"disable_delete,omitempty"`
ShutdownBehavior string `json:"shutdown_behavior"`
KeypairId string `json:"keypair_id"`
HostId string `json:"host_id"`
+77
View File
@@ -0,0 +1,77 @@
package apis
type BaseListInput struct {
Meta
// 查询限制量
// default: 20
Limit *int `json:"limit"`
// 查询偏移量
// default: 0
Offset *int `json:"offset"`
// Name of the field to be ordered by
OrderBy []string `json:"order_by"`
// List Order
// example: desc|asc
Order string
// Show more details
Details *bool `json:"details"`
// Filter results by a simple keyword search
Search string `json:"search"`
// Piggyback metadata information
WithMeta *bool `json:"with_meta"`
// Filters
Filter []string `json:"filters"`
// Filters with joint table col; joint_tbl.related_key(origin_key).filter_col.filter_cond(filters)
JointFilter []string `json:"joint_filter"`
// If true, match if any of the filters matches; otherwise, match if all of the filters match
FilterAny *bool `json:"filter_any"`
// Is an admin call?
Admin *bool `json:"admin"`
// Tenant ID or Name
Tenant string `json:"tenant"`
// Project domain filter
ProjectDomain string `json:"project_domain"`
// User ID or Name
User string `json:"user"`
// Show only specified fields
Field []string `json:"field"`
// Specify query scope, either project, domain or system
Scope string `json:"scope"`
// Show system resource
System *bool `json:"system"`
// Show only pending deleted resource
PendingDelete *bool `json:"pending_delete"`
// Show all resources including pending deleted
// TODO: fix this???
PendingDeleteAll *bool `json:"-"`
// Show all resources including the emulated resources
ShowEmulated *bool `json:"show_emulated"`
// Export field keys
ExportKeys string `json:"export_keys"`
// TODO: support this tags
// Tags []string `help:"Tags info, eg: hypervisor=aliyun, os_type=Linux, os_version" json:"-"`
// UserTags []string `help:"UserTags info, eg: group=rd" json:"-"`
// CloudTags []string `help:"CloudTags info, eg: price_key=cn-beijing" json:"-"`
// List objects belonging to the cloud provider
Manager string `json:"manager,omitempty"`
// List objects belonging to the cloud account
Account string `json:"account,omitempty"`
// List objects from the provider, choices:"OneCloud|VMware|Aliyun|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack"
Provider []string `json:"provider,omitempty"`
// List objects belonging to a special brand
Brand []string `json:"brand"`
// Cloud environment, choices:"public|private|onpremise|private_or_onpremise"
CloudEnv string `json:"cloud_env,omitempty"`
// List objects belonging to public cloud
PublicCloud *bool `json:"public_cloud"`
// List objects belonging to private cloud
PrivateCloud *bool `json:"private_cloud"`
// List objects belonging to on premise infrastructures
IsOnPremise *bool `json:"is_on_premise"`
// List objects managed by external providers
IsManaged *bool `json:"is_managed"`
// Marker for pagination
PagingMarker string `json:"paging_marker"`
}
+3 -3
View File
@@ -724,15 +724,15 @@ func getItemDetails(manager IModelManager, item IModel, ctx context.Context, use
jsonDict := jsonutils.Marshal(item).(*jsonutils.JSONDict)
jsonDict = jsonDict.CopyIncludes(getFields...)
jsonDict.Update(extraDict)
extraDict.Update(jsonDict)
// jsonDict = getModelExtraDetails(item, ctx, jsonDict)
extraRows := manager.FetchCustomizeColumns(ctx, userCred, query, []IModel{item}, stringutils2.NewSortedStrings(fieldFilter))
if len(extraRows) == 1 {
jsonDict.Update(extraRows[0])
extraDict.Update(extraRows[0])
}
return jsonDict, nil
return extraDict, nil
}
func (dispatcher *DBModelDispatcher) tryGetModelProperty(ctx context.Context, property string, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
+11 -8
View File
@@ -27,6 +27,7 @@ import (
"yunion.io/x/pkg/util/sets"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -73,9 +74,8 @@ type SGroup struct {
}
func (sm *SGroupManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential,
query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
guestFilter := jsonutils.GetAnyString(query, []string{"server", "guest"})
input *api.InstanceGroupListInput) (*sqlchemy.SQuery, error) {
guestFilter := input.Guest
if len(guestFilter) != 0 {
guestObj, err := GuestManager.FetchByIdOrName(userCred, guestFilter)
if err != nil {
@@ -91,11 +91,11 @@ func (group *SGroup) GetCustomizeColumns(ctx context.Context, userCred mcclient.
query jsonutils.JSONObject) *jsonutils.JSONDict {
extra := group.SVirtualResourceBase.GetCustomizeColumns(ctx, userCred, query)
ret, _ := group.getMoreDetails(ctx, userCred, extra)
return ret
return ret.JSON(ret)
}
func (group *SGroup) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential,
query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
query jsonutils.JSONObject) (*api.InstanceGroupDetail, error) {
extra, err := group.SVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
if err != nil {
return nil, err
@@ -104,12 +104,15 @@ func (group *SGroup) GetExtraDetails(ctx context.Context, userCred mcclient.Toke
}
func (group *SGroup) getMoreDetails(ctx context.Context, userCred mcclient.TokenCredential,
query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
ret := query.(*jsonutils.JSONDict)
data jsonutils.JSONObject) (*api.InstanceGroupDetail, error) {
ret := data.(*jsonutils.JSONDict)
q := GroupguestManager.Query().Equals("group_id", group.Id)
count, _ := q.CountWithError()
ret.Add(jsonutils.NewInt(int64(count)), "guest_count")
return ret, nil
output := new(api.InstanceGroupDetail)
data.Unmarshal(ret)
log.Errorf("output is %#v", output)
return output, nil
}
func (group *SGroup) ValidateDeleteCondition(ctx context.Context) error {
+1
View File
@@ -127,6 +127,7 @@ func (manager *SGuestManager) AllowListItems(ctx context.Context, userCred mccli
return manager.SVirtualResourceBaseManager.AllowListItems(ctx, userCred, query)
}
// 按指定条件列出云主机实例
func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
queryDict, ok := query.(*jsonutils.JSONDict)
if !ok {
+241
View File
@@ -0,0 +1,241 @@
#!/usr/bin/env python
import argparse
import os
from os.path import join as pjoin
import subprocess
import sys
def run_cmd(cmds):
print(' '.join(cmds))
proc = subprocess.Popen(
cmds, stdout=subprocess.PIPE)
while True:
line_gen = proc.stdout.readline().rstrip()
if not line_gen:
break
for l in line_gen:
print(l)
def run_generator(tool, input_dirs, out_pkg):
cmd = [tool]
for i in input_dirs:
cmd.extend(["--input-dirs", i])
cmd.extend(["--output-package", out_pkg])
run_cmd(cmd)
def run_model_api(input_dirs, out_pkg):
return run_generator('model-api-gen', input_dirs, out_pkg)
def run_swagger_gen(input_dirs, out_pkg):
return run_generator('swagger-gen', input_dirs, out_pkg)
def run_swagger_serve(output_dir):
def is_swagger_yaml(file):
return file.endswith('.yaml') and file.startswith('swagger')
yamls = [pjoin(output_dir, x) for x in os.listdir(output_dir) if is_swagger_yaml(x)]
cmd = ['swagger-serve', 'generate']
cmd.extend(['-i', ','.join(yamls), '-o', output_dir])
cmd.append('--serve')
run_cmd(cmd)
def run_swagger_yaml(svc, swagger_pkg_dir, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
work_dir = pjoin(swagger_pkg_dir, svc)
cmd = ["swagger", "generate", "spec", "--scan-models"]
cmd.extend(["--work-dir", work_dir])
cmd.extend(["-o", pjoin(output_dir, "swagger_%s.yaml" % svc)])
run_cmd(cmd)
class FuncDispatcher(object):
def __init__(self):
self.gen_dict = {}
self.collect_funcs()
def collect_funcs(self):
gen_dict = {}
for attr in dir(self):
if not attr.startswith('gen_'):
continue
func = getattr(self, attr)
if not callable(func):
continue
svc = attr.lstrip('gen_')
gen_dict[svc] = func
self.gen_dict = gen_dict
def get_choices(self):
svc = ["all"]
svc.extend(self.gen_dict.keys())
return svc
def dispatcher(self, opt):
def run_one(key):
self.gen_dict[key]()
def run_all():
for key in self.gen_dict:
run_one(key)
if opt.service is None or 'all' in opt.service:
run_all()
else:
for svc in opt.service:
run_one(svc)
def get_parser(self, subparsers, name, help):
parser = subparsers.add_parser(name, help=help)
parser.add_argument("-s", "--service", help="%s for services" % help,
nargs='+', choices=self.get_choices())
parser.set_defaults(func=self.dispatcher)
class ModelAPI(FuncDispatcher):
def __init__(self, pkg_dir, apis_dir):
super(ModelAPI, self).__init__()
self.pkg_dir = pkg_dir
self.apis_dir = apis_dir
def get_parser(self, subparsers):
return super(ModelAPI, self).get_parser(
subparsers, "model-api", "generate model struct code for api")
def run(self, pkg=[], out=[]):
if pkg is None:
return
in_dir = pjoin(self.pkg_dir, *pkg)
out_dir = pjoin(self.apis_dir, *out)
run_model_api([in_dir], out_dir)
def run_same(self, pkg):
self.run(pkg=[pkg], out=[pkg])
def run_model(self, svc):
self.run(pkg=[svc, "models"], out=[svc])
def gen_cloudcommon(self):
self.run(pkg=["cloudcommon", "db"])
def gen_cloudprovider(self):
self.run_same("cloudprovider")
def gen_compute(self):
self.run_model("compute")
def gen_image(self):
self.run_model("image")
def gen_identity(self):
self.run(pkg=["keystone", "models"], out=["identity"])
class SwaggerCode(FuncDispatcher):
def __init__(self, pkg_dir, pkg_swagger):
super(SwaggerCode, self).__init__()
self.pkg_dir = pkg_dir
self.pkg_swagger = pkg_swagger
def get_parser(self, subparsers):
return super(SwaggerCode, self).get_parser(
subparsers, "swagger-code", "generate swagger code")
def run(self, svc, pkg=[], out=''):
if svc is None:
return
if pkg is None:
return
svc_pkg_dir = pjoin(self.pkg_dir, svc)
input_dirs = [pjoin(svc_pkg_dir, x) for x in pkg]
out_dir = pjoin(self.pkg_swagger, out)
run_swagger_gen(input_dirs, out_dir)
def run_svc(self, svc, pkg=[]):
self.run(svc, pkg=pkg, out=svc)
def gen_identity(self):
self.run("keystone", pkg=["tokens", "models"], out="identity")
def gen_compute(self):
self.run_svc("compute", pkg=["models"])
def gen_image(self):
self.run_svc("image", pkg=["models"])
class SwaggerYAML(FuncDispatcher):
def __init__(self, swagger_dir, out_dir):
super(SwaggerYAML, self).__init__()
self.swagger_dir = swagger_dir
self.out_dir = out_dir
def get_parser(self, subparsers):
return super(SwaggerYAML, self).get_parser(
subparsers, "swagger-yaml", "generate swagger yaml")
def run(self, svc):
run_swagger_yaml(svc, self.swagger_dir, self.out_dir)
def gen_identity(self):
self.run("identity")
def gen_compute(self):
self.run("compute")
def gen_image(self):
self.run("image")
class SwaggerServe(object):
def __init__(self, output_dir):
self.output_dir = output_dir
def get_parser(self, subparsers):
parser = subparsers.add_parser(
"swagger-serve", help="generate swagger web site")
parser.set_defaults(func=self.run)
def run(self, opt):
run_swagger_serve(self.output_dir)
if __name__ == "__main__":
ONECLOUD="yunion.io/x/onecloud"
PKG_ONECLOUD=pjoin(ONECLOUD, "pkg")
PKG_APIS=pjoin(PKG_ONECLOUD, "apis")
PKG_GENERATED=pjoin(PKG_ONECLOUD, "generated")
PKG_SWAGGER=pjoin(PKG_GENERATED, "swagger")
SCRIPTS_DIR=os.path.dirname(os.path.realpath(__file__))
CUR_DIR=os.path.dirname(SCRIPTS_DIR)
SWAGGER_PKG=pjoin(CUR_DIR, "pkg", "generated", "swagger")
OUTPUT_DIR=pjoin(CUR_DIR, "_output")
OUTPUT_SWAGGER_DIR=pjoin(OUTPUT_DIR, "swagger")
model_api = ModelAPI(PKG_ONECLOUD, PKG_APIS)
swagger_yaml = SwaggerYAML(SWAGGER_PKG, OUTPUT_SWAGGER_DIR)
swagger_code = SwaggerCode(PKG_ONECLOUD, PKG_SWAGGER)
swagger_serve = SwaggerServe(OUTPUT_SWAGGER_DIR)
parser = argparse.ArgumentParser(description="Code generate helper.")
subparsers = parser.add_subparsers(dest='cmd')
subparsers.required = True
for cmd in [model_api, swagger_code, swagger_yaml, swagger_serve]:
cmd.get_parser(subparsers)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
options = parser.parse_args()
options.func(options)
-104
View File
@@ -1,104 +0,0 @@
#!/bin/bash
set -o errexit
set -o pipefail
ONECLOUD="yunion.io/x/onecloud"
PKG_ONECLOUD="$ONECLOUD/pkg"
PKG_APIS="$PKG_ONECLOUD/apis"
PKG_GENERATED="$PKG_ONECLOUD/generated"
PKG_SWAGGER="$PKG_GENERATED/swagger"
MODEL_API_PKG_MAP=(
"$PKG_ONECLOUD/cloudcommon/db:$PKG_APIS"
"$PKG_ONECLOUD/cloudprovider:$PKG_APIS/cloudprovider"
"$PKG_ONECLOUD/compute/models:$PKG_APIS/compute"
"$PKG_ONECLOUD/image/models:$PKG_APIS/image"
"$PKG_ONECLOUD/keystone/models:$PKG_APIS/identity"
)
MODEL_SWAGGER_PKG_MAP=(
"$PKG_ONECLOUD/compute/models:$PKG_SWAGGER/compute"
"$PKG_ONECLOUD/image/models:$PKG_SWAGGER/image"
"$PKG_ONECLOUD/keystone/models:$PKG_SWAGGER/identity"
)
CURDIR="$(dirname $(dirname $0))"
DOCS_DIR="$CURDIR/docs"
OUTPUT_DIR="$CURDIR/_output"
OUTPUT_SWAGGER_DIR="$OUTPUT_DIR/swagger"
generate_model_api() {
for pkg_path in "${MODEL_API_PKG_MAP[@]}"; do
model_pkg="${pkg_path%%:*}"
api_pkg="${pkg_path##*:}"
model-api-gen \
--input-dirs $model_pkg \
--output-package $api_pkg
done
}
generate_swagger_spec() {
# for pkg_path in "${MODEL_SWAGGER_PKG_MAP[@]}"; do
# model_pkg="${pkg_path%%:*}"
# swaager_pkg="${pkg_path##*:}"
# swagger-gen \
# --input-dirs $model_pkg \
# --output-package $swaager_pkg
# done
swagger-gen \
-i "$PKG_ONECLOUD/compute/models" \
-p "$PKG_SWAGGER/compute"
swagger-gen \
-i "$PKG_ONECLOUD/image/models" \
-p "$PKG_SWAGGER/image"
swagger-gen \
-i "$PKG_ONECLOUD/keystone/tokens" \
-i "$PKG_ONECLOUD/keystone/models" \
-p "$PKG_SWAGGER/identity"
}
generate_swagger_yaml() {
mkdir -p "$OUTPUT_SWAGGER_DIR"
for pkg_path in "${MODEL_SWAGGER_PKG_MAP[@]}"; do
model_pkg="${pkg_path%%:*}"
swaager_pkg="${pkg_path##*:}"
work_dir=${swaager_pkg#"$ONECLOUD"}
GO111MODULE=off swagger generate spec \
--scan-models \
--work-dir="$CURDIR/$work_dir" \
-o "$OUTPUT_SWAGGER_DIR/swagger_$(basename $swaager_pkg).yaml"
done
}
generate_swagger_serve() {
input_files="$(find $OUTPUT_SWAGGER_DIR -name 'swagger_*.yaml' -type f | paste -sd,)"
swagger-serve generate -i "$input_files" -o "$OUTPUT_SWAGGER_DIR" --serve
}
show_help() {
cat <<EOF
usage: $(basename $0) <subcommand>
Subcommands:
model_api: genereate model struct code
swagger_spec: generate swagger spec code
swagger_serve: generate swagger web site
EOF
}
subcmd=$1
case $subcmd in
"" | "-h" | "--help")
show_help
;;
*)
shift
generate_${subcmd} $@
if [ $? = 127 ]; then
echo "Run --help for a list of known subcommands." >&2
exit 1
fi
;;
esac