diff --git a/README.md b/README.md index e69de29..06f4783 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,40 @@ +Island (java version) +===================== + +Island is a tool to manage big workspace with many dependency and life cycle for big project. + +This is a re-implement of island in java with the benefit of managing the jgit interface and the "maven model" repository download for artefacts. + + +Install island +============== + +Install with krypton +-------------------- + +cf krypton repository ... + +to install: +```{.bash} +krypton install island +``` + +to remove: +```{.bash} +krypton remove island +``` + +Manual installation +------------------- + +TBD... + + +Remove old island (python) +========================== + +``` +\rm -f /home/heero/.local/bin/island +\rm -f /usr/bin/island +``` + diff --git a/src/org/atriasoft/island/Commands.java b/src/org/atriasoft/island/Commands.java index b01f48d..a9a7e81 100644 --- a/src/org/atriasoft/island/Commands.java +++ b/src/org/atriasoft/island/Commands.java @@ -1,6 +1,9 @@ package org.atriasoft.island; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -234,8 +237,8 @@ public class Commands { * @throws GitAPIException */ public static DeltaBranch getDeltaBranch(final Git git, final String branch1, final String branch2) throws IOException, GitAPIException { - List retCurrentBranchSha1 = getRevisionListToBranch(git, branch1); - List retTrackBranchSha1 = getRevisionListToBranch(git, branch2); + List retCurrentBranchSha1 = Commands.getRevisionListToBranch(git, branch1); + List retTrackBranchSha1 = Commands.getRevisionListToBranch(git, branch2); // remove all identical sha1 ==> not needed for this int inForward = 0; for (ObjectId elemSha1 : retCurrentBranchSha1) { @@ -265,5 +268,68 @@ public class Commands { } return new DeltaBranch(inForward, inBehind); } + public static void checkout(final Git git, final String destination_branch) { + try { + git.checkout().setCreateBranch(false).setName("refs/heads/" + destination_branch).call(); + } catch (GitAPIException e) { + Log.error("can not checkout branch:" + destination_branch); + e.printStackTrace(); + } + } + + public static String input() { + // Enter data using BufferReader + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + // Reading data using readLine + try { + return reader.readLine(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return ""; + } + } + + public record CreateVersion(String[] version, boolean addInManagement) {} + public static CreateVersion get_current_version_repo(final Path git_repo_path) { + Path version_path_file = git_repo_path.resolve("version.txt"); + boolean add_in_version_management = false; + String[] version_description = null; + if (!Files.exists(version_path_file)) { + Log.info("deliver: ==> No 'version.txt' file ==> not manage release version...."); + // Action to do: + boolean valid = false; + String input1 = null; + while (!valid) { + Log.print("Create a new version: (0.0.0)"); + Log.print(" (1) Add in managing version"); + Log.print(" (2) Do NOTHING & continue"); + input1 = Commands.input(); + if (input1.equals("1") || input1.equals("2") ) { + valid = true; + } else { + Log.print("!!! Must select in range [1,2]"); + } + } + if (input1.equals("1")) { + version_description = new String[]{"0", "0", "0"}; + add_in_version_management = true; + } else if (input1.equals("1")) { + Log.info("Continue Not managing for this repository"); + return null; + } else { + Log.warning("An error occured for this repository"); + return null; + } + } else { + try { + version_description = Tools.version_string_to_list(Tools.readFile(version_path_file, Charset.defaultCharset())); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return new CreateVersion(version_description, add_in_version_management); + } } diff --git a/src/org/atriasoft/island/MainIsland.java b/src/org/atriasoft/island/MainIsland.java index 8b118fa..6e82b79 100755 --- a/src/org/atriasoft/island/MainIsland.java +++ b/src/org/atriasoft/island/MainIsland.java @@ -8,13 +8,16 @@ import org.atriasoft.death.annotation.ArgCommand; import org.atriasoft.death.annotation.ArgDescription; import org.atriasoft.death.annotation.ArgName; import org.atriasoft.death.annotation.ArgSubActions; -import org.atriasoft.island.actions.Checkout; -import org.atriasoft.island.actions.Commit; -import org.atriasoft.island.actions.Fetch; -import org.atriasoft.island.actions.Init; -import org.atriasoft.island.actions.Push; -import org.atriasoft.island.actions.Status; -import org.atriasoft.island.actions.Sync; +import org.atriasoft.island.actions.BaseCheckout; +import org.atriasoft.island.actions.BaseCommit; +import org.atriasoft.island.actions.Deliver; +import org.atriasoft.island.actions.BaseFetch; +import org.atriasoft.island.actions.BaseInit; +import org.atriasoft.island.actions.ManifestCheckout; +import org.atriasoft.island.actions.ManifestStatus; +import org.atriasoft.island.actions.BasePush; +import org.atriasoft.island.actions.BaseStatus; +import org.atriasoft.island.actions.BaseSync; import org.atriasoft.island.actions.VolatileAdd; import org.atriasoft.island.actions.VolatileList; import org.atriasoft.island.actions.VolatileRemove; @@ -64,16 +67,19 @@ public class MainIsland { @ArgSubActions static public final ActionList subActions = new ActionList(); static { - MainConfig.subActions.add(Init.class); - MainConfig.subActions.add(Status.class); - MainConfig.subActions.add(Checkout.class); - MainConfig.subActions.add(Sync.class); - MainConfig.subActions.add(Fetch.class); - MainConfig.subActions.add(Commit.class); - MainConfig.subActions.add(Push.class); + MainConfig.subActions.add(BaseInit.class); + MainConfig.subActions.add(BaseStatus.class); + MainConfig.subActions.add(BaseCheckout.class); + MainConfig.subActions.add(BaseSync.class); + MainConfig.subActions.add(BaseFetch.class); + MainConfig.subActions.add(BaseCommit.class); + MainConfig.subActions.add(BasePush.class); MainConfig.subActions.add(VolatileAdd.class); MainConfig.subActions.add(VolatileRemove.class); MainConfig.subActions.add(VolatileList.class); + MainConfig.subActions.add(ManifestCheckout.class); + MainConfig.subActions.add(ManifestStatus.class); + MainConfig.subActions.add(Deliver.class); } public boolean check_boolean(final String value) { diff --git a/src/org/atriasoft/island/Manifest.java b/src/org/atriasoft/island/Manifest.java index 7e9d74e..38740ff 100644 --- a/src/org/atriasoft/island/Manifest.java +++ b/src/org/atriasoft/island/Manifest.java @@ -112,226 +112,6 @@ public class Manifest { tmpManifest.setFileRealPath(maniPath); this.manifests.put(includeElem, tmpManifest); } - /* - XmlElement rootNode = Exml.parse(this.manifestXml).getNodes().get(0).toElement(); - Log.debug("manifest : '" + this.manifestXml + "'"); - if (!rootNode.getValue().equals("manifest")) { - Log.error(" in '" + this.manifestXml + "' have not main xml node='manifest'"); - } - for (XmlNode child : rootNode.getNodes()) { - if (child.getType() == XmlNodeType.COMMENT) { - Log.verbose(" comment='" + child + "'"); - continue; - } - if (child.getValue().equals("remote")) { - String name = "origin"; - String fetch = ""; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("name")) { - name = attr.getValue(); - } else if (attr.getName().equals("fetch")) { - fetch = attr.getValue(); - // When we use manifest with relative element of the manifest git. - if (fetch.length() >= 2 && fetch.startsWith("..")) { - // we have a relative island manifest ==> use local manifest origin to get the full origin - Git git = Git.open(Env.get_island_path_manifest().toFile()); - RemoteListCommand remoteList = git.remoteList(); - -// cmd = "git remote get-url origin" -// Log.verbose("execute : " + cmd) -// base_origin = multiprocess.run_command(cmd, cwd=) -// Log.verbose("base_origin=" + base_origin[1]) -// base_origin = base_origin[1] -// while len(fetch) >= 2 \ -// and fetch[:2].equals("..": -// fetch = fetch[2:] -// while len(fetch) >= 1 \ -// and ( fetch[0].equals("/" \ -// or fetch[0].equals("\\"): -// fetch = fetch[1:] -// offset_1 = base_origin.rfind('/') -// offset_2 = base_origin.rfind(':') -// if offset_1 > offset_2: -// base_origin = base_origin[:offset_1] -// else: -// base_origin = base_origin[:offset_2] -// Log.verbose("new base_origin=" + base_origin) -// Log.verbose("tmp fetch=" + fetch) -// if fetch != "": -// fetch = base_origin + "/" + fetch -// else: -// fetch = base_origin - Log.verbose("new fetch=" + fetch); - } - fetch = removeEndSlash(fetch); - } else { - Log.error("Parsing the manifest : Unknow '" + child.getValue() + "' attibute : '" + attr.getName() + "', availlable:[name,fetch]"); - } - } - Log.debug(" find '" + child.getValue() + "' : name='" + name + "' fetch='" + fetch + "'"); - // parse the sub global mirror list - List mirror_list = new ArrayList<>(); - for (XmlNode child_2 : child.toElement().getNodes()) { - if (child_2.getValue().equals("mirror")) { - // find a new mirror - String mirror_name = ""; - String mirror_fetch = ""; - for (XmlAttribute attr_2 : child_2.toElement().getAttributes()) { - if (attr_2.getName().equals("name")) { - mirror_name = attr_2.getValue(); - } else if (attr_2.getName().equals("fetch")) { - mirror_fetch = attr_2.getValue(); - mirror_fetch = removeEndSlash(mirror_fetch); - } else { - Log.error("Parsing the manifest : Unknow '" + child_2.getValue() + "' attibute : '" + attr_2 + "', availlable:[name,fetch]"); - } - } - Log.debug("mirror: '" + mirror_name + "' '" + mirror_fetch + "'"); - if (mirror_name.isEmpty()) { - Log.critical("Missing mirrot 'name'"); - } - if (mirror_fetch.isEmpty()) { - Log.critical("Missing mirror 'fetch'"); - } - mirror_list.add(new MirrorConfig(mirror_name, mirror_fetch)); - } else { - Log.critical("Parsing the manifest : Unknow '" + child_2.getValue() + "', availlable:[mirror]"); - } - } - this.remotes.add(new RemoteConfig(name, fetch, mirror_list)); - continue; - } - if (child.getValue().equals("include")) { - String name = ""; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("name")) { - name = attr.getValue(); - } else { - Log.error("Parsing the manifest : Unknow '" + child.getValue() + "' attibute : '" + attr + "', availlable:[name]"); - } - } - Log.debug(" find '" + child.getValue() + "' : name='" + name + "'"); - // check if the file exist ... - Path new_name_xml = this.manifestXml.resolve(name); - if (!Files.exists(new_name_xml)) { - Log.critical("The file does not exist: " + new_name_xml); - } - this.includes.add(new IncludeConfig(name, new_name_xml, null)); - continue; - } - if (child.getValue().equals("default")) { - String remote = "origin"; - String revision = "master"; - boolean sync = false; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("remote")) { - remote = attr.getValue(); - } else if (attr.getName().equals("revision")) { - revision = attr.getValue(); - } else if (attr.getName().equals("sync-s")) { // synchronize submodule ... automaticaly - String syncBase = attr.getValue(); - if (syncBase.equalsIgnoreCase("true") - || syncBase.equals("1") - || syncBase.toLowerCase().equals("yes")) { - sync = true; - } else if (syncBase.equalsIgnoreCase("false") - || syncBase.equals("0") - || syncBase.equalsIgnoreCase("no")) { - sync = false; - } else { - Log.critical("Parsing the manifest : Unknow '" + child.getValue() + "' attibute : '" + attr + "', value:'" + sync + "' availlable:[true,1,yes,false,0,no]"); - } - } else { - Log.error("Parsing the manifest : Unknow '" + child.getValue() + "' attibute : '" + attr + "', availlable:[remote,revision,sync-s]"); - } - } - if (this.defaultWhat != null) { - Log.error("Parsing the manifest : Node '" + child.getValue() + "' already set"); - } - this.defaultWhat = new RepositoryConfig(remote, revision, sync); - Log.debug(" find '" + child.getValue() + "' : remote='" + remote + "' revision='" + revision + "' sync=" + sync); - continue; - } - if (child.getValue().equals("project")) { - String name = ""; - String path = ""; - String tag_sha1 = null; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("name")) { - name = attr.getValue(); - } else if (attr.getName().equals("path")) { - path = attr.getValue(); - } else if (attr.getName().equals("tag")) { - tag_sha1 = attr.getValue(); - } else { - Log.error("Parsing the manifest: Unknow '" + child.getValue() + "' attibute : '" + attr + "', availlable:[name,tag,sync-s]"); - } - } - if (name.isEmpty()) { - Log.error("Parsing the manifest: '" + child.getValue() + "' missing attribute: 'name' ==> specify the git to clone ..."); - } - this.projects.add(new ProjectConfig(name, path, tag_sha1)); - Log.debug(" find '" + child.getValue() + "' : name='" + name + "' path='" + path + "' tag='" + tag_sha1 + "'"); - continue; - } - if (child.getValue().equals("option")) { - // not managed ==> future use - String type_option = ""; - String value_option = ""; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("type")) { - type_option = attr.getValue(); - } else if (attr.getName().equals("value")) { - value_option = attr.getValue(); - } else { - Log.error("Parsing the manifest: Unknow '" + child.getValue() + "' attibute : '" + attr + "', availlable:[type,value]"); - } - } - if (type_option.equals("deliver-master")) { - this.deliver_master = value_option; - } else if (type_option.equals("deliver-develop")) { - this.deliver_develop = value_option; - } else if (type_option.equals("deliver-mode")) { - this.deliver_mode = value_option; - if (!this.deliver_mode.equals("merge") && !this.deliver_mode.equals("fast-forward")) { - Log.critical("Parsing the manifest: option 'deliver-mode' value availlable: [merge,fast-forward]"); - } - } else { - Log.critical("Parsing the manifest: Unknow 'type' value availlable: [deliver-master,deliver-develop,deliver-mode]"); - } - continue; - } - if (child.getValue().equals("link")) { - // not managed ==> future use - String source = ""; - String destination = ""; - for (XmlAttribute attr : child.toElement().getAttributes()) { - if (attr.getName().equals("source")) { - source = attr.getValue(); - } else if (attr.getName().equals("destination")) { - destination = attr.getValue(); - } else { - Log.critical("Parsing the manifest: Unknow '" + child.getValue() + "' attibute : '" + attr + "', availlable:[source,destination]"); - } - } - if (source.isEmpty()) { - Log.error("Parsing the manifest: '" + child.getValue() + "' missing attribute: 'source' ==> specify the git to clone ..."); - } - if (destination.isEmpty()) { - Log.error("Parsing the manifest: '" + child.getValue() + "' missing attribute: 'destination' ==> specify the git to clone ..."); - } - this.links.add(new Link(source, destination)); - Log.debug("Add link: '" + destination + "' ==> '" + source + "'"); - continue; - } - Log.info(" '" + child.getValue() + "' values=" + child.toElement().getAttributes()); - Log.error("Parsing error Unknow NODE : '" + child.getValue() + "' availlable:[remote,include,default,project,option,link]"); - } - // now we parse all sub repo: - for (IncludeConfig elem : this.includes) { - elem.setManifest(new Manifest(elem.getPath())); - } - */ } @@ -345,17 +125,6 @@ public class Manifest { } return path; } -// public void checkDoublePath(this, list_path = [], space="") { -// Log.debug(space + "check path : '" + this.manifest_xml + "'") -// for elem in this.projects: -// path = this._create_path_with_elem(elem) -// Log.debug(space + " check path:'" + str(path) + "'") -// if path in list_path: -// Log.error("Check Manifest error : double use of the path '" + str(path) + "'") -// list_path.append(path) -// for elem in this.includes: -// elem["manifest"]._check_double_path(list_path, space + " ") -// } public List get_all_configs() { ManifestFile mani = this.manifests.get(this.rootManifest); @@ -476,122 +245,19 @@ public class Manifest { */ return out; } - -// -//public void tag_manifest(manifest_xml_filename, all_tags): -// tree = etree.parse(manifest_xml_filename) -// Log.debug("manifest : '" + manifest_xml_filename + "'") -// root = tree.getroot() -// includes = [] -// if root.tag != "manifest": -// Log.error("(l:" + str(child.sourceline) + ") in '" + str(file) + "' have not main xml node='manifest'") -// return false -// for child in root: -// if type(child) == etree._Comment: -// Log.verbose("(l:" + str(child.sourceline) + ") comment='" + str(child.text) + "'"); -// continue -// if child.tag.equals("remote": -// continue -// if child.tag.equals("include": -// name = "" -// for attr in child.attrib: -// if attr.equals("name": -// name = child.attrib[attr] -// else: -// Log.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name]") -// Log.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : name='" + name + "'"); -// // check if the file exist ... -// new_name_xml = new Path(os.path.dirname(manifest_xml_filename),name) -// if os.path.exists(new_name_xml) == false: -// Log.error("(l:" + str(child.sourceline) + ") The file does not exist : '" + new_name_xml + "'") -// includes.append({ -// "name":name, -// "path":new_name_xml, -// "manifest":None -// }) -// continue -// if child.tag.equals("default": -// continue -// if child.tag.equals("project": -// name = "" -// path = "" -// tag_sha1 = None -// for attr in child.attrib: -// if attr.equals("name": -// name = child.attrib[attr] -// } else if attr.equals("path": -// path = child.attrib[attr] -// } else if attr.equals("tag": -// tag_sha1 = child.attrib[attr] -// else: -// Log.error("(l:" + str(child.sourceline) + ") Parsing the manifest: Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name,tag,sync-s]") -// if name.equals("": -// Log.error("(l:" + str(child.sourceline) + ") Parsing the manifest: '" + child.tag + "' missing attribute: 'name' ==> specify the git to clone ...") -// for elem_tag in all_tags: -// if elem_tag["name"] == name: -// child.set("tag", elem_tag["tag"]) -// continue -// if child.tag.equals("option": -// // not managed ==> future use -// continue -// if child.tag.equals("link": -// continue -// Log.info("(l:" + str(child.sourceline) + ") '" + str(child.tag) + "' values=" + str(child.attrib)); -// Log.error("(l:" + str(child.sourceline) + ") Parsing error Unknow NODE : '" + str(child.tag) + "' availlable:[remote,include,default,project,option,link]") -// tree.write(manifest_xml_filename, pretty_print=true, xml_declaration=true, encoding="utf-8") -// // now we parse all sub repo: -// for elem in includes: -// tag_manifest(elem["path"], all_tags) -// -// -// -//public void tag_clear(manifest_xml_filename): -// tree = etree.parse(manifest_xml_filename) -// Log.debug("manifest : '" + manifest_xml_filename + "'") -// root = tree.getroot() -// includes = [] -// if root.tag != "manifest": -// Log.error("(l:" + str(child.sourceline) + ") in '" + str(file) + "' have not main xml node='manifest'") -// return false -// for child in root: -// if type(child) == etree._Comment: -// Log.verbose("(l:" + str(child.sourceline) + ") comment='" + str(child.text) + "'"); -// continue -// if child.tag.equals("remote": -// continue -// if child.tag.equals("include": -// name = "" -// for attr in child.attrib: -// if attr.equals("name": -// name = child.attrib[attr] -// else: -// Log.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name]") -// Log.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : name='" + name + "'"); -// // check if the file exist ... -// new_name_xml = new Path(os.path.dirname(manifest_xml_filename),name) -// if os.path.exists(new_name_xml) == false: -// Log.error("(l:" + str(child.sourceline) + ") The file does not exist : '" + new_name_xml + "'") -// includes.append({ -// "name":name, -// "path":new_name_xml, -// "manifest":None -// }) -// continue -// if child.tag.equals("default": -// continue -// if child.tag.equals("project": -// child.attrib.pop("tag", None) -// continue -// if child.tag.equals("option": -// continue -// if child.tag.equals("link": -// continue -// Log.info("(l:" + str(child.sourceline) + ") '" + str(child.tag) + "' values=" + str(child.attrib)); -// Log.error("(l:" + str(child.sourceline) + ") Parsing error Unknow NODE : '" + str(child.tag) + "' availlable:[remote,include,default,project,option,link]") -// tree.write(manifest_xml_filename, pretty_print=true, xml_declaration=true, encoding="utf-8") -// // now we parse all sub repo: -// for elem in includes: -// tag_clear(elem["path"]) -// + public String getDeliverDevelop() { + OptionRepository defaultPlouf = this.defaultBase; + if (this.defaultWhat != null) { + defaultPlouf = this.defaultWhat; + } + return defaultPlouf.getBranchDevelop(); + } + public String getBranchRelease() { + OptionRepository defaultPlouf = this.defaultBase; + if (this.defaultWhat != null) { + defaultPlouf = this.defaultWhat; + } + return defaultPlouf.getBranchRelease(); + } } diff --git a/src/org/atriasoft/island/Tools.java b/src/org/atriasoft/island/Tools.java index 8f53ef0..1105d8f 100644 --- a/src/org/atriasoft/island/Tools.java +++ b/src/org/atriasoft/island/Tools.java @@ -1,8 +1,12 @@ package org.atriasoft.island; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.atriasoft.island.internal.Log; import org.atriasoft.island.model.ProjectConfig; @@ -43,4 +47,35 @@ public class Tools { } } + public static String readFile(final Path path, final Charset encoding) throws IOException { + byte[] encoded = Files.readAllBytes(path); + return new String(encoded, encoding); + } + + /** + * Generate the split of the generic version : + * - 1.5.2-dev + * @param version + * @return list of element : {"1", "5", "2", "dev"} + */ + public static String[] version_string_to_list(final String version) { + Log.verbose("parse version string '" + version +"'"); + List out = new ArrayList<>(); + if (version == null || version.isEmpty()) { + return new String[]{"0", "0", "0"}; + } + String[] elems = version.split("-"); + if (elems[0].split(".").length <= 1) { + Log.critical("Can not parde a version with wrong version model '" + version +"'"); + } + List values = Arrays.asList(elems[0].split(".")); + for (String elem : values) { + out.add(elem); + } + if (elems.length >= 2) { + out.add(elems[1]); + } + return out.toArray(new String[0]); + } + } diff --git a/src/org/atriasoft/island/actions/Checkout.java b/src/org/atriasoft/island/actions/BaseCheckout.java similarity index 98% rename from src/org/atriasoft/island/actions/Checkout.java rename to src/org/atriasoft/island/actions/BaseCheckout.java index 1d3c1b0..f017ec2 100644 --- a/src/org/atriasoft/island/actions/Checkout.java +++ b/src/org/atriasoft/island/actions/BaseCheckout.java @@ -27,7 +27,7 @@ import org.atriasoft.island.model.ProjectConfig; "checkout -r github master", "checkout -r=gitlab master", }) -public class Checkout { +public class BaseCheckout { @ArgName("remote") @ArgAlias('r') @ArgDescription("Name of the remote server") diff --git a/src/org/atriasoft/island/actions/Commit.java b/src/org/atriasoft/island/actions/BaseCommit.java similarity index 99% rename from src/org/atriasoft/island/actions/Commit.java rename to src/org/atriasoft/island/actions/BaseCommit.java index 9828dca..0e3cc6d 100644 --- a/src/org/atriasoft/island/actions/Commit.java +++ b/src/org/atriasoft/island/actions/BaseCommit.java @@ -25,7 +25,7 @@ import org.eclipse.jgit.api.Git; @ArgCommand("commit") @ArgDescription("commit in all repository") @ArgSample("commit -a --amend -m \"[DEV] your comment\"") -public class Commit { +public class BaseCommit { @ArgName("message") @ArgAlias('m') diff --git a/src/org/atriasoft/island/actions/Fetch.java b/src/org/atriasoft/island/actions/BaseFetch.java similarity index 99% rename from src/org/atriasoft/island/actions/Fetch.java rename to src/org/atriasoft/island/actions/BaseFetch.java index 1382d6d..da69498 100644 --- a/src/org/atriasoft/island/actions/Fetch.java +++ b/src/org/atriasoft/island/actions/BaseFetch.java @@ -27,7 +27,7 @@ import org.eclipse.jgit.lib.TextProgressMonitor; @ArgCommand("push") @ArgDescription("Update all the repository remote branch") @ArgSample("fetch --remote=github") -public class Fetch { +public class BaseFetch { @ArgName("remote") @ArgAlias('r') diff --git a/src/org/atriasoft/island/actions/Init.java b/src/org/atriasoft/island/actions/BaseInit.java similarity index 99% rename from src/org/atriasoft/island/actions/Init.java rename to src/org/atriasoft/island/actions/BaseInit.java index 85ca236..7618d81 100644 --- a/src/org/atriasoft/island/actions/Init.java +++ b/src/org/atriasoft/island/actions/BaseInit.java @@ -25,7 +25,7 @@ import org.eclipse.jgit.transport.sshd.SshdSessionFactory; @ArgCommand("init") @ArgDescription("Initialize an island workspace (need 'fetch' after)") @ArgSample("init http://github.com/atria-soft/manifest.git") -public class Init { +public class BaseInit { @ArgName("branch") @ArgAlias('b') @ArgDescription("Select the branch to checkout") diff --git a/src/org/atriasoft/island/actions/Push.java b/src/org/atriasoft/island/actions/BasePush.java similarity index 99% rename from src/org/atriasoft/island/actions/Push.java rename to src/org/atriasoft/island/actions/BasePush.java index 236f2d0..268cb2c 100644 --- a/src/org/atriasoft/island/actions/Push.java +++ b/src/org/atriasoft/island/actions/BasePush.java @@ -27,7 +27,7 @@ import org.eclipse.jgit.transport.PushResult; @ArgCommand("push") @ArgDescription("Push all repository to the upper server") @ArgSample("push --remote=github") -public class Push { +public class BasePush { @ArgName("remote") @ArgAlias('r') @ArgDescription("Name of the remote server") diff --git a/src/org/atriasoft/island/actions/Status.java b/src/org/atriasoft/island/actions/BaseStatus.java similarity index 98% rename from src/org/atriasoft/island/actions/Status.java rename to src/org/atriasoft/island/actions/BaseStatus.java index 5190bf2..6a78759 100644 --- a/src/org/atriasoft/island/actions/Status.java +++ b/src/org/atriasoft/island/actions/BaseStatus.java @@ -24,7 +24,7 @@ import org.eclipse.jgit.api.Git; @ArgCommand("status") @ArgDescription("Get the status of all the repositories") @ArgSample("status --tags") -public class Status { +public class BaseStatus { @ArgName("remote") @ArgAlias('r') diff --git a/src/org/atriasoft/island/actions/Sync.java b/src/org/atriasoft/island/actions/BaseSync.java similarity index 99% rename from src/org/atriasoft/island/actions/Sync.java rename to src/org/atriasoft/island/actions/BaseSync.java index 4999a3c..485da50 100644 --- a/src/org/atriasoft/island/actions/Sync.java +++ b/src/org/atriasoft/island/actions/BaseSync.java @@ -30,7 +30,7 @@ import org.eclipse.jgit.lib.TextProgressMonitor; @ArgCommand("sync") @ArgDescription("Syncronize all the repository referenced") @ArgSample("sync -d") -public class Sync { +public class BaseSync { @ArgName("download") @ArgAlias('d') diff --git a/src/org/atriasoft/island/actions/Deliver.java b/src/org/atriasoft/island/actions/Deliver.java new file mode 100644 index 0000000..2d43942 --- /dev/null +++ b/src/org/atriasoft/island/actions/Deliver.java @@ -0,0 +1,133 @@ +package org.atriasoft.island.actions; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import org.atriasoft.death.annotation.ArgAlias; +import org.atriasoft.death.annotation.ArgCommand; +import org.atriasoft.death.annotation.ArgDescription; +import org.atriasoft.death.annotation.ArgExecute; +import org.atriasoft.death.annotation.ArgName; +import org.atriasoft.death.annotation.ArgSample; +import org.atriasoft.island.Commands; +import org.atriasoft.island.Commands.CreateVersion; +import org.atriasoft.island.Config; +import org.atriasoft.island.Env; +import org.atriasoft.island.Manifest; +import org.atriasoft.island.Tools; +import org.atriasoft.island.internal.Log; +import org.atriasoft.island.model.ActionException; +import org.atriasoft.island.model.ConfigManifest; +import org.atriasoft.island.model.ProjectConfig; + +import org.eclipse.jgit.api.Git; + +@ArgCommand("deliver") +@ArgDescription("Deliver the current repository (develop & master MUST be up to date and you MUST be on master)") +@ArgSample("deliver --from=develop --to=master") +public class Deliver { + + @ArgName("from") + @ArgAlias('f') + @ArgDescription("Source branch to deliver") + public String from = null; + + @ArgName("to") + @ArgAlias('t') + @ArgDescription("Desticantion branche of the deliver") + public String to = null; + + @ArgExecute + public void execute() throws ActionException, Exception { + + // check system is OK + Manifest.checkIsInit(); + ConfigManifest configuration = Config.getUniqueConfig(); + // load the manifest after pulling it (if possible) + Path file_source_manifest = Env.getIslandPathManifest().resolve(configuration.getManifestName()); + if (!Files.exists(file_source_manifest)) { + Log.critical("Missing manifest file : '" + file_source_manifest + "'"); + } + Manifest mani = new Manifest(file_source_manifest); + if (this.from == null || this.from.isEmpty()) { + this.from = mani.getDeliverDevelop(); + } + if (this.to == null || this.to.isEmpty()) { + this.to = mani.getBranchRelease(); + } + + List all_project = mani.get_all_configs(); + Log.info("Check if all project are on master: " + all_project.size() + " projects"); + boolean deliver_availlable = true; + int id_element = 0; + for (ProjectConfig elem : all_project) { + id_element++; + String base_display = Tools.get_list_base_display(id_element, all_project.size(), elem); + Log.verbose("delivercheck : " + base_display); + if (!StatusActions.deliverCheck(elem, null, id_element, base_display, this.from, this.to)) { + deliver_availlable = false; + } + } + if (!deliver_availlable) { + Log.error("deliver-ckeck: Correct the warning to validate the Merge"); + return; + } + Log.info("deliver-ckeck: ==> All is OK"); + id_element = 0; + for (ProjectConfig elem : all_project) { + id_element += 1; + String base_display = Tools.get_list_base_display(id_element, all_project.size(), elem); + Log.info("deliver: ========================================================================"); + Log.info("deliver:.equals(" + base_display); + Log.info("deliver: ========================================================================"); + + Path git_repo_path = Env.get_island_root_path().resolve(elem.getPath()); + // Check the validity of the version, + CreateVersion curentVersionElem = Commands.get_current_version_repo(git_repo_path); + if (curentVersionElem == null) { + continue; + } + Log.info("deliver: ==> version: " + curentVersionElem.version()); + + + + Git git = Git.open(git_repo_path.toFile()); + + // go to the dev branch + select_branch = Commands.get_current_branch(git_repo_path); + + // Checkout destination branch: + Commands.checkout(git_repo_path, destination_branch); + + // create new repo tag + new_version_description = status.create_new_version_repo(git_repo_path, version_description, add_in_version_management, source_branch, destination_branch); + Log.info("new version: " + str(new_version_description)); + if (new_version_description == null) { + continue; + } + // merge branch + if (mani.deliver_mode.equals("merge") ) { + merge_force = true; + } else { + merge_force = false; + } + Commands.merge_branch_on_master(git_repo_path, source_branch, merge_force, branch_destination=destination_branch); + + version_path_file = new Path(git_repo_path, "version.txt"); + // update version file: + tools.file_write_data(version_path_file, tools.version_to_string(new_version_description)); + Commands.add_file(git_repo_path, version_path_file); + Commands.commit_all(git_repo_path, "[RELEASE] Release v" + tools.version_to_string(new_version_description)); + Commands.tag(git_repo_path, "v" + tools.version_to_string(new_version_description)); + Commands.checkout(git_repo_path, source_branch); + Commands.reset_hard(git_repo_path, destination_branch); + new_version_description.append("dev"); + tools.file_write_data(version_path_file, tools.version_to_string(new_version_description)); + Commands.add_file(git_repo_path, version_path_file); + Commands.commit_all(git_repo_path, status.default_update_message); + Commands.checkout(git_repo_path, destination_branch); + } + } +} + diff --git a/src/org/atriasoft/island/actions/ManifestCheckout.java b/src/org/atriasoft/island/actions/ManifestCheckout.java new file mode 100644 index 0000000..c3a1929 --- /dev/null +++ b/src/org/atriasoft/island/actions/ManifestCheckout.java @@ -0,0 +1,46 @@ +package org.atriasoft.island.actions; +import org.atriasoft.death.annotation.ArgAlias; +import org.atriasoft.death.annotation.ArgCommand; +import org.atriasoft.death.annotation.ArgDescription; +import org.atriasoft.death.annotation.ArgExecute; +import org.atriasoft.death.annotation.ArgName; +import org.atriasoft.death.annotation.ArgParams; +import org.atriasoft.death.annotation.ArgParamsDescription; +import org.atriasoft.death.annotation.ArgSample; +import org.atriasoft.island.Config; +import org.atriasoft.island.Manifest; +import org.atriasoft.island.Tools; +import org.atriasoft.island.internal.Log; +import org.atriasoft.island.model.ActionException; +import org.atriasoft.island.model.ConfigManifest; +import org.atriasoft.island.model.ProjectConfig; + +@ArgCommand("manifest-checkout") +@ArgDescription("Ckeckout a specific branch of the manifest") +@ArgSample({ + "manifest-checkout dev", + "manifest-checkout -r github master", + "manifest-checkout -r=gitlab master", + }) +public class ManifestCheckout { + @ArgName("remote") + @ArgAlias('r') + @ArgDescription("Name of the remote server") + public String remote = null; + + @ArgExecute + @ArgParams("branch") + @ArgParamsDescription("Branch to checkout (if '__TAG__' ==> checkout specific repository tags)") + public void execute(final String branch) throws ActionException, Exception { + // check system is OK + Manifest.checkIsInit(); + + ConfigManifest configuration = Config.getUniqueConfig(); + ProjectConfig elem = configuration.getManifestConfig(); + String base_display = Tools.get_list_base_display(0, 0, elem); + if (!StatusActions.checkout_elem(elem, this.remote, branch, base_display)) { + Log.error("Checkout have fail !!! "); + } + } + +} diff --git a/src/org/atriasoft/island/actions/ManifestStatus.java b/src/org/atriasoft/island/actions/ManifestStatus.java new file mode 100644 index 0000000..077b923 --- /dev/null +++ b/src/org/atriasoft/island/actions/ManifestStatus.java @@ -0,0 +1,41 @@ +package org.atriasoft.island.actions; + +import org.atriasoft.death.annotation.ArgAlias; +import org.atriasoft.death.annotation.ArgCommand; +import org.atriasoft.death.annotation.ArgDescription; +import org.atriasoft.death.annotation.ArgExecute; +import org.atriasoft.death.annotation.ArgName; +import org.atriasoft.death.annotation.ArgSample; +import org.atriasoft.island.Config; +import org.atriasoft.island.Manifest; +import org.atriasoft.island.Tools; +import org.atriasoft.island.model.ActionException; +import org.atriasoft.island.model.ConfigManifest; +import org.atriasoft.island.model.ProjectConfig; + +@ArgCommand("manifest-status") +@ArgDescription("Get the status of manifest repositories") +@ArgSample("manifest-status --tags") +public class ManifestStatus { + + @ArgName("remote") + @ArgAlias('r') + @ArgDescription("Name of the remote server") + public String remote = "origin"; + + @ArgName("tags") + @ArgAlias('t') + @ArgDescription("Display if the commit is on a tag (and display it)") + public boolean displayTag = false; + + @ArgExecute + public void execute() throws ActionException, Exception { + // check system is OK + Manifest.checkIsInit(); + ConfigManifest configuration = Config.getUniqueConfig(); + ProjectConfig elem = configuration.getManifestConfig(); + String base_display = Tools.get_list_base_display(0, 0, elem); + StatusActions.displayStatus(elem, this.remote, this.displayTag, 0, base_display); + } + +} diff --git a/src/org/atriasoft/island/actions/StatusActions.java b/src/org/atriasoft/island/actions/StatusActions.java index 6a30823..25eb1e7 100644 --- a/src/org/atriasoft/island/actions/StatusActions.java +++ b/src/org/atriasoft/island/actions/StatusActions.java @@ -31,7 +31,7 @@ public class StatusActions { // check if the repository is modify Git git = Git.open(git_repo_path.toFile()); boolean is_modify = git.status().call().hasUncommittedChanges(); - if (is_modify == true){ + if (is_modify){ Log.warning("checkout " + base_display + " ==> modify data can not checkout new branch"); return false; } @@ -194,6 +194,62 @@ public class StatusActions { Commands.getDiff(git); return deltas.behind(); } + + public static boolean deliverCheck(final ProjectConfig elem, final String argument_remote_name, final int id_element, final String base_display, final String source_branch, final String destination_branch) throws GitAPIException, IOException { + boolean deliver_availlable = true; + Log.debug("deliver-ckeck: " + base_display); + Log.debug(" ==> check repo exist"); + // Check the repo exist + Path git_repo_path = Env.get_island_root_path().resolve(elem.getPath()); + if (!Files.exists(git_repo_path)) { + Log.warning("deliver-ckeck: " + base_display + " ==> MUST be download"); + return false; + } + Log.debug(" ==> check is modify"); + // check if the curent repo is modify + Git git = Git.open(git_repo_path.toFile()); + boolean is_modify = git.status().call().hasUncommittedChanges(); + if (is_modify) { + Log.warning("deliver-ckeck: " + base_display + " ==> MUST not be modify"); + return false; + } + + Log.debug(" ==> check current branch is '" + source_branch + "'"); + // check if we are on source_branch + String select_branch = git.getRepository().getBranch(); + if (!select_branch.equals(source_branch)) { + Log.warning("deliver-ckeck: " + base_display + " ==> MUST be on source branch: '" + source_branch + "' and is: '" + select_branch + "'"); + return false; + } + Log.debug(" ==> check have tracking branch"); + // check if we have a remote traking branch + String tracking_remote_branch = Commands.getTrackingBranch(git, argument_remote_name, select_branch); + if (tracking_remote_branch == null) { + Log.warning("deliver-ckeck: " + base_display + " ==> MUST have a remote tracking branch"); + deliver_availlable = false; + } + + // go on destination branch + Commands.checkout(git, destination_branch); + Log.debug(" ==> check current branch is '" + source_branch + "'"); + // check if we are on "master" + select_branch = git.getRepository().getBranch(); + if (select_branch != destination_branch) { + Log.warning("deliver-ckeck: " + base_display + " ==> Can not checkout branch: '" + destination_branch + "' and is: '" + select_branch + "'"); + deliver_availlable = false; + } + Log.debug(" ==> check have tracking branch"); + // check if we have a remote traking branch + tracking_remote_branch = Commands.getTrackingBranch(git, argument_remote_name, select_branch); + if (tracking_remote_branch == null) { + Log.warning("deliver-ckeck: " + base_display + " ==> MUST have a remote tracking branch"); + deliver_availlable = false; + } + + // check out back the source branch + Commands.checkout(git, source_branch); + return deliver_availlable; + } } diff --git a/src/org/atriasoft/island/model/ConfigManifest.java b/src/org/atriasoft/island/model/ConfigManifest.java index 863461a..d3872e3 100644 --- a/src/org/atriasoft/island/model/ConfigManifest.java +++ b/src/org/atriasoft/island/model/ConfigManifest.java @@ -169,4 +169,8 @@ public class ConfigManifest { return addressManifest + offsetFetch + name; } + + public ProjectConfig getManifestConfig() { + return new ProjectConfig("manifest", Env.getIslandPathManifest().resolve(getManifestName()).toString()); + } } \ No newline at end of file diff --git a/tmpsrc/actions/islandAction_deliver.java b/tmpsrc/actions/islandAction_deliver.java index bccad18..2d3ec29 100644 --- a/tmpsrc/actions/islandAction_deliver.java +++ b/tmpsrc/actions/islandAction_deliver.java @@ -88,6 +88,12 @@ public void execute(_arguments): if deliver_availlable == false: Log.error("deliver-ckeck: Correct the warning to validate the Merge") return + + + + + + Log.info("deliver-ckeck: ==> All is OK") id_element = 0 for elem in all_project: @@ -96,9 +102,7 @@ public void execute(_arguments): Log.info("deliver: ========================================================================") Log.info("deliver:.equals(" + base_display) Log.info("deliver: ========================================================================") - - git_repo_path = new Path(Env.get_island_root_path(), elem.path) - // Check the validity of the version, +git_repo_path = new Path(Env.get_island_root_path(), elem.path)// Check the validity of the version, version_description, add_in_version_management = status.get_current_version_repo(git_repo_path) if version_description == None: continue @@ -120,7 +124,7 @@ public void execute(_arguments): merge_force = true else: merge_force = false - commands.merge_branch_on_master(git_repo_path, source_branch, merge_force, branch_destination=destination_branch) + commands.merge_branch_on_master(git_repo_pat source_branch, merge_force, branch_destination=destination_branch) version_path_file = new Path(git_repo_path, "version.txt") // update version file: diff --git a/tmpsrc/actions/islandAction_manifest-checkout.java b/tmpsrc/actions/islandAction_manifest-checkout.java deleted file mode 100644 index 764ddd4..0000000 --- a/tmpsrc/actions/islandAction_manifest-checkout.java +++ /dev/null @@ -1,72 +0,0 @@ -//!/usr/bin/python -// -*- coding: utf-8 -*- -//# -//# @author Edouard DUPIN -//# -//# @copyright 2012, Edouard DUPIN, all right reserved -//# -//# @license MPL v2.0 (see license file) -//# - -from realog import Log -from island import tools -from island import env -from island import config -from island import multiprocess -from island import manifest -from island import commands -import status -import os - - -//# -//# @brief Get the global description of the current action -//# @return (string) the description string (fist line if reserved for the overview, all is for the specific display) -//# -public void help(): - return "Manifest Ckeckout a specific branch of repository" - -//# -//# @brief Add argument to the specific action -//# @param[in,out] my_args (death.Arguments) Argument manager -//# @param[in] section Name of the currect action -//# -public void add_specific_arguments(my_args, section): - my_args.add("r", "remote", haveParam=true, desc="Name of the remote server") - my_args.add_arg("branch", optionnal=false, desc="Branch to checkout (if '__TAG__' ==> checkout specific repository tags)") - -//# -//# @brief Execute the action required. -//# -//# @return error value [0 .. 50] the <0 value is reserved system ==> else, what you want. -//# None : No error (return program out 0) -//# -10 : ACTION is not existing -//# -11 : ACTION execution system error -//# -12 : ACTION Wrong parameters -//# -public void execute(_arguments): - argument_remote_name = "" - branch_to_checkout = "" - for elem in _arguments: - if elem.getOptionName().equals("remote": - Log.info("find remote name: '" + elem.getArg() + "'") - argument_remote_name = elem.getArg() - } else if elem.getOptionName().equals("branch": - branch_to_checkout = elem.getArg() - else: - Log.error("Wrong argument: '" + elem.getOptionName() + "' '" + elem.getArg() + "'") - - // check system is OK - Manifest.checkIsInit(); - - ConfigManifest configuration = Config.getUniqueConfig(); - - - elem = configuration.get_manifest_config() - base_display = tools.get_list_base_display(0, 0, elem) - if status.checkout_elem(elem, argument_remote_name, branch_to_checkout, base_display) == false: - return Env.ret_action_fail - - - - diff --git a/tmpsrc/actions/islandAction_manifest-status.java b/tmpsrc/actions/islandAction_manifest-status.java deleted file mode 100644 index 7d75aea..0000000 --- a/tmpsrc/actions/islandAction_manifest-status.java +++ /dev/null @@ -1,63 +0,0 @@ -//!/usr/bin/python -// -*- coding: utf-8 -*- -//# -//# @author Edouard DUPIN -//# -//# @copyright 2012, Edouard DUPIN, all right reserved -//# -//# @license MPL v2.0 (see license file) -//# - -from realog import Log -from island import tools -from island import env -from island import config -from island import multiprocess -from island import manifest -from island import commands -import status -import os - - -//# -//# @brief Get the global description of the current action -//# @return (string) the description string (fist line if reserved for the overview, all is for the specific display) -//# -public void help(): - return "Display status spécifically of the manifest" - -//# -//# @brief Add argument to the specific action -//# @param[in,out] my_args (death.Arguments) Argument manager -//# @param[in] section Name of the currect action -//# -public void add_specific_arguments(_my_args, _section): - _my_args.add("t", "tags", haveParam=false, desc="Display if the commit is on a tag (and display it)") - -//# -//# @brief Execute the action required. -//# -//# @return error value [0 .. 50] the <0 value is reserved system ==> else, what you want. -//# None : No error (return program out 0) -//# -10 : ACTION is not existing -//# -11 : ACTION execution system error -//# -12 : ACTION Wrong parameters -//# -public void execute(_arguments): - argument_remote_name = "" - argument_display_tag = false - for elem in _arguments: - if elem.getOptionName().equals("tags": - argument_display_tag = true - else: - Log.error("Wrong argument: '" + elem.getOptionName() + "' '" + elem.getArg() + "'") - - // check system is OK - Manifest.checkIsInit(); - - ConfigManifest configuration = Config.getUniqueConfig(); - elem = configuration.get_manifest_config() - base_display = tools.get_list_base_display(0, 0, elem) - ret = status.display_status(elem, argument_remote_name, argument_display_tag, 0, base_display) - if ret != None: - return Env.ret_action_need_updtate \ No newline at end of file