1
+ # !/usr/bin/env perl
2
+
3
+ use v5.20;
4
+ use strict;
5
+ use warnings;
6
+ use File::Basename;
7
+ use File::Path qw( make_path) ;
8
+ use File::Spec;
9
+ use Cwd qw( abs_path) ;
10
+ use Getopt::Long;
11
+
12
+ # Get project root directory (one level up from bin/)
13
+ my $script_dir = dirname(abs_path($0 ));
14
+ my $project_root = dirname($script_dir );
15
+
16
+ # Parse command line arguments
17
+ my $capi_version ;
18
+ my $language ;
19
+ my $output_path ;
20
+ my $help ;
21
+
22
+ GetOptions(
23
+ ' version=s' => \$capi_version ,
24
+ ' language=s' => \$language ,
25
+ ' output=s' => \$output_path ,
26
+ ' help' => \$help ,
27
+ ) or die usage();
28
+
29
+ # Show usage if help requested or missing required arguments
30
+ if ($help || !$capi_version || !$language ) {
31
+ print usage();
32
+ exit ($help ? 0 : 1);
33
+ }
34
+
35
+ # Set default output path if not provided
36
+ $output_path //= File::Spec-> catfile($project_root , ' sdk' , $capi_version , $language );
37
+
38
+ # Validate inputs
39
+ validate_inputs();
40
+
41
+ # Generate SDK
42
+ generate_sdk();
43
+
44
+ sub usage {
45
+ return <<EOF ;
46
+ Usage: $0 --version=VERSION --language=LANGUAGE [--output=PATH]
47
+
48
+ Generate SDK from CAPI OpenAPI specification
49
+
50
+ Required options:
51
+ --version=VERSION CAPI version (e.g., 3.195.0)
52
+ --language=LANGUAGE Target language for SDK generation
53
+
54
+ Optional options:
55
+ --output=PATH Output directory (default: ./sdk/VERSION/LANGUAGE/)
56
+ --help Show this help message
57
+
58
+ Supported languages:
59
+ ada, android, apex, bash, c, clojure, cpp-qt-client, cpp-rest-sdk-client,
60
+ cpp-tiny, cpp-ue4, cpp-pistache-server, cpp-restbed-server, crystal, csharp,
61
+ csharp-netcore, dart, eiffel, elixir, elm, erlang-client, erlang-server, go,
62
+ go-server, groovy, haskell-http-client, haskell, java, java-micronaut-client,
63
+ java-micronaut-server, javascript, javascript-closure-angular, jaxrs-cxf-client,
64
+ jaxrs-cxf, jaxrs-cxf-extended, jaxrs-jersey, jaxrs-resteasy, jaxrs-resteasy-eap,
65
+ jaxrs-spec, kotlin, kotlin-server, kotlin-spring, lua, nim, objc, ocaml, perl,
66
+ php, php-laravel, php-lumen, php-slim4, php-symfony, powershell, python,
67
+ python-fastapi, python-flask, python-aiohttp, r, ruby, rust, rust-server,
68
+ scala-akka, scala-akka-http-server, scala-finch, scala-gatling, scala-lagom-server,
69
+ scala-play-server, scala-sttp, scalaz, spring, swift5, typescript-angular,
70
+ typescript-aurelia, typescript-axios, typescript-fetch, typescript-inversify,
71
+ typescript-jquery, typescript-nestjs, typescript-node, typescript-redux-query,
72
+ typescript-rxjs
73
+
74
+ Examples:
75
+ $0 --version=3.195.0 --language=go
76
+ $0 --version=3.181.0 --language=python --output=/tmp/capi-python-sdk
77
+ EOF
78
+ }
79
+
80
+ sub validate_inputs {
81
+ # Check if spec file exists
82
+ my $spec_file = File::Spec-> catfile($project_root , ' capi' , " ${capi_version} .openapi.json" );
83
+ unless (-f $spec_file ) {
84
+ die " Error: OpenAPI spec file not found: $spec_file \n " .
85
+ " Please run 'make gen-openapi-spec' first to generate the specification.\n " ;
86
+ }
87
+
88
+ # Check if openapi-generator is available
89
+ my $generator_check = ` which openapi-generator 2>/dev/null || which openapi-generator-cli 2>/dev/null` ;
90
+ chomp $generator_check ;
91
+ unless ($generator_check ) {
92
+ die " Error: openapi-generator-cli not found.\n " .
93
+ " Please run 'make deps' to install dependencies.\n " ;
94
+ }
95
+ }
96
+
97
+ sub generate_sdk {
98
+ my $spec_file = File::Spec-> catfile($project_root , ' capi' , " ${capi_version} .openapi.json" );
99
+
100
+ # Create output directory if it doesn't exist
101
+ make_path($output_path ) unless -d $output_path ;
102
+
103
+ # Determine which command to use (openapi-generator or openapi-generator-cli)
104
+ my $generator_cmd = ` which openapi-generator 2>/dev/null` ;
105
+ chomp $generator_cmd ;
106
+ $generator_cmd = ' openapi-generator-cli' unless $generator_cmd ;
107
+
108
+ # Build the command
109
+ my $cmd = " $generator_cmd generate " .
110
+ " -i '$spec_file ' " .
111
+ " -g '$language ' " .
112
+ " -o '$output_path '" ;
113
+
114
+ # Add language-specific options
115
+ my $additional_props = get_additional_properties($language );
116
+ $cmd .= " --additional-properties='$additional_props '" if $additional_props ;
117
+
118
+ # Execute the command
119
+ say " Generating $language SDK for CAPI $capi_version ..." ;
120
+ say " Command: $cmd " ;
121
+
122
+ my $result = system ($cmd );
123
+
124
+ if ($result == 0) {
125
+ say " \n SDK generated successfully!" ;
126
+ say " Output directory: $output_path " ;
127
+ } else {
128
+ die " \n Error: Failed to generate SDK. Exit code: " . ($result >> 8) . " \n " ;
129
+ }
130
+ }
131
+
132
+ sub get_additional_properties {
133
+ my ($lang ) = @_ ;
134
+
135
+ # Language-specific additional properties
136
+ my %lang_props = (
137
+ ' go' => ' packageName=capiclient,isGoSubmodule=true,generateInterfaces=true' ,
138
+ ' python' => ' packageName=capi_client,projectName=capi-client' ,
139
+ ' java' => ' groupId=org.cloudfoundry,artifactId=capi-client,artifactVersion=' . $capi_version ,
140
+ ' javascript' => ' npmName=@cloudfoundry/capi-client,npmVersion=' . $capi_version ,
141
+ ' typescript-node' => ' npmName=@cloudfoundry/capi-client,npmVersion=' . $capi_version ,
142
+ ' ruby' => ' gemName=capi_client,gemVersion=' . $capi_version ,
143
+ ' php' => ' packageName=CloudFoundry\\\\ CAPI,composerPackageName=cloudfoundry/capi-client' ,
144
+ ' csharp' => ' packageName=CloudFoundry.CAPI,packageVersion=' . $capi_version ,
145
+ ' rust' => ' packageName=capi_client,packageVersion=' . $capi_version ,
146
+ );
147
+
148
+ return $lang_props {$lang } // ' ' ;
149
+ }
0 commit comments