-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #219 from azar-writes-code/feat-xmlconvert
feat: command `xmlconvert` and `customLicense` added to compage cli
- Loading branch information
Showing
9 changed files
with
365 additions
and
256 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/intelops/compage/cmd/subcommand/customLicense" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func init() { | ||
// Create the logger instance | ||
logger := logrus.New() | ||
logger.SetFormatter(&logrus.TextFormatter{ | ||
FullTimestamp: true, | ||
TimestampFormat: "2006-01-02 15:04:05", | ||
}) | ||
|
||
// Create the instance for customlicense | ||
customlicense := customLicense.NewCustomLicenseCmd(logger) | ||
|
||
// Add Subcommand for the root command | ||
rootCmd.AddCommand(customlicense.Execute()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package customLicense | ||
|
||
const exampleCommand = ` | ||
# Convert XML file to JSON and YAML with the file path provided in the command line | ||
compage customLicense path=https://raw.githubusercontent.com/licenses/license-templates/master/templates/apache.txt projectPath=/some/local/path/LICENSE | ||
` | ||
var ( | ||
path = "https://raw.githubusercontent.com/licenses/license-templates/master/templates/apache.txt" | ||
projectPath = "LICENSE" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package customLicense | ||
|
||
import ( | ||
"io" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type CustomLicenseCmd struct { | ||
logger *logrus.Logger | ||
} | ||
|
||
func NewCustomLicenseCmd(logger *logrus.Logger) *CustomLicenseCmd { | ||
return &CustomLicenseCmd{ | ||
logger: logger, | ||
} | ||
} | ||
|
||
// Execute runs the xmlconvert command | ||
func (cl *CustomLicenseCmd) Execute() *cobra.Command { | ||
// Create a new cobra command for xmlconvert | ||
customLicenseCmd := &cobra.Command{ | ||
Use: "customLicense", | ||
Short: "customLicense takes the public url of the license file and stores it in the specified path of the project", | ||
Long: `The 'customLicense' command retrieves a license file from a specified public URL and stores it in a designated path within your project. By default, it uses 'config.xml' for the license URL and 'config.yaml' for the project path, ensuring easy integration and updates of license files. This command includes pre-run validation and customizable flags for flexible usage.`, | ||
Example: exampleCommand, | ||
PreRun: cl.preRun, // Define a pre-run function | ||
Run: cl.run, // Define the run function | ||
} | ||
|
||
// Define the flags for the xmlconvert command | ||
customLicenseCmd.Flags().StringVar(&path, "path", path, "please specify the public url of the license file. The default path is ``") | ||
customLicenseCmd.Flags().StringVar(&projectPath, "projectPath", projectPath, "Provide the project path to store the license file. The default path is ``") | ||
|
||
return customLicenseCmd | ||
} | ||
|
||
func (cl *CustomLicenseCmd) preRun(cmd *cobra.Command, args []string) { | ||
// Do any pre-run setup here | ||
yellow := "\033[33m" | ||
reset := "\033[0m" | ||
text := "WARNING: This command is in alpha version and may need some changes." | ||
cl.logger.Println(yellow + text + reset) | ||
} | ||
|
||
func (cl *CustomLicenseCmd) run(cmd *cobra.Command, args []string) { | ||
// Ensure path is set | ||
if path == "" { | ||
cl.logger.Fatal("Path to the license file URL must be specified") | ||
} | ||
|
||
// Use the current working directory if projectPath is not provided | ||
if projectPath == "" { | ||
cwd, err := os.Getwd() | ||
if err != nil { | ||
cl.logger.Fatalf("Failed to get the current working directory: %v", err) | ||
} | ||
projectPath = filepath.Join(cwd, "LICENSE") | ||
} | ||
|
||
// Log the start of the process | ||
cl.logger.Println("Starting to download the license file from:", path) | ||
|
||
// Create the HTTP request to fetch the license file | ||
response, err := http.Get(path) | ||
if err != nil { | ||
cl.logger.Fatalf("Failed to download the license file: %v", err) | ||
} | ||
defer response.Body.Close() | ||
|
||
// Check if the HTTP request was successful | ||
if response.StatusCode != http.StatusOK { | ||
cl.logger.Fatalf("Failed to download the license file, HTTP Status: %s", response.Status) | ||
} | ||
|
||
// Create the destination directory if it does not exist | ||
err = os.MkdirAll(filepath.Dir(projectPath), os.ModePerm) | ||
if err != nil { | ||
cl.logger.Fatalf("Failed to create the destination directory: %v", err) | ||
} | ||
|
||
// Create the destination file | ||
outFile, err := os.Create(projectPath) | ||
if err != nil { | ||
cl.logger.Fatalf("Failed to create the destination file: %v", err) | ||
} | ||
defer outFile.Close() | ||
|
||
// Copy the content from the response to the file | ||
_, err = io.Copy(outFile, response.Body) | ||
if err != nil { | ||
cl.logger.Fatalf("Failed to save the license file: %v", err) | ||
} | ||
|
||
// Log the success of the operation | ||
cl.logger.Println("License file successfully downloaded and stored at:", projectPath) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package xmlconvert | ||
|
||
// xmlFile is the default path to the XML configuration file. | ||
var xmlFile = "config.xml" | ||
|
||
// outputFiles is the default list of output file paths. | ||
var outputFiles = []string{ | ||
"config.yaml", | ||
"config.json", | ||
} | ||
|
||
var exampleCommand = ` | ||
# Convert XML file to JSON and YAML with the file path provided in the command line | ||
compage xmlconvert --xmlFile config.xml | ||
# Convert XML file to JSON and YAML with the provided output files with path name specified | ||
compage xmlconvert --xmlFile config.xml --outputFiles filename.yaml,filename.json | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package xmlconvert | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"github.com/clbanning/mxj/v2" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// ReadXML reads the XML file from the provided path and unmarshals it into a generic map. | ||
func ReadXML(filePath string) (map[string]interface{}, error) { | ||
// Open the XML file. | ||
xmlFile, err := os.Open(filePath) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to open XML file: %v", err) | ||
} | ||
defer xmlFile.Close() | ||
|
||
// Read the XML file into a byte slice. | ||
byteValue, _ := io.ReadAll(xmlFile) | ||
|
||
// Convert the XML file into a generic map. | ||
result, err := mxj.NewMapXml(byteValue) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to unmarshal XML: %v", err) | ||
} | ||
|
||
return result, nil | ||
} | ||
|
||
// WriteJSON writes the given data to a JSON file at the specified path. | ||
func WriteJSON(data map[string]interface{}, filePath string) error { | ||
// Marshal the data into a JSON byte slice with indentation. | ||
jsonData, err := json.MarshalIndent(data, "", " ") | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal JSON: %v", err) | ||
} | ||
|
||
// Write the JSON data to the specified file path. | ||
err = os.WriteFile(filePath, jsonData, 0644) | ||
if err != nil { | ||
return fmt.Errorf("failed to write JSON file: %v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// WriteYAML writes the given data to a YAML file at the specified path. | ||
func WriteYAML(data map[string]interface{}, filePath string) error { | ||
// Marshal the data into a YAML byte slice. | ||
yamlData, err := yaml.Marshal(data) | ||
if err != nil { | ||
return fmt.Errorf("failed to marshal YAML: %v", err) | ||
} | ||
|
||
// Write the YAML data to the specified file path. | ||
err = os.WriteFile(filePath, yamlData, 0644) | ||
if err != nil { | ||
return fmt.Errorf("failed to write YAML file: %v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// CreateFile writes the given data to a file at the specified path based on the file extension. | ||
// Supported file extensions are "json" and "yaml". | ||
func CreateFile(data map[string]interface{}, filePath string, extension string) error { | ||
// Determine the file type based on the extension. | ||
switch extension { | ||
case "json": | ||
return WriteJSON(data, filePath) | ||
case "yaml": | ||
return WriteYAML(data, filePath) | ||
default: | ||
return fmt.Errorf("invalid file extension: %s", extension) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package xmlconvert | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// XMLConvertCmd represents the structure of the xmlconvert command | ||
type XMLConvertCmd struct { | ||
logger *logrus.Logger | ||
} | ||
|
||
// NewXMLConvertCmd returns a new instance of XMLConvertCmd | ||
func NewXMLConvertCmd(logger *logrus.Logger) *XMLConvertCmd { | ||
return &XMLConvertCmd{ | ||
logger: logger, | ||
} | ||
} | ||
|
||
// Execute runs the xmlconvert command | ||
func (xml *XMLConvertCmd) Execute() *cobra.Command { | ||
// Create a new cobra command for xmlconvert | ||
xmlConvertCmd := &cobra.Command{ | ||
Use: "xmlconvert", | ||
Short: "Convert XML to JSON and YAML", | ||
Long: "`xmlconvert` converts XML file provided in the command line arguments to JSON and YAML format. It can be used to convert XML file to JSON and YAML file.", | ||
Example: exampleCommand, | ||
PreRun: xml.preRun, // Define a pre-run function | ||
Run: xml.run, // Define the run function | ||
} | ||
|
||
// Define the flags for the xmlconvert command | ||
xmlConvertCmd.Flags().StringVar(&xmlFile, "xmlFile", xmlFile, "provide xml file path to convert. The default path is `config.xml`") | ||
xmlConvertCmd.Flags().StringArrayVar(&outputFiles, "outputFiles", outputFiles, "returns converted output file. The default path is `config.yaml`") | ||
|
||
return xmlConvertCmd | ||
} | ||
|
||
// preRun is a pre-run function that logs a warning message | ||
func (xml *XMLConvertCmd) preRun(cmd *cobra.Command, args []string) { | ||
yellow := "\033[33m" | ||
reset := "\033[0m" | ||
text := "WARNING: This command is in alpha version and may need some changes." | ||
xml.logger.Println(yellow + text + reset) | ||
} | ||
|
||
// run is the function that will be called when the xmlconvert command is executed | ||
func (xml *XMLConvertCmd) run(cmd *cobra.Command, args []string) { | ||
xmlData, err := ReadXML(xmlFile) | ||
if err != nil { | ||
xml.logger.Fatal(err) | ||
} | ||
xml.logger.Info("output files: ", outputFiles) | ||
|
||
// Check if only two output files are supported | ||
if len(outputFiles) > 2 { | ||
xml.logger.Fatal("only two output file extensions are supported: json and yaml") | ||
} | ||
|
||
// Check if output files are provided | ||
if len(outputFiles) == 0 { | ||
xml.logger.Fatal("please provide output file") | ||
} | ||
|
||
// Check if only one output file is provided | ||
if len(outputFiles) == 1 { | ||
fileExtension := strings.Split(outputFiles[0], ".")[len(strings.Split(outputFiles[0], "."))-1] | ||
CreateFile(xmlData, outputFiles[0], fileExtension) | ||
} else { | ||
for _, file := range outputFiles { | ||
fileExtension := strings.Split(file, ".")[len(strings.Split(file, "."))-1] | ||
CreateFile(xmlData, file, fileExtension) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/intelops/compage/cmd/subcommand/xmlconvert" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func init() { | ||
// Create the logger instance | ||
logger := logrus.New() | ||
logger.SetFormatter(&logrus.TextFormatter{ | ||
FullTimestamp: true, | ||
TimestampFormat: "2006-01-02 15:04:05", | ||
}) | ||
|
||
// Create the instance for xmlconvert | ||
xmlConvert := xmlconvert.NewXMLConvertCmd(logger) | ||
|
||
// Add Subcommand for the root command | ||
rootCmd.AddCommand(xmlConvert.Execute()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.