1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "shell_command.h"
17 
18 #include <getopt.h>
19 #include <iostream>
20 #include <memory>
21 #include <string>
22 
23 #include "constants.h"
24 #include "packager.h"
25 #include "hap_packager.h"
26 #include "hsp_packager.h"
27 
28 namespace OHOS {
29 namespace AppPackingTool {
30 namespace {
31 
32 } // namespace
33 
ShellCommand(int argc, char *argv[], std::string name)34 ShellCommand::ShellCommand(int argc, char *argv[], std::string name)
35 {
36     opterr = 0;
37     argc_ = argc;
38     argv_ = argv;
39     name_ = name;
40 
41     if (argc < MIN_ARGUMENT_NUMBER) {
42         cmd_ = Constants::CMD_HELP;
43         return;
44     }
45     cmd_ = argv[1];
46 }
47 
~ShellCommand()48 ShellCommand::~ShellCommand() {}
49 
CreateCommandMap()50 int ShellCommand::CreateCommandMap()
51 {
52     commandMap_ = {
53         {"help", [this] { return this->RunAsHelpCommand(); } },
54         {"pack", [this] { return this->RunAsPackCommand(); } },
55         {"unpack", [this] { return this->RunAsUnpackCommand(); } }
56     };
57     return ERR_OK;
58 }
59 
ParseParam()60 int ShellCommand::ParseParam()
61 {
62     int n = 0;
63     while (n < Constants::OPTIONS_SIZE) {
64         int32_t option = getopt_long(argc_, argv_, Constants::SHORT_OPTIONS, Constants::LONG_OPTIONS, nullptr);
65         if (optind < 0 || optind > argc_) {
66             return ERR_INVALID_VALUE;
67         }
68         if (option < 0) {
69             std::cout << "ParseParam finish." << std::endl;
70             break;
71         } else if (option == '?') {
72             resultReceiver_.append("not support param: ").append(argv_[optind - 1]).append("\n");
73             return ERR_INVALID_VALUE;
74         } else {
75             // example: --mode hap
76             std::string paramName = argv_[optind - OFFSET_REQUIRED_ARGUMENT];
77             paramName = paramName.substr(Constants::PARAM_PREFIX.length());
78             std::string paramValue = optarg;
79             parameterMap_[paramName] = optarg;
80         }
81         n++;
82     }
83     return ERR_OK;
84 }
85 
OnCommand()86 int ShellCommand::OnCommand()
87 {
88     auto respond = commandMap_[cmd_];
89     if (respond == nullptr) {
90         resultReceiver_.append("not support command: ").append(cmd_).append("\n");
91         respond = commandMap_[Constants::CMD_HELP];
92     }
93     respond();
94     return ERR_OK;
95 }
96 
ExecCommand()97 std::string ShellCommand::ExecCommand()
98 {
99     int result = CreateCommandMap();
100     if (result != ERR_OK) {
101         resultReceiver_.append("failed to create command map.\n");
102         return resultReceiver_;
103     }
104     result = ParseParam();
105     if (result != ERR_OK) {
106         resultReceiver_.append("failed to init parameter map.\n");
107         return resultReceiver_;
108     }
109 
110     result = OnCommand();
111     if (result != ERR_OK) {
112         resultReceiver_.append("failed to execute your command.\n");
113         return resultReceiver_;
114     }
115     return resultReceiver_;
116 }
117 
RunAsHelpCommand()118 int ShellCommand::RunAsHelpCommand()
119 {
120     resultReceiver_.append(HELP_MSG);
121     return ERR_OK;
122 }
123 
RunAsPackCommand()124 int ShellCommand::RunAsPackCommand()
125 {
126     std::cout << "RunAsPackCommand " << std::endl;
127     std::unique_ptr<Packager> packager = getPackager();
128     if (packager != nullptr) {
129         packager->MakePackage();
130     }
131     return ERR_OK;
132 }
133 
RunAsUnpackCommand()134 int ShellCommand::RunAsUnpackCommand()
135 {
136     std::cout << "RunAsUnpackCommand " << std::endl;
137     return ERR_OK;
138 }
139 
getPackager()140 std::unique_ptr<Packager> ShellCommand::getPackager()
141 {
142     std::string mode = parameterMap_[Constants::PARAM_MODE];
143     if (mode == Constants::MODE_HAP) {
144         std::unique_ptr<Packager> packager =
145             std::make_unique<HapPackager>(parameterMap_, resultReceiver_);
146         return packager;
147     } else if (mode == Constants::MODE_HSP) {
148         std::unique_ptr<Packager> packager =
149             std::make_unique<HspPackager>(parameterMap_, resultReceiver_);
150         return packager;
151     }
152     resultReceiver_.append("not support --mode: ").append(mode).append("\n");
153     return nullptr;
154 }
155 
156 } // namespace AppPackingTool
157 } // namespace OHOS