summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorNeil Guzman2013-08-02 14:50:57 (EDT)
committer Alexander Kurtakov2013-08-16 14:50:27 (EDT)
commit5c3a3e3522f647bf2271678950317fba00fbecb9 (patch)
treecddbb801044eb9480dd6dab0cb48a091645ad158
parent17b570077bf83c1f515914c0ab13ef8fbf74a586 (diff)
downloadorg.eclipse.linuxtools-5c3a3e3522f647bf2271678950317fba00fbecb9.zip
org.eclipse.linuxtools-5c3a3e3522f647bf2271678950317fba00fbecb9.tar.gz
org.eclipse.linuxtools-5c3a3e3522f647bf2271678950317fba00fbecb9.tar.bz2
RPMStubby: Perl Makefile templaterefs/changes/13/15213/10
Grab the Makefile attributes to help create a specfile template. Change-Id: I13e72a550aa5fd4be3d6c9474f703d367359da93 Signed-off-by: Neil Guzman <nguzman@redhat.com> Reviewed-on: https://git.eclipse.org/r/15213 Reviewed-by: Alexander Kurtakov <akurtako@redhat.com> IP-Clean: Alexander Kurtakov <akurtako@redhat.com> Tested-by: Alexander Kurtakov <akurtako@redhat.com>
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/plugin.xml28
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/StubbyMakefilePLGenerator.java133
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/model/PerlModel.java182
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/parser/PerlMakefileParser.java658
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/popup/actions/StubifyMakefilePLHandler.java26
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/Generator.java8
-rw-r--r--rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/InputType.java8
7 files changed, 1038 insertions, 5 deletions
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/plugin.xml b/rpmstubby/org.eclipse.linuxtools.rpmstubby/plugin.xml
index 0324ab6..3f649dc 100644
--- a/rpmstubby/org.eclipse.linuxtools.rpmstubby/plugin.xml
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/plugin.xml
@@ -42,6 +42,12 @@
id="rpmstubby.stubifyGem"
name="%action.label">
</command>
+ <command
+ categoryId="rpmstubby.commands"
+ description="%action.label"
+ id="rpmstubby.stubifyMakefilePL"
+ name="%action.label">
+ </command>
</extension>
<extension
@@ -62,6 +68,10 @@
class="org.eclipse.linuxtools.internal.rpmstubby.popup.actions.StubifyGemHandler"
commandId="rpmstubby.stubifyGem">
</handler>
+ <handler
+ class="org.eclipse.linuxtools.internal.rpmstubby.popup.actions.StubifyMakefilePLHandler"
+ commandId="rpmstubby.stubifyMakefilePL">
+ </handler>
</extension>
<extension
point="org.eclipse.ui.menus">
@@ -139,6 +149,24 @@
</with>
</visibleWhen>
</command>
+ <command
+ commandId="rpmstubby.stubifyMakefilePL">
+ <visibleWhen>
+ <with
+ variable="selection">
+ <iterate
+ ifEmpty="false">
+ <adapt
+ type="org.eclipse.core.resources.IResource">
+ <test
+ property="org.eclipse.core.resources.name"
+ value="*.PL">
+ </test>
+ </adapt>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
</menuContribution>
</extension>
</plugin>
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/StubbyMakefilePLGenerator.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/StubbyMakefilePLGenerator.java
new file mode 100644
index 0000000..b40a933
--- /dev/null
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/StubbyMakefilePLGenerator.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Neil Guzman - perl implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.rpmstubby;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.linuxtools.internal.rpmstubby.model.PerlModel;
+
+/**
+ * Generator for RPM specfile from perl Makefile.PL.
+ *
+ */
+public class StubbyMakefilePLGenerator extends AbstractGenerator {
+
+ private PerlModel model;
+
+ /**
+ * Creates the generator by parsing the Makefile.PL file.
+ *
+ * @param makefile
+ * The Makefile.PL file to generate specfile for.
+ */
+ public StubbyMakefilePLGenerator(IFile makefile) {
+ parse(makefile);
+ specfileName = model.getPackageName().toLowerCase() + ".spec";
+ projectName = makefile.getProject().getName();
+ }
+
+ /**
+ * Creates the model which contains the information
+ *
+ * @param makefile The Makefile.PL file
+ */
+ private void parse(IFile makefile) {
+ model = new PerlModel(makefile);
+ }
+
+ /**
+ * Generates a RPM specfile based on the parsed data from the Makefile.PL file.
+ *
+ * @return The generated Makefile.PL.
+ */
+ @Override
+ public String generateSpecfile() {
+ StringBuilder buffer = new StringBuilder();
+ String packageName = model.getPackageName();
+ buffer.append("Name: " + packageName.toLowerCase() + "\n");
+ buffer.append("Version: " + model.getVersion() + "\n");
+ buffer.append("Release: 1%{?dist}" + "\n");
+ buffer.append("Summary: " + model.getSummary() + "\n\n");
+
+ buffer.append("Group: Development/Libraries\n");
+ buffer.append("License: GPL+ or Artistic\n");
+ buffer.append("URL: "+model.getURL() + "\n"); // e.g., Net-XMPP/ for Net::XMPP
+ buffer.append("Source0: #FIXME\n\n");
+ buffer.append("BuildArch: noarch\n");
+ generateRequires(buffer);
+ buffer.append("%{?perl_default_filter}\n\n\n");
+ buffer.append("%description\n" + model.getDescription() + "\n\n\n");
+ generatePrepSection(buffer);
+ generateBuildSection(buffer);
+ generateInstallSection(buffer);
+ generateFilesSections(buffer);
+ generateChangelog(buffer);
+
+ return buffer.toString();
+ }
+
+ /**
+ * Generate requires
+ *
+ * @param buffer Buffer to write content to
+ */
+ private void generateRequires(StringBuilder buffer) {
+ buffer.append("BuildRequires: perl(ExtUtils::MakeMaker)\n");
+ List<String> requires = model.getInstallRequires() ;
+ if (!requires.isEmpty()) {
+ for (String str : requires) {
+ buffer.append("BuildRequires: " + str + "\n");
+ }
+ }
+ buffer.append("Requires: perl(:MODULE_COMPAT_%(eval \"`%{__perl} -V:version`\"; echo $version))\n\n");
+ }
+
+ /**
+ * Generate prep
+ *
+ * @param buffer Buffer to write content to
+ */
+ private static void generatePrepSection(StringBuilder buffer) {
+ buffer.append("%prep\n");
+ buffer.append("%setup -q #You may need to update this according to your Source0\n\n\n");
+ }
+
+ /**
+ * Generate build
+ *
+ * @param buffer Buffer to write content to
+ */
+ private static void generateBuildSection(StringBuilder buffer) {
+ buffer.append("%build\n");
+ buffer.append("%{__perl} Makefile.PL INSTALLDIRS=vendor\n\n\n");
+ }
+
+ /**
+ * Generate install
+ *
+ * @param buffer Buffer to write content to
+ */
+ private static void generateInstallSection(StringBuilder buffer) {
+ buffer.append("%install\n");
+ buffer.append("make pure_install PERL_INSTALL_ROOT=$RPM_BUILD_ROOT\n\n\n");
+ }
+
+ /**
+ * Generate files
+ *
+ * @param buffer Buffer to write content to
+ */
+ private static void generateFilesSections(StringBuilder buffer) {
+ buffer.append("%files\n");
+ buffer.append("%{perl_vendorlib}/*\n\n\n");
+ }
+} \ No newline at end of file
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/model/PerlModel.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/model/PerlModel.java
new file mode 100644
index 0000000..e2bb0e5
--- /dev/null
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/model/PerlModel.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Neil Guzman - perl implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.rpmstubby.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.internal.rpmstubby.StubbyLog;
+import org.eclipse.linuxtools.internal.rpmstubby.parser.CommonMetaData;
+import org.eclipse.linuxtools.internal.rpmstubby.parser.PerlMakefileParser;
+
+/**
+ * Gives easy access to data from the perl Makefile.PL file.
+ *
+ */
+public class PerlModel {
+
+ private static final String FIX_ME = "#FIXME";
+
+ private static final String LICENSE_REQ = "GPL+ or Artistic";
+ private static final String CPAN_URL = "http://search.cpan.org/dist/";
+
+ private static final String ABSTRACT = "abstract";
+ private static final String REQUIRES = "prereq_pm";
+
+ private PerlMakefileParser perlMakefileParser;
+
+ /**
+ * Perl makefile
+ *
+ * @param file
+ * The Perl makefile
+ */
+ public PerlModel(IFile file) {
+ try {
+ perlMakefileParser = new PerlMakefileParser(file);
+ } catch (IOException e) {
+ StubbyLog.logError(e);
+ } catch (CoreException e) {
+ StubbyLog.logError(e);
+ }
+ }
+
+ /**
+ * Get the value from one of the makefile attributes. If the value is empty, it
+ * will return #FIXME
+ *
+ * @param key
+ * The makefile attribute to get value of
+ * @return The value of the option
+ */
+ private String getValue(String key) {
+ String rc = perlMakefileParser.getValue(key);
+ if (rc.isEmpty()) {
+ rc = FIX_ME;
+ }
+ return rc;
+ }
+
+ /**
+ * Get the install requires in the makefile
+ *
+ * @return A list of the values taken from the makefile
+ */
+ public List<String> getInstallRequires() {
+ List<String> rc = new ArrayList<String>();
+ List<String> temp = perlMakefileParser.getValueList(REQUIRES);
+ String ver = "";
+ if (!temp.isEmpty()) {
+ for (String str : temp) {
+ ver = str.substring(str.indexOf("=>")+2, str.length());
+ str = str.substring(0, str.indexOf("=>"));
+ str = str.replaceAll("(\\S+)", "perl($1)");
+ if (!ver.isEmpty() && hasDigits(ver)) {
+ str = str.concat(">= " + ver);
+ }
+ rc.add(str);
+ ver = "";
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Returns the package name.
+ *
+ * @return The package name.
+ */
+ public String getSimplePackageName() {
+ String rc = "";
+ rc = getValue(CommonMetaData.NAME);
+ if (!rc.equals(FIX_ME)) {
+ rc = rc.replaceAll("::", "-");
+ }
+ return rc;
+ }
+
+ /**
+ * The simple package name with "perl-" prepended to make better RPM
+ * package name.
+ *
+ * @return The package
+ */
+ public String getPackageName() {
+ String simpleName = getSimplePackageName();
+ if (simpleName.startsWith("perl-")) {
+ return simpleName;
+ }
+ return "perl-"+simpleName;
+ }
+
+ /**
+ * Returns the version
+ *
+ * @return The version
+ */
+ public String getVersion() {
+ String version = getValue(CommonMetaData.VERSION);
+ if (!hasDigits(version)) {
+ version = "1 " + FIX_ME;
+ }
+ return version;
+ }
+
+ /**
+ * Utility method to try and see if a string contains digits within it
+ *
+ * @param str
+ * The string to check if it has digits
+ * @return True if string contains digits
+ */
+ public boolean hasDigits(String str) {
+ return str.matches(".*\\d.*");
+ }
+
+ /**
+ * Returns the summary
+ *
+ * @return The package summary
+ */
+ public String getSummary() {
+ return getValue(ABSTRACT);
+ }
+
+ /**
+ * Returns the license
+ *
+ * @return The license
+ */
+ public String getLicense() {
+ return LICENSE_REQ;
+ }
+
+ /**
+ * Returns the url
+ *
+ * @return The url
+ */
+ public String getURL() {
+ return CPAN_URL+getSimplePackageName();
+ }
+
+ /**
+ * Returns the description
+ *
+ * @return The description
+ */
+ public String getDescription() {
+ return getValue(ABSTRACT);
+ }
+}
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/parser/PerlMakefileParser.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/parser/PerlMakefileParser.java
new file mode 100644
index 0000000..7c43ad8
--- /dev/null
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/parser/PerlMakefileParser.java
@@ -0,0 +1,658 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Neil Guzman - perl implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.rpmstubby.parser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.internal.rpmstubby.StubbyLog;
+
+/**
+ * Class to parse a Perl Makefile.PL to grab specfile properties
+ *
+ */
+public class PerlMakefileParser {
+
+ /*
+ * Perl Regular Expressions
+ *
+ */
+ private static final String WHITE_SPACE = "(?:\\s+)";
+ private static final String COMMENT = "#.+"; // # comment
+ private static final String LINE_WITH_COMMENT = "(?:(.*)#.+)"; // line # comment
+ private static final String VARIABLE_PARAMS = "(?:my|local|our)";
+
+ private static final String WORD = "(\\b\\w+\\b)"; // variable
+ private static final String NON_WHITE_SPACE = "(\\S+)";
+ private static final String VARIABLE = "(?:" + VARIABLE_PARAMS
+ + WHITE_SPACE + ")?(?:\\$|@|%)" + WORD + WHITE_SPACE + "?"; // %variable | my $variable | our @variable
+ private static final String ASSOCIATIVE_KEY = WHITE_SPACE + "?"
+ + NON_WHITE_SPACE + WHITE_SPACE + "?";
+
+ private static final String EXCLUDE_SPECIALS = "(?![=~|\\-\\*\\+\\/])";
+ private static final String NON_CONDITIONAL = "(?!(?:\\s*if|elsif|unless))";
+ private static final String ASSIGNMENT_OPERATOR = "=";
+ private static final String ASSOCIATIVE_OPERATOR = "=>";
+ private static final String SIMPLE_ASSIGNMENT = NON_CONDITIONAL
+ + WHITE_SPACE + "?" + VARIABLE + "(?:" + ASSIGNMENT_OPERATOR + ")"
+ + EXCLUDE_SPECIALS + "(?:(.+))"; // %var = value || [1] = [2]
+ private static final String ASSOCIATIVE_ASSIGNMENT = ASSOCIATIVE_KEY
+ + ASSOCIATIVE_OPERATOR + "(?:(.+))"; // 'key' => 'value' || [1] => [2]
+
+ private static final String FUNCTION = "\\s*" + WORD
+ + "*\\s*?\\((.*)\\)\\s*"; // foo(bar) | foo(foo(bar)) | foo() || [1]([2])
+ private static final String BEGIN_END = "(?:[^#]*<<END)"; // [CS] test<<END | <<END
+ private static final String END_END = "^END$"; // [CS]
+ private static final String BEGIN_BC = "^=(?!cut)[a-z]\\S+(\\s)?\\S+"; // [CS] =test | =test test
+ private static final String END_BC = "^=cut$"; // [CS]
+
+ private static final String MAKEFILE_FUNCTION_NAME = "WriteMakefile";
+ private static final String MAKEFILE_FUNCTION = "^.*"
+ + MAKEFILE_FUNCTION_NAME + WHITE_SPACE + "?\\(.*$";
+
+ /*
+ * A few common opening characters and their closing counterparts
+ *
+ */
+ private static final Map<Character, Character> SURROUNDING_CHARACTER;
+ static {
+ Map<Character, Character> aMap = new HashMap<Character, Character>();
+ aMap.put('[', ']');
+ aMap.put('{', '}');
+ aMap.put('(', ')');
+ aMap.put(']', '[');
+ aMap.put('}', '{');
+ aMap.put(')', '(');
+ SURROUNDING_CHARACTER = Collections.unmodifiableMap(aMap);
+ }
+
+ private static final char SQUARE_BRACKET = '[';
+ private static final char CURLY_BRACKET = '{';
+ private static final char ROUND_BRACKET = '(';
+
+ private static final int IN_BRACKETS = 0x00000001;
+ private static final int MAKE_FUNCTION = 0x00000002;
+
+ private IFile file;
+ private Map<String, String> mVariableDefinitions;
+ private Map<String, String> mMakefileDefinitions;
+
+ /**
+ * Initialize.
+ *
+ * @param file
+ * The perl Makefile.
+ * @throws CoreException
+ * Throws CoreException.
+ * @throws IOException
+ * Throws IOException.
+ */
+ public PerlMakefileParser(IFile file) throws IOException, CoreException {
+ mVariableDefinitions = new HashMap<String, String>();
+ mMakefileDefinitions = new HashMap<String, String>();
+ if (file.getContents().available() <= 0) {
+ return;
+ }
+ this.file = file;
+ parse();
+ }
+
+ /**
+ * Parse the perl Makefile.
+ *
+ */
+ public void parse() {
+ String content = "";
+ String line = "";
+ try {
+ Scanner variableScanner = new Scanner(file.getContents());
+ grabSimpleDefinitions(cleanUpContent(variableScanner));
+ cleanupVariables(mVariableDefinitions);
+ resolveVariables(mVariableDefinitions);
+
+ /*
+ * Going through the makefile function's attributes
+ */
+ if (!mVariableDefinitions.containsKey(MAKEFILE_FUNCTION_NAME)) {
+ return;
+ }
+ Scanner makefileScanner = new Scanner(
+ mVariableDefinitions.get(MAKEFILE_FUNCTION_NAME));
+ makefileScanner.useDelimiter("(?<=,)");
+ ArrayList<String> makefileList = new ArrayList<String>();
+
+ while (makefileScanner.hasNext()) {
+ line = makefileScanner.next();
+ if (matchesAssociativeAssignment(line)) {
+ makefileList.add(line);
+ } else if (!makefileList.isEmpty()) {
+ makefileList.set(
+ makefileList.size() - 1,
+ makefileList.get(makefileList.size() - 1).concat(
+ line));
+ }
+ }
+
+ for (String str : makefileList) {
+ content = content.concat(str + '\n');
+ }
+ grabAssociativeDefinitions(content);
+ cleanupVariables(mMakefileDefinitions);
+ resolveVariables(mMakefileDefinitions);
+
+ makefileScanner.close();
+ variableScanner.close();
+ } catch (Exception e) {
+ StubbyLog.logError(e);
+ }
+ }
+
+ /**
+ * Get the value of the variable.
+ *
+ * @param key The variable to get the value of.
+ * @return The value of the variable.
+ */
+ public String getValue(String key) {
+ String rc = "";
+ if (mMakefileDefinitions.containsKey(key)) {
+ rc = mMakefileDefinitions.get(key);
+ }
+ return rc;
+ }
+
+ /**
+ * Get the list of values from the variable.
+ *
+ * @param key The variable to get the value of.
+ * @return The list of values from the variable.
+ */
+ public List<String> getValueList(String key) {
+ List<String> rc = new ArrayList<String>();
+ String var = "";
+ String[] tmp = {};
+ if (mMakefileDefinitions.containsKey(key)) {
+ var = mMakefileDefinitions.get(key);
+ tmp = var.split(",");
+ for (String str : tmp) {
+ str = cleanUpString(str);
+ rc.add(str);
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Grab the simple key->value pairs from some content.
+ *
+ * @param content
+ * The content to grab the key->value pairs from.
+ */
+ private void grabSimpleDefinitions(String content) {
+ Scanner scanner = new Scanner(content);
+ Stack<Character> brackets = new Stack<Character>();
+ String key = "";
+ String value = "";
+ String tempVar = "";
+ String line = "";
+ String[] tmp;
+ int flags = 0;
+
+ while (scanner.hasNext()) {
+ line = scanner.nextLine();
+ if (matchesSimpleAssignment(line)) {
+ tmp = line.split("=");
+ key = removeVariableSigils(tmp[0]).toLowerCase().replaceAll(
+ "\\W", "");
+ value = tmp[1];
+ if (containsOpener(value)) {
+ flags |= IN_BRACKETS;
+ } else {
+ mVariableDefinitions.put(key, value);
+ }
+ } else if (containsMakefileFunction(line)) {
+ flags |= MAKE_FUNCTION;
+ flags |= IN_BRACKETS;
+ }
+ if ((flags & IN_BRACKETS) == IN_BRACKETS) {
+ checkBrackets(brackets, line);
+ tempVar = tempVar.concat(line.trim());
+ if (brackets.isEmpty()) {
+ if ((flags & MAKE_FUNCTION) == MAKE_FUNCTION) {
+ mVariableDefinitions.putAll(extractFunction(tempVar));
+ } else {
+ tmp = tempVar.split("=[^>]");
+ key = removeVariableSigils(tmp[0]).toLowerCase()
+ .replaceAll("\\W", "");
+ value = tmp[1];
+ mVariableDefinitions.put(key, value);
+ }
+ tempVar = "";
+ flags &= 0;
+ }
+ }
+ }
+ scanner.close();
+ }
+
+ /**
+ * Grab the associative key=>value pairs from some content.
+ *
+ * @param content
+ * The content to grab the key=>value pairs from.
+ */
+ private void grabAssociativeDefinitions(String content) {
+ Scanner scanner = new Scanner(content);
+ Stack<Character> brackets = new Stack<Character>();
+ String key = "";
+ String value = "";
+ String tempVar = "";
+ String line = "";
+ String[] tmp;
+ int flags = 0;
+
+ while (scanner.hasNext()) {
+ line = scanner.nextLine();
+ if (matchesAssociativeAssignment(line)
+ && (flags & IN_BRACKETS) != IN_BRACKETS) {
+ tmp = line.split("=>");
+ key = removeVariableSigils(tmp[0].toLowerCase().replaceAll(
+ "\\W", ""));
+ value = tmp[1];
+ if (containsOpener(value)) {
+ flags |= IN_BRACKETS;
+ } else {
+ mMakefileDefinitions.put(key, value);
+ }
+ }
+ if ((flags & IN_BRACKETS) == IN_BRACKETS) {
+ checkBrackets(brackets, line);
+ tempVar = tempVar.concat(line.trim());
+ if (brackets.isEmpty()) {
+ key = removeVariableSigils(tempVar
+ .substring(0, tempVar.indexOf("=>")).toLowerCase()
+ .replaceAll("\\W", ""));
+ value = tempVar.substring(tempVar.indexOf("=>") + 2,
+ tempVar.length());
+ mMakefileDefinitions.put(key, value);
+ tempVar = "";
+ flags &= 0;
+ }
+ }
+ }
+ scanner.close();
+ }
+
+ /**
+ * Check if the line is within a set of brackets. Update the stack tracking
+ * bracket completeness.
+ *
+ * @param brackets
+ * The stack tracking the bracket completeness.
+ * @param line
+ * The line to parse for brackets.
+ */
+ public static void checkBrackets(Stack<Character> brackets, String line) {
+ for (char c : line.toCharArray()) {
+ if (c == SQUARE_BRACKET || c == CURLY_BRACKET || c == ROUND_BRACKET) {
+ brackets.push(c);
+ } else if (c == SURROUNDING_CHARACTER.get(SQUARE_BRACKET)
+ || c == SURROUNDING_CHARACTER.get(CURLY_BRACKET)
+ || c == SURROUNDING_CHARACTER.get(ROUND_BRACKET)) {
+ if (brackets.peek() == SURROUNDING_CHARACTER.get(c)
+ && !brackets.isEmpty()) {
+ brackets.pop();
+ }
+ }
+ }
+ }
+
+ /**
+ * Go through the map of key->value pairings and check and see if a key has
+ * another key as a value. If so, resolve that.
+ *
+ * @param variables
+ * The key->value pairings.
+ */
+ private void resolveVariables(Map<String, String> variables) {
+ String tempVal = "";
+ for (String key : variables.keySet()) {
+ tempVal = variables.get(key);
+ if (mVariableDefinitions.containsKey(tempVal)) {
+ variables.put(key, mVariableDefinitions.get(tempVal));
+ }
+ }
+ }
+
+ /**
+ * Extract the function name and the contents of the function and return it
+ * as a key->value pairing.
+ *
+ * @param line
+ * The line to extract the function from.
+ * @return The key->value pairing of function and parameter(s).
+ */
+ public static Map<String, String> extractFunction(String line) {
+ Map<String, String> rc = new HashMap<String, String>();
+ Pattern pattern = Pattern.compile(FUNCTION, Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.find()) {
+ rc.put(variableMatcher.group(1), variableMatcher.group(2));
+ }
+ return rc;
+ }
+
+ /**
+ * Extract the key->value pairing from an associative assignment.
+ *
+ * @param line
+ * The line to extract the function from.
+ * @return The key->value pairing of function and parameter(s).
+ */
+ public static Map<String, String> extractKeyValueAssociation(String line) {
+ Map<String, String> rc = new HashMap<String, String>();
+ String[] keyValue = {};
+ String key = "";
+ String value = "";
+ if (matchesAssociativeAssignment(line)) {
+ keyValue = line.split("=>");
+ key = cleanUpString(keyValue[0].toLowerCase());
+ value = cleanUpString(keyValue[1]);
+ rc.put(key, value);
+ }
+ return rc;
+ }
+
+ /**
+ * Utility to go through the map of variables to clean up their values.
+ *
+ * @param variables
+ * The map of variables to go through.
+ */
+ private static void cleanupVariables(Map<String, String> variables) {
+ String val = "";
+ for (String key : variables.keySet()) {
+ val = cleanUpString(removeVariableSigils(variables.get(key)))
+ .trim();
+ if (val.startsWith("(") || val.startsWith("[")
+ || val.startsWith("{")) {
+ val = val.substring(1, val.length());
+ }
+ if (val.endsWith(")") || val.endsWith("]") || val.endsWith("}")) {
+ val = val.substring(0, val.length() - 1);
+ }
+ val = cleanUpString(val);
+ variables.put(key, val);
+ }
+ }
+
+ /**
+ * Utility to clean up the line of some unwanted characters.
+ *
+ * @param line
+ * The line to clean up.
+ * @return The cleaned up version of the line.
+ */
+ private static String cleanUpString(String line) {
+ String rc = "";
+ line = line.trim().replaceAll("('|\")", "");
+ if (line.endsWith(";")) {
+ line = line.substring(0, line.length() - 1);
+ }
+ if (line.endsWith(",")) {
+ line = line.substring(0, line.length() - 1);
+ }
+ rc = line;
+ return rc;
+ }
+
+ /**
+ * Remove the variable sigils.
+ *
+ * @param variable
+ * The variable to remove sigils from.
+ * @return A word only variable with no sigils.
+ */
+ public static String removeVariableSigils(String variable) {
+ return variable
+ .replaceAll(
+ "(\\bmy\\b|\\bour\\b|\\blocal\\b|(\\\\)?\\$|(\\\\)?@|(\\\\)?%)",
+ "");
+ }
+
+ /**
+ * Clean up the contents of the file and remove all the comments, END
+ * blocks, and block comments.
+ *
+ * @param scanner
+ * The scanner of the file to be read.
+ * @return The cleaned up content.
+ */
+ private static String cleanUpContent(Scanner scanner) {
+ String rc = "";
+ String line = "";
+ boolean flagEND = true;
+ boolean flagBC = true;
+ while (scanner.hasNext()) {
+ line = scanner.nextLine();
+ // ignore lines between ENDS
+ if (containsBeginEND(line)) {
+ flagEND = false;
+ } else if (matchesEndEND(line)) {
+ line = scanner.nextLine();
+ flagEND = true; // true
+ }
+ // ignore lines between =someword and =cut
+ if (matchesBeginBC(line)) {
+ flagBC = false;
+ } else if (matchesEndBC(line)) {
+ line = scanner.nextLine();
+ flagBC = true;
+ }
+ // remove the comments
+ if (matchesLineWithComment(line)) {
+ line = line.replaceAll(COMMENT, "");
+ }
+ // if not empty line or within comment/END block
+ if (flagEND && flagBC && !line.trim().equals("")) {
+ rc = rc.concat(line + '\n');
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line contains a function.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line contains a function.
+ */
+ public static boolean containsFunction(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(FUNCTION, Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.find()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check to see if the line contains the WriteMakefile function.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line contains the WriteMakefile function.
+ */
+ public static boolean containsMakefileFunction(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(MAKEFILE_FUNCTION,
+ Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.find()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check to see if the line contains an opening bracket.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line contains an opening bracket.
+ */
+ public static boolean containsOpener(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile("(\\(|\\[|\\{)",
+ Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.find()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line contains <<END. It is case-sensitive.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line contains <<END.
+ */
+ public static boolean containsBeginEND(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(BEGIN_END);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.find()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line is a simple assignment of a variable.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line is a simple assignment of a variable.
+ */
+ public static boolean matchesSimpleAssignment(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(SIMPLE_ASSIGNMENT,
+ Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line is a simple assignment of a variable.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line is a simple assignment of a variable.
+ */
+ public static boolean matchesAssociativeAssignment(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(ASSOCIATIVE_ASSIGNMENT,
+ Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line matches the END. It is case-sensitive.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line matches END.
+ */
+ public static boolean matchesEndEND(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(END_END);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line matches the beginning of a block comment. It is
+ * case-sensitive.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line matches the beginning of a block comment.
+ */
+ public static boolean matchesBeginBC(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(BEGIN_BC);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line matches the end of a block comment (=cut). It is
+ * case-sensitive.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line matches =cut.
+ */
+ public static boolean matchesEndBC(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(END_BC);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Check if a line matches that of a line with a comment.
+ *
+ * @param line
+ * The line to check.
+ * @return True if the line matches that of a line with a comment.
+ */
+ public static boolean matchesLineWithComment(String line) {
+ boolean rc = false;
+ Pattern pattern = Pattern.compile(LINE_WITH_COMMENT,
+ Pattern.CASE_INSENSITIVE);
+ Matcher variableMatcher = pattern.matcher(line);
+ if (variableMatcher.matches()) {
+ rc = true;
+ }
+ return rc;
+ }
+}
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/popup/actions/StubifyMakefilePLHandler.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/popup/actions/StubifyMakefilePLHandler.java
new file mode 100644
index 0000000..34f61c2
--- /dev/null
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/internal/rpmstubby/popup/actions/StubifyMakefilePLHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Neil Guzman - perl implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.rpmstubby.popup.actions;
+
+import org.eclipse.linuxtools.rpmstubby.InputType;
+
+/**
+ * Handler for the Makefile.PL stubify command.
+ *
+ */
+public class StubifyMakefilePLHandler extends StubifyHandler {
+
+ @Override
+ protected InputType getInputType() {
+ return InputType.PERL_MAKEFILE;
+ }
+
+}
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/Generator.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/Generator.java
index 18e5229..9237be6 100644
--- a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/Generator.java
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/Generator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Red Hat Inc. and others.
+ * Copyright (c) 2011, 2013 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,7 +7,7 @@
*
* Contributors:
* Alexander Kurtakov - initial API and implementation
- * Neil Guzman - python, ruby implementation
+ * Neil Guzman - python, ruby, perl implementation (B#350065,B#350066)
*******************************************************************************/
package org.eclipse.linuxtools.rpmstubby;
@@ -16,6 +16,7 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.linuxtools.internal.rpmstubby.StubbyEggGenerator;
import org.eclipse.linuxtools.internal.rpmstubby.StubbyGemGenerator;
import org.eclipse.linuxtools.internal.rpmstubby.StubbyGenerator;
+import org.eclipse.linuxtools.internal.rpmstubby.StubbyMakefilePLGenerator;
import org.eclipse.linuxtools.internal.rpmstubby.StubbyPomGenerator;
/**
@@ -56,6 +57,9 @@ public class Generator {
case RUBY_GEM:
new StubbyGemGenerator(file).writeContent();
break;
+ case PERL_MAKEFILE:
+ new StubbyMakefilePLGenerator(file).writeContent();
+ break;
default:
break;
}
diff --git a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/InputType.java b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/InputType.java
index bba1bfa..fffca4a 100644
--- a/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/InputType.java
+++ b/rpmstubby/org.eclipse.linuxtools.rpmstubby/src/org/eclipse/linuxtools/rpmstubby/InputType.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Red Hat, Inc.
+ * Copyright (c) 2011, 2013 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,7 +7,7 @@
*
* Contributors:
* Alexander Kurtakov - initial API and implementation
- * Neil Guzman - python, ruby implementation
+ * Neil Guzman - python, ruby, perl implementation (B#350065,B#350066)
*******************************************************************************/
package org.eclipse.linuxtools.rpmstubby;
@@ -25,7 +25,9 @@ public enum InputType {
/** Python Egg setup.py file */
PYTHON_EGG("setup.py"),
/** Ruby *.gemspec file */
- RUBY_GEM("*.gemspec");
+ RUBY_GEM("*.gemspec"),
+ /** Perl Makefile.PL file */
+ PERL_MAKEFILE("Makefile.PL");
private String fileNamePattern;