96 Commits

Author SHA1 Message Date
3089c34365 [RELEASE] create a fix version 2025-01-11 16:20:10 +01:00
5affb21544 [FIX] install path is wrong 2025-01-11 16:19:40 +01:00
7f574dc425 [RELEASE] create version v1.3.0 2024-07-06 10:33:45 +02:00
7413a8da19 [DEV] change dev version win .1 version and call .island/release.bash 2024-06-25 13:44:39 +02:00
d09b88c67a [DEV] add island binary 2024-05-13 22:28:55 +02:00
e6d69292ef [DEV] update version 2024-02-05 12:26:11 +01:00
f83cad03ed [DEV] correct version selection 2024-01-29 00:12:52 +01:00
15a537455c [DEV] update the project to use pyproject.toml 2024-01-28 22:20:32 +01:00
9be73c60d1 [RELEASE] version 1.1.3 2024-01-22 12:35:14 +01:00
70df1e8580 [DEV] update documentation 2024-01-22 09:06:32 +01:00
a2ab9d7074 [DEV] create new version 2023-06-01 22:57:11 +02:00
3fb2049bc3 [DEV] some clean 2023-06-01 21:15:34 +02:00
f83b79b740 [DEV] add VSC manifest support 2023-03-30 21:44:27 +02:00
908293a48d [DEV] so many upgrade 2023-03-07 22:44:26 +01:00
f05cd3fe51 [DEV] start review island 2023-03-06 21:07:52 +01:00
fa8f5ec087 [DEV] add specific remote 2019-10-03 16:06:36 +02:00
06b9a43b8b [VERSION] update dev tag version 2019-08-28 01:09:10 +02:00
37aca015fc [RELEASE] Release v1.0.0 2019-08-28 01:09:10 +02:00
77fc465524 [DEBUG] correct no update 2019-08-28 01:08:35 +02:00
c709ddc730 [DEBUG] update new delivery methode 2019-08-28 01:07:03 +02:00
4b820e9cfb [DEBUG] correct mission version filename 2019-08-28 00:39:54 +02:00
851aff50f3 [DEBUG] update status interface 2019-08-28 00:38:29 +02:00
d0183a416b [DEV] add version file 2019-08-28 00:31:29 +02:00
492743cd6a [DEV] update version model 2019-08-28 00:23:32 +02:00
e809d2c309 [DEV] update deliver mode 2019-08-27 23:46:12 +02:00
0702c24dbd [DEV] add option to specify the mode of merge 2019-08-27 23:45:54 +02:00
825667f038 [DEV] specify the mode of merge 2019-08-27 23:45:43 +02:00
04019f5b0e [DEV] select option deliver in manifest 2019-08-27 23:23:10 +02:00
f9793383c6 [DEV] manifest add deliver option 2019-08-27 23:21:48 +02:00
909637ca17 [DEBUG] correct deliver interface 2019-08-27 22:55:17 +02:00
06c671996f [DEV] add manifest access and tags 2019-08-27 22:07:02 +02:00
7e0a7fe45b [DEV] add function to clear and set tags in manifest 2019-08-27 22:03:19 +02:00
936d5d028c [DEV] externalyse actions 2019-08-27 22:02:50 +02:00
be4a10b1a1 [DEV] Add unique config concept 2019-08-27 22:01:33 +02:00
19000e72e5 [DEV] externalize repo and link config 2019-08-27 21:58:10 +02:00
cb477a4ba7 [DEV] Add return value 2019-08-27 21:56:49 +02:00
0997e377d2 [DEV] add return value from execution 2019-08-27 21:56:03 +02:00
59341b9b00 [DEV] strop the rework on generic asign 2019-08-22 22:14:33 +02:00
a9e1685d8d RELEASE] new version 0.9.0 2019-08-02 00:07:42 +02:00
2435b99328 [DEBUG] correct the command actions 2019-08-02 00:06:44 +02:00
e8c5dc4da0 [DEV] add dynamic links 2019-08-02 00:06:23 +02:00
e604008a27 [DEV] add future interface of options 2019-08-02 00:05:45 +02:00
d646aab6f6 [DEV] add volatile basic insterface 2019-08-02 00:05:26 +02:00
31f2815230 [DEBUG] remove error code 2019-08-02 00:03:56 +02:00
8c3c73f2ff [DEV] add a warning ad the end of the application when error 2019-08-02 00:00:26 +02:00
4d15e21c12 [DEBUG] correct the check of tracking branch 2019-07-31 00:15:10 +02:00
8660b5b376 [DEV] update mode to check island is init 2019-07-31 00:45:00 +02:00
bd7f732ca2 [DEV] add a volatile repository concept 2019-07-31 00:44:52 +02:00
3f51e9e35c [DEV] change the configuration file 2019-07-31 00:43:56 +02:00
78f559ec21 [DEV] update methode to clone the repository (done it in generic) 2019-07-31 00:42:52 +02:00
065b3ea6a7 [DEV] add clone commands 2019-07-31 00:42:08 +02:00
42a432a004 [DEV] update the sync-local action 2019-07-30 23:38:06 +02:00
833792cd81 [DEV] better help in the actions main file 2019-07-30 23:37:39 +02:00
8fb94175ae [DEV] add fetch manifest in the fetch action 2019-07-30 23:36:59 +02:00
375c983df6 [DEV] add command rebase 2019-07-30 23:36:16 +02:00
00b2544511 [DEV] add basic documentation in the action parts 2019-07-30 23:36:00 +02:00
3e432ffc21 [DEBUG] correct the user configuration path 2019-07-30 23:34:11 +02:00
4c50fb154d [DEV] add a path filter in the island request 2019-07-30 23:33:26 +02:00
d31e66ac73 [DEV] add sync-local 2019-07-24 22:12:42 +02:00
d5d52537bd [RELEASE] new version 0.8.0 2019-07-17 13:29:06 +02:00
459910369e [DEV] remove update of manifect when this is not needed 2019-06-25 14:03:21 +02:00
47a4209a8b [DEV] add manifect sync 2019-06-25 13:32:04 +02:00
531b793603 [DEV] update sync with external command 2019-06-25 13:31:44 +02:00
93a05a7145 [DEV] add submodule command 2019-06-25 13:31:27 +02:00
49d415f26b [DEV] add pull command 2019-06-25 13:31:13 +02:00
c357fe0f35 [DEV] add prune in fetch 2019-06-25 13:31:02 +02:00
a52d7a307b [DEBUG] remove unneeded warning inn get status 2019-06-14 12:08:40 +02:00
2a484d1ce2 [RELEASE] new version 0.7.0 2019-06-12 15:59:33 +02:00
3f49ad7fb3 [DEV] add a deliver-push methode 2019-06-12 15:58:02 +02:00
5cc7e6b16a [DEV] deliver add capability to add a repository in the vertionning system 2019-06-12 15:57:41 +02:00
ff9ed410ad [DEBUG] remove dead code 2019-06-12 15:57:09 +02:00
180f2968e7 [DEV] deliver: add possibility to not generate version for a specific repository 2019-06-12 15:56:55 +02:00
ab38c6cccb [DEBUG] remove parameters of deliver 2019-06-12 15:55:59 +02:00
4e0b7778b0 [DEBUG] correct deliver help 2019-06-12 15:55:30 +02:00
9f0584d6c3 [DEV] simplify fetch commands 2019-06-12 15:55:11 +02:00
7eb2a7d171 [DEV] update to status to use commands 2019-06-12 15:54:55 +02:00
3a907784c5 [DEV] add git get all remote tags command 2019-06-12 15:54:23 +02:00
785d8efd70 [DEV] add git get all tags command 2019-06-12 15:54:12 +02:00
1f3959499c [DEV] add git get current tags command 2019-06-12 15:53:54 +02:00
c342082394 [DEBUG] correct the git sha1 get from branch 2019-06-12 15:53:37 +02:00
aedbd09497 [DEV] add git push command 2019-06-12 15:53:10 +02:00
fe1a4ec667 [DEV] add git fetch command 2019-06-12 15:51:11 +02:00
88edb38d26 [DEV] set every git command display error arriving in the call returns 2019-06-12 15:50:41 +02:00
0593274392 [DEV] set the commonad accessing to the server updated 2019-06-12 15:48:58 +02:00
daa5c8039d [DEV] add tool to generize the wait config 2019-06-12 15:46:51 +02:00
21650b55c8 [DEV] add Wait configuration 2019-06-12 15:46:32 +02:00
fe93eb07f6 [DEBUG] correct the commands tools 2019-05-30 14:59:36 +02:00
1177261c85 [DEV] add saved local config property 2019-05-30 14:50:06 +02:00
c7ab6ff5e5 [DEV] add basic display the folder instead of the git repository name 2019-05-30 14:49:12 +02:00
cfab74dfa1 [DEV] add the deliver action (version 1) 2019-05-30 14:01:36 +02:00
bfdcf41ac4 [DEV] add display tags in the status 2019-05-30 14:01:09 +02:00
77cc304dac [DEV] update to the command actions 2019-05-30 13:59:32 +02:00
39a80ea719 [DEV] add a check to verify if action have a unknow parameter authorised 2019-05-30 13:57:35 +02:00
e1899f89d0 [DOC] correct the documentation of actions 2019-05-30 13:56:55 +02:00
e0ec2bddae [DEV] add a convertiser to transform string version in a array element 2019-05-30 13:55:45 +02:00
27936e3ac1 [DEV] add git command file to centralize the git command access 2019-05-30 13:55:05 +02:00
44 changed files with 4836 additions and 2002 deletions

16
.flake8 Normal file
View File

@@ -0,0 +1,16 @@
[flake8]
# Temporary, should be fixed and reenabled
# B006 Do not use mutable data structures for argument defaults. They are created during function definition time. All calls to the function reuse this one instance of that data structure, persisting changes between them.
# B028 'state_name' is manually surrounded by quotes, consider using the `!r` conversion flag.
# B902 blind except Exception
# Permanently disabled, because conflicting with other rules
# B950 line too long (conflicting with black)
# E203 whitespace before ':' (conflicting with black)
# E501 line too long (81 > 79 characters) (conflicting with black)
# W503 line break before binary operator: Nothing to be done on this one, we use W504 instead
ignore = B006, B028, B902, B950, E203, E501, W503, ANN101, ANN102, ANN401
max-line-length = 99
# max-complexity = 18
select = A,ANN,B,C,D,E,F,I,W,T

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@
# Setuptools distribution folder. # Setuptools distribution folder.
/dist/ /dist/
/build/ /build/
/.venv/
# Python egg metadata, regenerated from source files by setuptools. # Python egg metadata, regenerated from source files by setuptools.
/*.egg-info /*.egg-info

18
.isort.cfg Normal file
View File

@@ -0,0 +1,18 @@
# Configuration settings for isort.
[settings]
py_version=38
profile=black
line_length = 80
lines_after_imports = 2
known_firstparty=nfar_*
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
order_by_type = false
combine_as_imports = true
force_grid_wrap = 3
force_sort_within_sections = true
include_trailing_comma = true
skip = setup.py
use_parentheses = true

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"cSpell.words": ["realog"]
}

View File

@@ -1,32 +1,16 @@
Lutin Lutin
===== =====
`island` is a generic source downloader and syncronizer is a FREE software tool. `island` is a generic source downloader and synchronizer is a FREE software tool.
It is compatible with basic format of repo-git manifest. This project is created to be easyest to read with simple interface It is compatible with basic format of repo-git manifest. This project is created to be easiest to read with simple interface
(no internal git usage, but user level git usage) The main point to create the "fork" is the non-support of repo of relativity (no internal git usage, but user level git usage) The main point to create the "fork" is the non-support of repo of relativity
in submodule of git (submodule reference with ../xxx.git) This point is really important when you want to have a rellocable in submodule of git (submodule reference with ../xxx.git) This point is really important when you want to have a relocate
manifest and project with submodule. The simpl eexample is the atria-soft / generic-library / musicdsp that are availlable on manifest and project with submodule. The simpl example is the atria-soft / generic-library / musicdsp that are available on
github, gitlab, bitbucket and personal server. github, gitlab, bitbucket and personal server.
.. image:: https://badge.fury.io/py/island.png ![https://badge.fury.io/py/island.png](https://badge.fury.io/py/island.png))
:target: https://pypi.python.org/pypi/island
Release (master)
----------------
.. image:: https://travis-ci.org/HeeroYui/island.svg?branch=master
:target: https://travis-ci.org/HeeroYui/island
Developement (dev)
------------------
.. image:: https://travis-ci.org/HeeroYui/island.svg?branch=dev
:target: https://travis-ci.org/HeeroYui/island
Instructions Instructions
------------ ------------
@@ -78,7 +62,7 @@ Download and synchronize the sources:
island sync island sync
Select all branch availlable in the worktree: (checkout origin/dev in dev branch and track it, do nothing if the branch does not exist) Select all branch available in the work-tree: (checkout origin/dev in dev branch and track it, do nothing if the branch does not exist)
island checkout dev island checkout dev
@@ -86,6 +70,43 @@ Show the status of the workspace
island status island status
Develop in local (with virtual env):
====================================
see: https://setuptools.pypa.io/en/latest/userguide/development_mode.html
Create your development environment:
```bash
# Create a virtual environment
python -m venv .venv
# Activate the python virtual environment
source .venv/bin/activate
# Install the package in editable mode (dynamic use of files)
pip install --editable .
```
Run the application . ```island --help```
Manual set in production:
=========================
install generic tools for deployment
```bash
pip3 install twine
```
Create the new version:
```bash
# Clean previous packages
\rm -rf dist/
# Compile the package
python3 -m build
# Upload the package
python3 -m twine upload dist/*
```
TODO list TODO list
--------- ---------
@@ -123,4 +144,3 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.

View File

@@ -1,11 +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)
##
import island

View File

@@ -1,233 +1,8 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Inland INIT GLOBAL.
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import os
import sys
import fnmatch
import copy
# Local import
from . import host
from . import tools
from realog import debug
from . import env
from . import actions
import death.Arguments as arguments
import death.ArgElement as arg_element
is_init = False
@author Edouard DUPIN
def filter_name_and_file(root, list_files, filter): @copyright 2012, Edouard DUPIN, all right reserved
# filter elements: @license MPL v2.0 (see license file)
tmp_list = fnmatch.filter(list_files, filter)
out = []
for elem in tmp_list:
if os.path.isfile(os.path.join(root, elem)) == True:
out.append(elem);
return out;
def import_path_local(path):
out = []
debug.verbose("island files: " + str(path) + " [START]")
list_files = os.listdir(path)
# filter elements:
tmp_list_island_file = filter_name_and_file(path, list_files, env.get_system_base_name() + "*.py")
debug.verbose("island files: " + str(path) + " : " + str(tmp_list_island_file))
# Import the module:
for filename in tmp_list_island_file:
out.append(os.path.join(path, filename))
debug.verbose(" Find a file : '" + str(out[-1]) + "'")
return out
def init():
global is_init;
if is_init == True:
return
list_of_island_files = import_path_local(os.path.join(tools.get_current_path(__file__), 'actions'))
actions.init(list_of_island_files)
is_init = True
# initialize the system ...
init()
debug.verbose("List of actions: " + str(actions.get_list_of_action()))
my_args = arguments.Arguments()
my_args.add_section("option", "Can be set one time in all case")
my_args.add("h", "help", desc="Display this help")
my_args.add("v", "verbose", list=[["0","None"],["1","error"],["2","warning"],["3","info"],["4","debug"],["5","verbose"],["6","extreme_verbose"]], desc="display debug level (verbose) default =2")
my_args.add("c", "color", desc="Display message in color")
my_args.add("n", "no-fetch-manifest", haveParam=False, desc="Disable the fetch of the manifest")
my_args.set_stop_at(actions.get_list_of_action())
local_argument = my_args.parse()
##
## @brief Display the help of this makefile.
##
def usage():
color = debug.get_color_set()
# generic argument displayed :
my_args.display()
print(" Action availlable" )
list_actions = actions.get_list_of_action();
for elem in list_actions:
print(" " + color['green'] + elem + color['default'])
print(" " + actions.get_action_help(elem))
""" """
print(" " + color['green'] + "init" + color['default'])
print(" initialize a 'island' interface with a manifest in a git ")
print(" " + color['green'] + "sync" + color['default'])
print(" Syncronise the currect environement")
print(" " + color['green'] + "status" + color['default'])
print(" Dump the status of the environement")
"""
print(" ex: " + sys.argv[0] + " -c init http://github.com/atria-soft/manifest.git")
print(" ex: " + sys.argv[0] + " sync")
exit(0)
def check_boolean(value):
if value == "" \
or value == "1" \
or value == "true" \
or value == "True" \
or value == True:
return True
return False
# preparse the argument to get the verbose element for debug mode
def parseGenericArg(argument, active):
debug.extreme_verbose("parse arg : " + argument.get_option_name() + " " + argument.get_arg() + " active=" + str(active))
if argument.get_option_name() == "help":
if active == False:
usage()
return True
elif argument.get_option_name()=="jobs":
if active == True:
#multiprocess.set_core_number(int(argument.get_arg()))
pass
return True
elif argument.get_option_name()=="depth":
if active == True:
env.set_parse_depth(int(argument.get_arg()))
return True
elif argument.get_option_name() == "verbose":
if active == True:
debug.set_level(int(argument.get_arg()))
return True
elif argument.get_option_name() == "color":
if active == True:
if check_boolean(argument.get_arg()) == True:
debug.enable_color()
else:
debug.disable_color()
return True
elif argument.get_option_name() == "no-fetch-manifest":
if active == False:
env.set_fetch_manifest(False)
return True
return False
"""
# open configuration of island:
config_file_name = "islandConfig.py"
config_file = os.path.join(tools.get_run_path(), config_file_name)
if os.path.isfile(config_file) == True:
sys.path.append(os.path.dirname(config_file))
debug.debug("Find basic configuration file: '" + config_file + "'")
# the file exist, we can open it and get the initial configuration:
configuration_file = __import__(config_file_name[:-3])
if "get_exclude_path" in dir(configuration_file):
data = configuration_file.get_exclude_path()
debug.debug(" get default config 'get_exclude_path' val='" + str(data) + "'")
env.set_exclude_search_path(data)
if "get_parsing_depth" in dir(configuration_file):
data = configuration_file.get_parsing_depth()
debug.debug(" get default config 'get_parsing_depth' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("depth", str(data)), True)
if "get_default_jobs" in dir(configuration_file):
data = configuration_file.get_default_jobs()
debug.debug(" get default config 'get_default_jobs' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("jobs", str(data)), True)
if "get_default_color" in dir(configuration_file):
data = configuration_file.get_default_color()
debug.debug(" get default config 'get_default_color' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("color", str(data)), True)
if "get_default_debug_level" in dir(configuration_file):
data = configuration_file.get_default_debug_level()
debug.debug(" get default config 'get_default_debug_level' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("verbose", str(data)), True)
if "get_default_print_pretty" in dir(configuration_file):
data = configuration_file.get_default_print_pretty()
debug.debug(" get default config 'get_default_print_pretty' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("pretty", str(data)), True)
if "get_default_force_optimisation" in dir(configuration_file):
data = configuration_file.get_default_force_optimisation()
debug.debug(" get default config 'get_default_force_optimisation' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("force-optimisation", str(data)), True)
if "get_default_isolate_system" in dir(configuration_file):
data = configuration_file.get_default_isolate_system()
debug.debug(" get default config 'get_default_isolate_system' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("isolate-system", str(data)), True)
"""
# parse default unique argument:
for argument in local_argument:
parseGenericArg(argument, True)
# remove all generic arguments:
new_argument_list = []
for argument in local_argument:
if parseGenericArg(argument, False) == True:
continue
new_argument_list.append(argument)
# now the first argument is: the action:
if len(new_argument_list) == 0:
debug.warning("--------------------------------------")
debug.warning("Missing the action to do ...")
debug.warning("--------------------------------------")
usage()
# TODO : move tin in actions ...
list_actions = actions.get_list_of_action();
action_to_do = new_argument_list[0].get_arg()
new_argument_list = new_argument_list[1:]
if action_to_do not in list_actions:
debug.warning("--------------------------------------")
debug.warning("Wrong action type : '" + str(action_to_do) + "' availlable list: " + str(list_actions) )
debug.warning("--------------------------------------")
usage()
# todo : Remove this
if action_to_do != "init" \
and os.path.exists(env.get_island_path()) == False:
debug.error("Can not execute a island cmd if we have not initialize a config: '" + str("." + env.get_system_base_name()) + "' in upper 6 parent path")
exit(-1)
actions.execute(action_to_do, my_args.get_last_parsed()+1)
# stop all started threads;
#multiprocess.un_init()

View File

@@ -1,28 +1,33 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action interface.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
import os
import sys
from typing import List, Any, Optional
import death.Arguments as arguments
# Local import # Local import
from realog import debug from realog import debug
import os
import sys
from . import env from . import env
import death.Arguments as arguments
list_actions = [] list_actions = []
__base_action_name = env.get_system_base_name() + "Action_" __base_action_name = env.get_system_base_name() + "Action_"
def init(files):
global list_actions; def init(files) -> None:
debug.debug("List of action for island: ") global list_actions
debug.verbose(f"List of action for island: {len(files)}")
for elem_path in files: for elem_path in files:
debug.verbose("parse file : " + elem_path)
base_name = os.path.basename(elem_path) base_name = os.path.basename(elem_path)
if len(base_name) <= 3 + len(__base_action_name): if len(base_name) <= 3 + len(__base_action_name):
# reject it, too small # reject it, too small
@@ -33,87 +38,111 @@ def init(files):
continue continue
name_action = base_name[len(__base_action_name) :] name_action = base_name[len(__base_action_name) :]
debug.debug(" '" + os.path.basename(elem_path)[:-3] + "' file=" + elem_path) debug.debug(" '" + os.path.basename(elem_path)[:-3] + "' file=" + elem_path)
list_actions.append({ list_actions.append(
{
"name": name_action, "name": name_action,
"path": elem_path, "path": elem_path,
}) }
)
##
## @brief Get the wall list of action availlable def get_list_of_action() -> List[str]:
## @return ([string]) the list of action name """Get the wall list of action available
##
def get_list_of_action(): :return: the list of action name
global list_actions; """
global list_actions
out = [] out = []
for elem in list_actions: for elem in list_actions:
out.append(elem["name"]) out.append(elem["name"])
return out return out
##
## @brief Get a description of an action def get_function_value(action_name: str, function_name: str, default_value: Optional[Any] = None) -> Any:
## @param[in] action_name (string) Name of the action """Get a description of an action.
## @return (string/None) A descriptive string or None
## :param action_name: Name of the action
def get_desc(action_name): :param function_name: Name of the function to call
global list_actions; :param default_value: Returned value of the call if function does not exist, defaults to None
:return: the requested value or the default_value
"""
global list_actions
for elem in list_actions: for elem in list_actions:
if elem["name"] == action_name: if elem["name"] == action_name:
# finish the parsing # finish the parsing
sys.path.append(os.path.dirname(elem["path"])) sys.path.append(os.path.dirname(elem["path"]))
the_action = __import__(__base_action_name + action_name) the_action = __import__(__base_action_name + action_name)
if "get_desc" not in dir(the_action): if function_name not in dir(the_action):
return "" return default_value
return the_action.get_desc() method_to_call = getattr(the_action, function_name)
return "" return method_to_call()
return default_value
def usage(arguments, action_name): def get_action_help(action_name: str) -> str:
color = debug.get_color_set() """Get the global help value of a module.
:param action_name: Name of the action
:return: The first line of description
"""
value = get_function_value(action_name, "help", "---")
return value.split("\n")[0]
def usage(arguments, action_name) -> None:
# generic argument displayed for specific action: # generic argument displayed for specific action:
print("Specific argument for the command: '" + action_name + "'" ) # print("Specific argument for the command: '" + action_name + "'" )
print(" " + get_desc(action_name)) value = get_function_value(action_name, "help")
debug.info("Description:")
debug.info("\t" + str(value))
arguments.display(action_name) arguments.display(action_name)
value = get_function_value(action_name, "help_example")
if value is not None:
debug.info("Example:")
for elem in value.split("\n"):
debug.info("\t" + elem)
exit(0) exit(0)
def execute(action_name, argument_start_id): def execute(action_name, argument_start_id):
global list_actions; global list_actions
# TODO: Move here the check if action is availlable # TODO: Move here the check if action is available
for elem in list_actions: for elem in list_actions:
if elem["name"] != action_name: if elem["name"] != action_name:
continue continue
debug.info("action: " + str(elem)); debug.info("action: " + str(elem))
# finish the parsing # finish the parsing
sys.path.append(os.path.dirname(elem["path"])) sys.path.append(os.path.dirname(elem["path"]))
the_action = __import__(__base_action_name + action_name) the_action = __import__(__base_action_name + action_name)
my_under_args_parser = arguments.Arguments() my_under_args_parser = arguments.Arguments()
my_under_args_parser.add("h", "help", desc="Help of this action") my_under_args_parser.add("h", "help", desc="Help of this action")
if "add_specific_arguments" in dir(the_action): if "add_specific_arguments" in dir(the_action):
the_action.add_specific_arguments(my_under_args_parser, elem["name"]) the_action.add_specific_arguments(my_under_args_parser, elem["name"])
my_under_args = my_under_args_parser.parse(argument_start_id) have_unknow_argument = False
if "have_unknow_argument" in dir(the_action):
have_unknow_argument = the_action.have_unknow_argument()
my_under_args = my_under_args_parser.parse(argument_start_id, have_unknow_argument)
# search help if needed ==> permit to not duplicating code # search help if needed ==> permit to not duplicating code
for elem in my_under_args: for elem in my_under_args:
if elem.get_option_name() == "help": if elem.get_option_name() == "help":
usage(my_under_args_parser, action_name) usage(my_under_args_parser, action_name)
return False return 0
# now we can execute: # now we can execute:
if "execute" not in dir(the_action): if "execute" not in dir(the_action):
debug.error("execute is not implmented for this action ... '" + str(action_name) + "'") debug.error("execute is not implmented for this action ... '" + str(action_name) + "'")
return False return -11
debug.info("execute: " + action_name) debug.info("execute: " + action_name)
for elem in my_under_args: for elem in my_under_args:
debug.info(" " + str(elem.get_option_name()) + "='" + str(elem.get_arg()) + "'") debug.debug(" " + str(elem.get_option_name()) + "='" + str(elem.get_arg()) + "'")
return the_action.execute(my_under_args) ret = the_action.execute(my_under_args)
if ret == None:
return 0
if ret < 0:
debug.info(" ==========================")
debug.info(" == Some error occured ==")
debug.info(" ==========================")
return ret
debug.error("Can not do the action...") debug.error("Can not do the action...")
return False return -10
def get_action_help(action_name):
global list_actions;
for elem in list_actions:
if elem["name"] != action_name:
continue
sys.path.append(os.path.dirname(elem["path"]))
the_action = __import__(__base_action_name + action_name)
if "help" in dir(the_action):
return the_action.help()
return "---"

View File

@@ -1,33 +1,59 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for Checkout.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
from island import manifest
import os import os
from realog import debug
import status
def help(): from island import (
return "plop" config,
env,
manifest,
tools,
)
#
# @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)
#
def help() -> str:
return "Checkout a specific branch in all repository"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the current action
#
def add_specific_arguments(my_args, section): def add_specific_arguments(my_args, section):
my_args.add("r", "remote", haveParam=True, desc="Name of the remote server") my_args.add("r", "remote", haveParam=True, desc="Name of the remote server")
my_args.add_arg("branch", optionnal=False, desc="Branch to checkout") my_args.add_arg(
"branch",
optionnal=False,
desc="Branch to checkout (if '__TAG__' ==> checkout specific repository tags)",
)
def execute(arguments):
#
# @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
#
def execute(_arguments):
argument_remote_name = "" argument_remote_name = ""
branch_to_checkout = "" branch_to_checkout = ""
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "remote": if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'") debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg() argument_remote_name = elem.get_arg()
@@ -36,20 +62,17 @@ def execute(arguments):
else: else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.Config() configuration = config.get_unique_config()
# update the local configuration file: # update the local configuration file:
configuration.set_branch(branch_to_checkout) configuration.set_branch(branch_to_checkout)
configuration.store() configuration.store()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -57,94 +80,11 @@ def execute(arguments):
all_project = mani.get_all_configs() all_project = mani.get_all_configs()
debug.info("checkout of: " + str(len(all_project)) + " projects") debug.info("checkout of: " + str(len(all_project)) + " projects")
id_element = 0 id_element = 0
have_error = False
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.verbose("checkout : " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) if status.checkout_elem(elem, argument_remote_name, branch_to_checkout, base_display) is False:
if os.path.exists(git_repo_path) == False: have_error = True
debug.warning("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> repository does not exist ...") if have_error is True:
continue return env.ret_action_fail
# check if the repository is modify
cmd = "git diff --quiet"
debug.verbose("execute : " + cmd)
ret_diff = multiprocess.run_command(cmd, cwd=git_repo_path)
# get local branch
cmd = "git branch"
debug.verbose("execute : " + cmd)
ret_branch = multiprocess.run_command(cmd, cwd=git_repo_path)
# get tracking branch
cmd = "git rev-parse --abbrev-ref --symbolic-full-name @{u}"
debug.verbose("execute : " + cmd)
ret_track = multiprocess.run_command(cmd, cwd=git_repo_path)
is_modify = True
if ret_diff[0] == 0:
is_modify = False
if is_modify == True:
debug.warning("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> modify data can not checkout new branch")
continue
list_branch = ret_branch[1].split('\n')
list_branch2 = []
select_branch = ""
for elem_branch in list_branch:
list_branch2.append(elem_branch[2:])
if elem_branch[:2] == "* ":
select_branch = elem_branch[2:]
# check if we are on the good branch:
if branch_to_checkout == select_branch:
debug.info("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> No change already on good branch")
continue
# check if we have already checkout the branch before
debug.verbose(" check : " + branch_to_checkout + " in " + str(list_branch2))
if branch_to_checkout in list_branch2:
cmd = "git checkout " + branch_to_checkout
debug.verbose("execute : " + cmd)
ret = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret[0] != 0 \
and ret[1] != "" \
and ret != False:
debug.info("'" + str(ret) + "'")
debug.error("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> Can not checkout to the correct branch")
continue
debug.info("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> switch branch")
# TODO : Check the number of commit to the origin/XXX branch ....
continue
# Check if the remote branch exist ...
cmd = "git branch -a"
debug.verbose("execute : " + cmd)
ret_branch_all = multiprocess.run_command(cmd, cwd=git_repo_path)
list_branch_all = ret_branch_all[1].split('\n')
exist = False
for elem_branch in list_branch_all:
debug.verbose(" check : '" + elem_branch + "' == '" + " remotes/" + elem.select_remote["name"] + "/" + branch_to_checkout + "'")
if elem_branch == " remotes/" + elem.select_remote["name"] + "/" + branch_to_checkout:
exist = True
debug.info(" ==> find ...")
break
if exist == False:
debug.info("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> NO remote branch")
continue
# checkout the new branch:
cmd = "git checkout --quiet " + elem.select_remote["name"] + "/" + branch_to_checkout + " -b " + branch_to_checkout
# + " --track " + elem.select_remote["name"] + "/" + branch_to_checkout
debug.verbose("execute : " + cmd)
ret = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret[1] != "" \
and ret != False:
debug.info("'" + str(ret) + "'")
debug.error("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> Can not checkout to the correct branch")
continue
debug.info("checkout " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + " ==> create new branch")
continue

View File

@@ -1,41 +1,63 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for command.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import multiprocess
from island import config
from island import manifest
import os import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "write the command you want to be executed in every repository" return "Write the command you want to be executed in every repository"
def execute(arguments):
#
# @brief Set the option argument are not able to check if the argument are correct or not
# @return (boolean) have parameter without arguments
#
def have_unknow_argument():
return True
#
# @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
#
def execute(_arguments):
cmd = "" cmd = ""
for elem in arguments: for elem in _arguments:
debug.info("Get data element: " + str(elem.get_arg())) debug.info("Get data element: " + str(elem.get_arg()))
cmd += elem.get_arg() + " " cmd += elem.get_arg() + " "
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.Config() configuration = config.get_unique_config()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -46,11 +68,13 @@ def execute(arguments):
for elem in all_project: for elem in all_project:
debug.info("------------------------------------------") debug.info("------------------------------------------")
id_element += 1 id_element += 1
debug.info("execute command : " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("execute command : " + base_display)
tools.wait_for_server_if_needed()
# debug.debug("elem : " + str(elem)) # debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) == False: if os.path.exists(git_repo_path) is False:
debug.info("" + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + "\r\t\t\t\t\t\t\t\t\t" + " (not download)") debug.info("" + base_display + "\r\t\t\t\t\t\t\t\t\t" + " (not download)")
continue continue
debug.verbose("execute : " + cmd) debug.verbose("execute : " + cmd)
@@ -60,4 +84,3 @@ def execute(arguments):
debug.info("err=" + ret[2]) debug.info("err=" + ret[2])
else: else:
debug.info("Execution ERROR") debug.info("Execution ERROR")

View File

@@ -1,42 +1,61 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for commit.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
from island import manifest
import os import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "commit in all repository" return "Commit in all 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
#
def add_specific_arguments(my_args, section): def add_specific_arguments(my_args, section):
my_args.add("m", "message", haveParam=True, desc="Message to commit data") my_args.add("m", "message", haveParam=True, desc="Message to commit data")
my_args.add("a", "all", desc="Commit all elements") my_args.add("a", "all", desc="Commit all elements")
my_args.add("", "amend", desc="Ammend data at the previous commit") my_args.add("", "amend", desc="Ammend data at the previous commit")
def execute(arguments): #
# @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
#
def execute(_arguments):
argument_message = "" argument_message = ""
argument_amend = "" argument_amend = ""
argument_all = "" argument_all = ""
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "message": if elem.get_option_name() == "message":
debug.info("find message: '" + elem.get_arg() + "'") debug.info("find message: '" + elem.get_arg() + "'")
argument_message = " --message \"" + elem.get_arg() + "\" "; argument_message = ' --message "' + elem.get_arg() + '" '
elif elem.get_option_name() == "all": elif elem.get_option_name() == "all":
argument_all = " --all " argument_all = " --all "
elif elem.get_option_name() == "amend": elif elem.get_option_name() == "amend":
@@ -44,22 +63,13 @@ def execute(arguments):
else: else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.Config() configuration = config.get_unique_config()
if env.get_fetch_manifest() == True:
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
# update manifest
cmd = "git fetch --all"
multiprocess.run_command_direct(cmd, cwd=env.get_island_path_manifest())
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -68,16 +78,17 @@ def execute(arguments):
id_element = 0 id_element = 0
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.info("commit: " + str(id_element) + "/" + str(len(all_project)) + ": " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("commit: " + base_display)
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) == False: if os.path.exists(git_repo_path) is False:
debug.error("can not commit project that not exist") debug.error("can not commit project that not exist")
continue continue
if os.path.exists(os.path.join(git_repo_path,".git")) == False: if os.path.exists(os.path.join(git_repo_path, ".git")) is False:
# path already exist but it is not used to as a git repo ==> this is an error # path already exist but it is not used to as a git repo ==> this is an error
debug.warning("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart") debug.warning("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart")
continue; continue
# simply update the repository ... # simply update the repository ...
debug.verbose("commit in project:") debug.verbose("commit in project:")
@@ -85,4 +96,3 @@ def execute(arguments):
cmd = "git commit " + argument_amend + argument_all + argument_message cmd = "git commit " + argument_amend + argument_all + argument_message
debug.debug("execute : " + cmd) debug.debug("execute : " + cmd)
multiprocess.run_command_direct(cmd, cwd=git_repo_path) multiprocess.run_command_direct(cmd, cwd=git_repo_path)

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
"""Action script for deliver-push.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Push a delover (develop & master & tag) on the remotre server"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section):
my_args.add("r", "remote", haveParam=True, desc="Name of the remote server")
#
# @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
#
def execute(_arguments):
argument_remote_name = ""
for elem in _arguments:
if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg()
else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest)
destination_branch = mani.deliver_master
source_branch = mani.deliver_develop
all_project = mani.get_all_configs()
debug.info("fetch : " + str(len(all_project)) + " projects")
id_element = 0
for elem in all_project:
id_element += 1
# configure remote name:
if argument_remote_name == "":
argument_remote_name = elem.select_remote["name"]
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("deliver-push: " + base_display)
tools.wait_for_server_if_needed()
status.deliver_push(elem, argument_remote_name, destination_branch, source_branch, base_display)

View File

@@ -0,0 +1,196 @@
# -*- coding: utf-8 -*-
"""Action script for deliver.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Deliver the current repository (develop & master MUST be up to date and you MUST be on master)"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(_my_args, _section):
_my_args.add("f", "from", haveParam=True, desc="source branche to deliver")
_my_args.add("t", "to", haveParam=True, desc="desticantion branche of the deliver")
#
# @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
#
def execute(_arguments):
argument_from = None
argument_to = None
for elem in _arguments:
if elem.get_option_name() == "from":
debug.info("find source branch name: '" + elem.get_arg() + "'")
argument_from = elem.get_arg()
elif elem.get_option_name() == "to":
debug.info("find destination branch name: '" + elem.get_arg() + "'")
argument_to = elem.get_arg()
else:
debug.error(
"Wrong argument: '"
+ elem.get_option_name()
+ "' '"
+ elem.get_arg()
+ "'"
)
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
file_source_manifest = os.path.join(
env.get_island_path_manifest(), configuration.get_manifest_name()
)
if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest)
destination_branch = mani.deliver_master
source_branch = mani.deliver_develop
if argument_from != None:
source_branch = argument_from
if argument_to != None:
destination_branch = argument_to
all_project = mani.get_all_configs()
debug.info(
"Check if all project are on master: " + str(len(all_project)) + " projects"
)
id_element = 0
deliver_available = True
for elem in all_project:
id_element += 1
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.verbose("deliver-ckeck: " + base_display)
if (
status.deliver_check(
elem,
"origin", # TODO: argument_remote_name,
id_element,
base_display,
source_branch,
destination_branch,
)
is False
):
deliver_available = False
if deliver_available is False:
debug.error("deliver-ckeck: Correct the warning to validate the Merge")
return
debug.info("deliver-ckeck: ==> All is OK")
id_element = 0
for elem in all_project:
id_element += 1
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info(
"deliver: ========================================================================"
)
debug.info("deliver: == " + base_display)
debug.info(
"deliver: ========================================================================"
)
git_repo_path = os.path.join(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
debug.info("deliver: ==> version: " + str(version_description))
# 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,
)
debug.info("new version: " + str(new_version_description))
if new_version_description == None:
continue
# merge branch
if mani.deliver_mode == "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 = os.path.join(git_repo_path, "version.txt")
# update version file:
tools.file_write_data(
version_path_file, tools.version_to_string(new_version_description) + "\n"
)
if commands.call_island_release_script(git_repo_path):
commands.add_all(git_repo_path)
else:
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)
# add a 1 at the version (development mode is to prevent the system to min consider snapshot as official versions)
new_version_description[2] += 1
new_version_description.append("dev")
tools.file_write_data(
version_path_file, tools.version_to_string(new_version_description) + "\n"
)
if commands.call_island_release_script(git_repo_path):
commands.add_all(git_repo_path)
else:
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)

View File

@@ -1,54 +1,69 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for fetch.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
from island import manifest
import os import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "plop" return "Fecth all the repository (get all modification on the server)"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section): def add_specific_arguments(my_args, section):
my_args.add("r", "remote", haveParam=True, desc="Name of the remote server") my_args.add("r", "remote", haveParam=True, desc="Name of the remote server")
def execute(arguments):
#
# @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
#
def execute(_arguments):
argument_remote_name = "" argument_remote_name = ""
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "remote": if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'") debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg() argument_remote_name = elem.get_arg()
else: else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
debug.info("fetch manifest : '" + str(env.get_island_path_manifest()) + "'")
commands.fetch(env.get_island_path_manifest(), "origin")
configuration = config.Config() configuration = config.get_unique_config()
if env.get_fetch_manifest() == True:
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
# update manifest
cmd = "git fetch --all"
multiprocess.run_command_direct(cmd, cwd=env.get_island_path_manifest())
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -57,25 +72,24 @@ def execute(arguments):
id_element = 0 id_element = 0
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.info("fetch: " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) # configure remote name:
if argument_remote_name == "":
argument_remote_name = elem.select_remote["name"]
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("fetch: " + base_display)
tools.wait_for_server_if_needed()
# debug.debug("elem : " + str(elem)) # debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) == False: if os.path.exists(git_repo_path) is False:
debug.error("can not fetch project that not exist") debug.error("can not fetch project that not exist")
continue continue
if os.path.exists(os.path.join(git_repo_path,".git")) == False: if os.path.exists(os.path.join(git_repo_path, ".git")) is False:
# path already exist but it is not used to as a git repo ==> this is an error # path already exist but it is not used to as a git repo ==> this is an error
debug.error("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart") debug.error("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart")
# simply update the repository ... # simply update the repository ...
debug.verbose("Fetching project: ") debug.verbose("Fetching project: ")
# fetch the repository
cmd = "git fetch"
if argument_remote_name != "":
cmd += " " + argument_remote_name
else:
cmd += " " + elem.select_remote["name"]
debug.verbose("execute : " + cmd)
multiprocess.run_command_direct(cmd, cwd=git_repo_path)
commands.fetch(git_repo_path, argument_remote_name)

View File

@@ -1,37 +1,61 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for init.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
import os import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "Init a island repository (need 'fetch' after)" return "Init a island repository (need 'fetch' after)"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section): def add_specific_arguments(my_args, section):
my_args.add("b", "branch", haveParam=True, desc="Select branch to display") my_args.add("b", "branch", haveParam=True, desc="Select branch to display")
my_args.add("m", "manifest", haveParam=True, desc="Name of the manifest") my_args.add("m", "manifest", haveParam=True, desc="Name of the manifest")
def execute(arguments): #
if len(arguments) == 0: # @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
#
def execute(_arguments):
if len(_arguments) == 0:
debug.error("Missing argument to execute the current action ...") debug.error("Missing argument to execute the current action ...")
# the configuration availlable: # the configuration available:
branch = "master" branch = "master"
manifest_name = "default.xml" manifest_name = "default.xml"
address_manifest = "" address_manifest = ""
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "branch": if elem.get_option_name() == "branch":
debug.info("find branch name: '" + elem.get_arg() + "'") debug.info("find branch name: '" + elem.get_arg() + "'")
branch = elem.get_arg() branch = elem.get_arg()
@@ -50,36 +74,28 @@ def execute(arguments):
debug.info("Init with: '" + address_manifest + "' branch='" + branch + "' name of manifest='" + manifest_name + "'") debug.info("Init with: '" + address_manifest + "' branch='" + branch + "' name of manifest='" + manifest_name + "'")
# check if .XXX exist (create it if needed) # check if .XXX exist (create it if needed)
if os.path.exists(env.get_island_path()) == True \ if manifest.is_island_init() is True:
and os.path.exists(env.get_island_path_config()) == True \
and os.path.exists(env.get_island_path_manifest()) == True:
debug.error("System already init: path already exist: '" + str(env.get_island_path()) + "'") debug.error("System already init: path already exist: '" + str(env.get_island_path()) + "'")
tools.create_directory(env.get_island_path()) tools.create_directory(env.get_island_path())
# check if the git of the manifest if availlable # check if the git of the manifest if available
# create the file configuration: # create the file configuration:
conf = config.Config() conf = config.get_unique_config()
conf.set_manifest(address_manifest) conf.set_manifest(address_manifest)
conf.set_branch(branch) conf.set_branch(branch)
conf.set_manifest_name(manifest_name) conf.set_manifest_name(manifest_name)
conf.store() conf.store()
#clone the manifest repository debug.info("Clone the manifest")
cmd = "git clone " + address_manifest + " --branch " + branch + " " + env.get_island_path_manifest() ret_values = commands.clone(env.get_island_path_manifest(), address_manifest, branch_name=branch)
debug.info("clone the manifest") if ret_values is False:
ret = multiprocess.run_command_direct(cmd) debug.info("'" + str(ret_values) + "'")
if ret == "":
return True
if ret == False:
# all is good, ready to get the system work corectly
return True
debug.info("'" + ret + "'")
debug.error("Init does not work") debug.error("Init does not work")
return False return False
debug.info("Init done correctly ...")
return None

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
"""Action script for manifest-checkout.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def 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
#
def 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
#
def execute(_arguments):
argument_remote_name = ""
branch_to_checkout = ""
for elem in _arguments:
if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg()
elif elem.get_option_name() == "branch":
branch_to_checkout = elem.get_arg()
else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
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) is False:
return env.ret_action_fail

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
"""Action script for manifest-deliver-push.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Push the manifest delivery"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section):
pass
#
# @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
#
def execute(_arguments):
for elem in _arguments:
debug.error("pull Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
elem = configuration.get_manifest_config()
# Check the manifest is up to date ...
base_display = tools.get_list_base_display(0, 0, elem)
mani = manifest.Manifest(file_source_manifest)
destination_branch = mani.deliver_master
source_branch = mani.deliver_develop
status.deliver_push(elem, "origin", destination_branch, source_branch, base_display)

View File

@@ -0,0 +1,197 @@
# -*- coding: utf-8 -*-
"""Action script for manifest-deliver.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Deliver the manifest (merge develop vertion and create a branch with the specific current tags)"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section):
pass
# must be on the branch we choice to merge ...
#
# @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
#
def execute(_arguments):
argument_remote_name = ""
for elem in _arguments:
debug.error("pull Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
elem = configuration.get_manifest_config()
mani = manifest.Manifest(file_source_manifest)
destination_branch = mani.deliver_master
source_branch = mani.deliver_develop
# Check the manifest is up to date ...
base_display = tools.get_list_base_display(0, 0, elem)
debug.verbose("deliver-ckeck: " + base_display)
if (
status.deliver_check(
elem,
argument_remote_name,
0,
base_display,
source_branch,
destination_branch,
)
is False
):
debug.error("Can not deliver a MANIFEST that is not ready to merge", crash=False)
return env.ret_action_fail
all_tags = check_all_tags(mani)
if all_tags == None:
debug.error("Need the Tags are set in sub-repository", crash=False)
return env.ret_action_fail
# deliver the manifest (if Needed ...)
base_display = tools.get_list_base_display(0, 0, elem)
debug.info("manifest-deliver: ========================================================================")
debug.info("manifest-deliver: == " + base_display)
debug.info("manifest-deliver: ========================================================================")
git_repo_path = os.path.join(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:
return env.ret_action_fail
debug.info("manifest-deliver: ==> version: " + str(version_description))
# go to the dev branch
select_branch = commands.get_current_branch(git_repo_path)
# 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,
)
debug.info("new version: " + str(new_version_description))
if new_version_description == None:
return
# merge branch
commands.checkout(git_repo_path, destination_branch)
if mani.deliver_mode == "merge":
merge_force = True
else:
merge_force = False
commands.merge_branch_on_master(git_repo_path, source_branch, merge_force, branch_destination=destination_branch)
manifest.tag_manifest(file_source_manifest, all_tags)
version_path_file = os.path.join(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")
manifest.tag_clear(file_source_manifest)
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)
debug.info("manifest-deliver: ==> DONE")
def check_all_tags(mani):
all_project = mani.get_all_configs()
debug.info("Check all: " + str(len(all_project)) + " projects have a current tag ...")
id_element = 0
check_have_error = False
list_tags = []
for elem in all_project:
id_element += 1
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
if elem.volatile is True:
debug.info(base_display + "\r\t\t\t\t\t\t\t\t\t" + " (Not Managed)")
continue
tags_comment = ""
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
debug.error(
base_display + volatile + "\r\t\t\t\t\t\t\t\t\t" + " (not download)",
crash=False,
)
check_have_error = True
continue
ret_current_tags = commands.get_tags_current(git_repo_path)
debug.verbose("tags found: " + str(ret_current_tags))
if len(ret_current_tags) == 0:
list_tags.append({"name": elem.name, "tag": ""})
else:
list_tags.append({"name": elem.name, "tag": ret_current_tags[0]})
for elem_tag in ret_current_tags:
if len(tags_comment) != 0:
tags_comment += ","
tags_comment += elem_tag
if len(ret_current_tags) == 0:
debug.error(
base_display + "\r\t\t\t\t\t\t\t\t\t" + " (NO TAG DETECTED)",
crash=False,
)
check_have_error = True
continue
else:
debug.info(base_display + "\r\t\t\t\t\t\t\t\t\t" + " " + tags_comment)
if check_have_error is True:
return None
return list_tags

View File

@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
"""Action script for manifest-status.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def 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
#
def 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
#
def execute(_arguments):
argument_remote_name = ""
argument_display_tag = False
for elem in _arguments:
if elem.get_option_name() == "tags":
argument_display_tag = True
else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
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_update

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
"""Action script for manifest-sync.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Syncronize all the repository referenced"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section):
pass
#
# @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
#
def execute(_arguments):
for elem in _arguments:
debug.error("pull Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
is_modify_manifest = commands.check_repository_is_modify(env.get_island_path_manifest())
if is_modify_manifest is True:
commands.fetch(env.get_island_path_manifest(), "origin")
else:
commands.pull(env.get_island_path_manifest(), "origin")

View File

@@ -1,58 +1,67 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for push.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
from island import manifest
import os import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "Push all repository to the upper server" return "Push all repository to the upper server"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(_my_args, _section):
_my_args.add("r", "remote", haveParam=True, desc="Name of the remote server")
def add_specific_arguments(my_args, section): #
my_args.add("r", "remote", haveParam=True, desc="Name of the remote server") # @brief Execute the action required.
#
# @return error value [0 .. 50] the <0 value is reserved system ==> else, what you want.
def execute(arguments): # None : No error (return program out 0)
# -10 : ACTION is not existing
# -11 : ACTION execution system error
# -12 : ACTION Wrong parameters
#
def execute(_arguments):
argument_remote_name = "" argument_remote_name = ""
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "remote": if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'") debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg() argument_remote_name = elem.get_arg()
else: else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.get_unique_config()
configuration = config.Config()
if env.get_fetch_manifest() == True:
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
# update manifest
cmd = "git fetch --all"
multiprocess.run_command_direct(cmd, cwd=env.get_island_path_manifest())
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -61,14 +70,16 @@ def execute(arguments):
id_element = 0 id_element = 0
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.info("push: " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("push: " + base_display)
tools.wait_for_server_if_needed()
# debug.debug("elem : " + str(elem)) # debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) == False: if os.path.exists(git_repo_path) is False:
debug.error("can not push project that not exist") debug.error("can not push project that not exist")
continue continue
if os.path.exists(os.path.join(git_repo_path,".git")) == False: if os.path.exists(os.path.join(git_repo_path, ".git")) is False:
# path already exist but it is not used to as a git repo ==> this is an error # path already exist but it is not used to as a git repo ==> this is an error
debug.error("path '" + git_repo_path + "' exist but not used for a git repository. Clean it and restart") debug.error("path '" + git_repo_path + "' exist but not used for a git repository. Clean it and restart")
@@ -77,7 +88,7 @@ def execute(arguments):
cmd = "git branch -a" cmd = "git branch -a"
debug.verbose("execute : " + cmd) debug.verbose("execute : " + cmd)
ret_branch = multiprocess.run_command(cmd, cwd=git_repo_path) ret_branch = multiprocess.run_command(cmd, cwd=git_repo_path)
list_branch = ret_branch[1].split('\n') list_branch = ret_branch[1].split("\n")
list_branch2 = [] list_branch2 = []
list_branch3 = [] list_branch3 = []
select_branch = "" select_branch = ""
@@ -104,4 +115,3 @@ def execute(arguments):
cmd += " " + select_branch + ":" + select_branch cmd += " " + select_branch + ":" + select_branch
debug.info("execute : " + cmd) debug.info("execute : " + cmd)
multiprocess.run_command_direct(cmd, cwd=git_repo_path) multiprocess.run_command_direct(cmd, cwd=git_repo_path)

View File

@@ -1,144 +1,98 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for status.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import multiprocess
from island import config
from island import manifest
import os import os
from realog import debug
import status
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "plop" return "Get the status of all the repositories"
def add_specific_arguments(my_args, section): #
my_args.add("r", "remote", haveParam=True, desc="Name of the remote server") # @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(_my_args, _section):
_my_args.add("r", "remote", haveParam=True, desc="Name of the remote server")
_my_args.add(
"t",
"tags",
haveParam=False,
desc="Display if the commit is on a tag (and display it)",
)
def execute(arguments): #
# @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
#
def execute(_arguments):
argument_remote_name = "" argument_remote_name = ""
for elem in arguments: argument_display_tag = False
for elem in _arguments:
if elem.get_option_name() == "remote": if elem.get_option_name() == "remote":
debug.info("find remote name: '" + elem.get_arg() + "'") debug.info("find remote name: '" + elem.get_arg() + "'")
argument_remote_name = elem.get_arg() argument_remote_name = elem.get_arg()
elif elem.get_option_name() == "tags":
argument_display_tag = True
else: else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \ configuration = config.get_unique_config()
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.Config()
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
is_modify_manifest = commands.check_repository_is_modify(env.get_island_path_manifest())
if is_modify_manifest is True:
debug.info("!!!!!!!!!!!! MANIFEST is modify !!!!!!!!")
all_project = mani.get_all_configs() all_project = mani.get_all_configs()
debug.info("status of: " + str(len(all_project)) + " projects") debug.info("status of: " + str(len(all_project)) + " projects")
id_element = 0 id_element = 0
elem = configuration.get_manifest_config()
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
status.display_status(elem, argument_remote_name, argument_display_tag, id_element, base_display)
is_behind = False
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.verbose("status : " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
#debug.debug("elem : " + str(elem)) ret = status.display_status(elem, argument_remote_name, argument_display_tag, id_element, base_display)
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) if ret != None:
if os.path.exists(git_repo_path) == False: is_behind = True
debug.info("" + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + "\r\t\t\t\t\t\t\t\t\t" + " (not download)")
continue
# check if the repository is modify if is_behind is True:
cmd = "git diff --quiet" return env.ret_action_need_update
debug.verbose("execute : " + cmd)
ret_diff = multiprocess.run_command(cmd, cwd=git_repo_path)
# get local branch
cmd = "git branch -a"
debug.verbose("execute : " + cmd)
ret_branch = multiprocess.run_command(cmd, cwd=git_repo_path)
is_modify = True
if ret_diff[0] == 0:
is_modify = False
list_branch = ret_branch[1].split('\n')
list_branch2 = []
list_branch3 = []
select_branch = ""
for elem_branch in list_branch:
if len(elem_branch.split(" -> ")) != 1:
continue
if elem_branch[2:10] == "remotes/":
elem_branch = elem_branch[:2] + elem_branch[10:]
if elem_branch[:2] == "* ":
list_branch2.append([elem_branch[2:], True])
select_branch = elem_branch[2:]
else:
list_branch2.append([elem_branch[2:], False])
list_branch3.append(elem_branch[2:])
debug.verbose("List all branch: " + str(list_branch3))
# get tracking branch
if argument_remote_name == "":
cmd = "git rev-parse --abbrev-ref --symbolic-full-name @{u}"
debug.verbose("execute : " + cmd)
ret_track = multiprocess.run_command(cmd, cwd=git_repo_path)
else:
debug.extreme_verbose("check if exist " + argument_remote_name + "/" + select_branch + " in " + str(list_branch3))
if argument_remote_name + "/" + select_branch not in list_branch3:
debug.info("" + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + "\r\t\t\t\t\t\t\t (NO BRANCH)")
continue;
else:
ret_track = [True, argument_remote_name + "/" + select_branch]
modify_status = " "
if is_modify == True:
modify_status = " *** "
debug.verbose("select branch = '" + select_branch + "' is modify : " + str(is_modify) + " track: '" + str(ret_track[1]) + "'")
cmd = "git rev-list " + select_branch
debug.verbose("execute : " + cmd)
ret_current_branch_sha1 = multiprocess.run_command(cmd, cwd=git_repo_path)[1].split('\n')
cmd = "git rev-list " + ret_track[1]
debug.verbose("execute : " + cmd)
ret_track_branch_sha1 = multiprocess.run_command(cmd, cwd=git_repo_path)[1].split('\n')
# remove all identical sha1 ==> not needed for this
in_forward = 0
for elem_sha1 in ret_current_branch_sha1:
if elem_sha1 not in ret_track_branch_sha1:
in_forward += 1
in_behind = 0
for elem_sha1 in ret_track_branch_sha1:
if elem_sha1 not in ret_current_branch_sha1:
in_behind += 1
behind_forward_comment = ""
if in_forward != 0:
behind_forward_comment += "forward=" + str(in_forward)
if in_behind != 0:
if in_forward != 0:
behind_forward_comment += " "
behind_forward_comment += "behind=" + str(in_behind)
if behind_forward_comment != "":
behind_forward_comment = "\r\t\t\t\t\t\t\t\t\t\t\t\t[" + behind_forward_comment + "]"
#debug.info("" + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + "\r\t\t\t\t\t\t\t" + modify_status + "(" + select_branch + " -> " + ret_track[1] + " -> " + elem.select_remote["name"] + "/" + elem.branch + ")")
debug.info("" + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name) + "\r\t\t\t\t\t\t\t" + modify_status + "(" + select_branch + " -> " + ret_track[1] + ")" + behind_forward_comment)
if is_modify == True:
cmd = "git status --short"
debug.verbose("execute : " + cmd)
ret_diff = multiprocess.run_command(cmd, cwd=git_repo_path)
tmp_color_red = "\033[31m"
tmp_color_default= "\033[00m"
debug.info(tmp_color_red + ret_diff[1] + tmp_color_default)

View File

@@ -0,0 +1,177 @@
# -*- coding: utf-8 -*-
"""Action script for sync-local.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
import update_links
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Update all the branche to the trackin branch in local (no remote access)"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section):
my_args.add(
"r",
"reset",
haveParam=False,
desc="Rebase the repository instead of 'reset --hard'",
)
#
# @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)
# -5 : env.ret_manifest_is_not_existing : Manifest does not exit
# -10 : env.ret_action_is_not_existing : ACTION is not existing
# -11 : env.ret_action_executing_system_error : ACTION execution system error
# -12 : env.ret_action_wrong_parameters : ACTION Wrong parameters
# -13 : env.ret_action_partial_done : ACTION partially done
#
def execute(_arguments):
reset_instead_of_rebase = False
for elem in _arguments:
if elem.get_option_name() == "rebase":
reset_instead_of_rebase = True
debug.info("==> Request reset instead of rebase")
else:
debug.error(
"SYNC Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'",
ret_value=env.ret_action_wrong_parameters,
)
# check system is OK
manifest.check_island_is_init()
configuration = config.get_unique_config()
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
is_modify_manifest = commands.check_repository_is_modify(env.get_island_path_manifest())
if is_modify_manifest is True:
debug.warning("Manifest is modify")
else:
ret_track = commands.get_current_tracking_branch(env.get_island_path_manifest())
is_forward = commands.is_forward(env.get_island_path_manifest(), ret_track)
if is_forward is True:
# fetch the repository
debug.warning(
"sync-local: Not update ==> the MANIFEST is forward the remote branch "
+ str(commands.get_forward(env.get_island_path_manifest(), ret_track))
)
else:
debug.verbose("Check behind:")
is_behind = commands.is_behind(env.get_island_path_manifest(), ret_track)
if is_behind is False:
# fetch the repository
debug.info("sync-local: MANIFEST is up-to-date")
else:
if reset_instead_of_rebase is True:
debug.info("sync-local: MANIFEST Reset to " + ret_track)
commands.reset_hard(env.get_island_path_manifest(), ret_track)
else:
debug.info("sync-local: MANIFEST Rebase to " + ret_track)
commands.rebase(env.get_island_path_manifest(), ret_track)
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) is False:
debug.error(
"Missing manifest file : '" + str(file_source_manifest) + "'",
ret_value=env.ret_manifest_is_not_existing,
)
mani = manifest.Manifest(file_source_manifest)
all_project = mani.get_all_configs()
debug.info("synchronize : " + str(len(all_project)) + " projects")
id_element = 0
count_error = 0
for elem in all_project:
id_element += 1
base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("----------------------------------------------------------------")
debug.info("sync-local: " + base_display)
# debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
# The Repository does not exist ==> Nothing to do...
debug.warning("sync-local: ==> Not download")
count_error += 1
continue
if os.path.exists(os.path.join(git_repo_path, ".git")) is False:
# path already exist but it is not used to as a git repo ==> this is an error
debug.warning("sync-local: is already existing but not used for a git repository. Remove it and sync")
count_error += 1
continue
# simply update the repository ...
debug.verbose("Check modify:")
is_modify = commands.check_repository_is_modify(git_repo_path)
if is_modify is True:
# fetch the repository
debug.warning("sync-local: Not update ==> the repository is modified (pass through)")
count_error += 1
continue
debug.verbose("Check tracking and local branch:")
# get tracking branch
ret_track = commands.get_current_tracking_branch(git_repo_path)
select_branch = commands.get_current_branch(git_repo_path)
debug.debug("sync-local: check: " + select_branch + " ==> " + ret_track)
debug.verbose("Check forward:")
is_forward = commands.is_forward(git_repo_path, ret_track)
if is_forward is True:
# fetch the repository
debug.warning(
"sync-local: Not update ==> the repository is forward the remote branch " + str(commands.get_forward(git_repo_path, ret_track))
)
count_error += 1
continue
debug.verbose("Check behind:")
is_behind = commands.is_behind(git_repo_path, ret_track)
if is_behind is False:
# fetch the repository
debug.info("sync-local: Nothing to do.")
continue
if reset_instead_of_rebase is True:
debug.info("sync-local: Reset to " + ret_track)
commands.reset_hard(git_repo_path, ret_track)
else:
debug.info("sync-local: Reset to " + ret_track)
commands.rebase(git_repo_path, ret_track)
if count_error != 0:
debug.info(" ***********************************************************")
debug.info(" ** local sync partial warning on " + str(count_error) + " repository")
debug.info(" ***********************************************************")
return env.ret_action_partial_done
# Update the links:
have_error = update_links.update(configuration, mani, "sync-local")
if have_error is True:
return -1
return None

View File

@@ -1,54 +1,90 @@
#!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Action script for sync.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
from realog import debug
from island import tools
from island import env
from island import config
from island import multiprocess
from island import manifest
import os import os
from realog import debug
import update_links
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help(): def help():
return "plop" return "Syncronize all the repository referenced"
#
# @brief at the end of the help wa have the example section
# @return (string) the Example description string
#
def help_example():
return "island init https://git.heeroyui.org/atria-tools/island.git"
#
# @brief Add argument to the specific action
# @param[in,out] my_args (death.Arguments) Argument manager
# @param[in] section Name of the currect action
#
def add_specific_arguments(my_args, section): def add_specific_arguments(my_args, section):
my_args.add("d", "download", haveParam=False, desc="Just download not download repository") my_args.add(
"d",
"download",
haveParam=False,
desc="Just download the 'not download' repository",
)
def execute(arguments):
#
# @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
#
def execute(_arguments):
just_download = False just_download = False
for elem in arguments: for elem in _arguments:
if elem.get_option_name() == "download": if elem.get_option_name() == "download":
just_download = True just_download = True
debug.info("find remote name: '" + elem.get_arg() + "'") debug.info("find remote name: '" + elem.get_arg() + "'")
else: else:
debug.error("SYNC Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'") debug.error("SYNC Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check if .XXX exist (create it if needed) # check system is OK
if os.path.exists(env.get_island_path()) == False \ manifest.check_island_is_init()
or os.path.exists(env.get_island_path_config()) == False \
or os.path.exists(env.get_island_path_manifest()) == False:
debug.error("System already init have an error: missing data: '" + str(env.get_island_path()) + "'")
configuration = config.get_unique_config()
configuration = config.Config() # TODO: Load Old manifect to check diff ...
debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'") debug.info("update manifest : '" + str(env.get_island_path_manifest()) + "'")
# update manifest is_modify_manifest = commands.check_repository_is_modify(env.get_island_path_manifest())
cmd = "git fetch --all" if is_modify_manifest is True:
multiprocess.run_command_direct(cmd, cwd=env.get_island_path_manifest()) commands.fetch(env.get_island_path_manifest(), "origin")
else:
commands.pull(env.get_island_path_manifest(), "origin")
file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name()) file_source_manifest = os.path.join(env.get_island_path_manifest(), configuration.get_manifest_name())
if os.path.exists(file_source_manifest) == False: if os.path.exists(file_source_manifest) is False:
debug.error("Missing manifest file : '" + str(file_source_manifest) + "'") debug.error("Missing manifest file : '" + str(file_source_manifest) + "'")
mani = manifest.Manifest(file_source_manifest) mani = manifest.Manifest(file_source_manifest)
@@ -58,25 +94,32 @@ def execute(arguments):
id_element = 0 id_element = 0
for elem in all_project: for elem in all_project:
id_element += 1 id_element += 1
debug.info("sync : " + str(id_element) + "/" + str(len(all_project)) + " : " + str(elem.name)) base_display = tools.get_list_base_display(id_element, len(all_project), elem)
debug.info("sync : " + base_display)
tools.wait_for_server_if_needed()
# debug.debug("elem : " + str(elem)) # debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path) git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) == False: if elem.tag != None:
debug.warning("Need to select a specific tag version ... " + elem.tag)
if os.path.exists(git_repo_path) is False:
# this is a new clone ==> this is easy ... # this is a new clone ==> this is easy ...
# clone the manifest repository # clone the manifest repository
address_manifest = "" address_manifest = ""
### example git@git.plouf.com:basic_folder # example git@git.plouf.com:basic_folder
cmd = "git clone " + elem.select_remote["fetch"] address_manifest = elem.select_remote["fetch"]
if elem.select_remote["fetch"][0:4] == "git@" \ if elem.select_remote["fetch"][0:4] == "git@" and len(elem.select_remote["fetch"][4:].split(":")) <= 1:
and len(elem.select_remote["fetch"][4:].split(":")) <= 1: address_manifest += ":"
cmd += ":"
else: else:
cmd += "/" address_manifest += "/"
cmd += elem.name + " --branch " + elem.branch + " --origin " + elem.select_remote["name"] + " " + git_repo_path address_manifest += elem.name
debug.info("clone the repo") debug.info("clone the repo")
ret = multiprocess.run_command_direct(cmd) ret = commands.clone(
if ret != "" \ git_repo_path,
and ret != False: address_manifest,
branch_name=elem.branch,
origin=elem.select_remote["name"],
)
if ret[0] != "" and ret[0] != False:
# all is good, ready to get the system work corectly # all is good, ready to get the system work corectly
debug.info("'" + str(ret) + "'") debug.info("'" + str(ret) + "'")
debug.error("Clone repository does not work ... ") debug.error("Clone repository does not work ... ")
@@ -91,8 +134,7 @@ def execute(arguments):
cmd += "/" cmd += "/"
cmd += elem.name cmd += elem.name
ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path) ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path)
if ret != "" \ if ret != "" and ret != False:
and ret != False:
# all is good, ready to get the system work corectly # all is good, ready to get the system work corectly
debug.info("'" + str(ret) + "'") debug.info("'" + str(ret) + "'")
debug.warning("Can not add global mirror ... ") debug.warning("Can not add global mirror ... ")
@@ -100,13 +142,11 @@ def execute(arguments):
debug.verbose("Add global mirror: " + str(mirror) + " (done)") debug.verbose("Add global mirror: " + str(mirror) + " (done)")
# debug.info("plop " + str(elem.select_remote.keys())) # debug.info("plop " + str(elem.select_remote.keys()))
# check submodule if requested: # check submodule if requested:
if elem.select_remote["sync"] == True \ if elem.select_remote["sync"] is True and os.path.exists(os.path.join(git_repo_path, ".gitmodules")) is True:
and os.path.exists(os.path.join(git_repo_path, ".gitmodules")) == True:
debug.info(" ==> update submodule") debug.info(" ==> update submodule")
cmd = "git submodule init" cmd = "git submodule init"
ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path) ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path)
if ret != "" \ if ret != "" and ret != False:
and ret != False:
# all is good, ready to get the system work corectly # all is good, ready to get the system work corectly
debug.info("'" + str(ret) + "'") debug.info("'" + str(ret) + "'")
debug.error("Can not init submodules ... ") debug.error("Can not init submodules ... ")
@@ -116,115 +156,44 @@ def execute(arguments):
if ret[:16] == "Submodule path '": if ret[:16] == "Submodule path '":
# all is good ... # all is good ...
debug.info(" " + ret) debug.info(" " + ret)
elif ret != "" \ elif ret != "" and ret != False:
and ret != False:
# all is good, ready to get the system work corectly # all is good, ready to get the system work corectly
debug.info("'" + str(ret) + "'") debug.info("'" + str(ret) + "'")
debug.error("Can not init submodules ... ") debug.error("Can not init submodules ... ")
continue continue
continue continue
if just_download == True: if just_download is True:
debug.info("SYNC: Already downloaded") debug.info("SYNC: Already downloaded")
continue continue
if os.path.exists(os.path.join(git_repo_path,".git")) == False: if os.path.exists(os.path.join(git_repo_path, ".git")) is False:
# path already exist but it is not used to as a git repo ==> this is an error # path already exist but it is not used to as a git repo ==> this is an error
debug.error("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart") debug.error("path '" + git_repo_path + "' is already existing but not used for a git repository. Clean it and restart")
# simply update the repository ... # simply update the repository ...
debug.verbose("Fetching project: ") debug.verbose("Fetching project: ")
# fetch the repository
cmd = "git fetch " + elem.select_remote["name"]
debug.verbose("execute : " + cmd)
multiprocess.run_command_direct(cmd, cwd=git_repo_path)
# check if the repository is modify
cmd = "git diff --quiet"
debug.verbose("execute : " + cmd)
ret_diff = multiprocess.run_command(cmd, cwd=git_repo_path)
# get local branch
cmd = "git branch"
debug.verbose("execute : " + cmd)
ret_branch = multiprocess.run_command(cmd, cwd=git_repo_path)
# get tracking branch # get tracking branch
cmd = "git rev-parse --abbrev-ref --symbolic-full-name @{u}" ret_track = commands.get_current_tracking_branch(git_repo_path)
debug.verbose("execute : " + cmd) is_modify = commands.check_repository_is_modify(git_repo_path)
ret_track = multiprocess.run_command(cmd, cwd=git_repo_path) select_branch = commands.get_current_branch(git_repo_path)
is_modify = True if is_modify is True:
if ret_diff[0] == 0: # fetch the repository
is_modify = False commands.fetch(git_repo_path, elem.select_remote["name"])
debug.warning("[" + elem.name + "] Not update ==> the repository is modified (just fetch)")
list_branch = ret_branch[1].split('\n')
list_branch2 = []
select_branch = ""
for elem_branch in list_branch:
if elem_branch[:2] == "* ":
list_branch2.append([elem_branch[2:], True])
select_branch = elem_branch[2:]
else:
list_branch2.append([elem_branch[2:], False])
if is_modify == True:
debug.warning("[" + elem.name + "] Not update ==> the repository is modified")
continue continue
""" # TODO: this does not work ... commands.pull(git_repo_path, elem.select_remote["name"])
if ret_track[1] != elem.select_remote["name"] + "/" + elem.branch:
debug.warning("[" + elem.name + "] Not update ==> the current branch does not track the correct branch : track '" + ret_track[1] + "' instead of '" + elem.select_remote["name"] + "/" + elem.branch + "'")
continue
"""
cmd = "git pull"
debug.verbose("execute : " + cmd)
ret_pull = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret_pull[0] == 0:
if ret_pull[1] == "Already up-to-date.":
pass
elif ret_pull[1] != "":
debug.info(ret_pull[1])
else:
if ret_pull[1] != "":
debug.warning("ERROR GIT: " + ret_pull[1])
else:
debug.warning("ERROR GIT: in pull")
debug.verbose("select branch = '" + select_branch + "' is modify : " + str(is_modify) + " track: '" + str(ret_track[1]) + "'") debug.verbose("select branch = '" + select_branch + "' track: '" + str(ret_track) + "'")
# check submodule if requested: # check submodule if requested:
if elem.select_remote["sync"] == True \ if elem.select_remote["sync"] is True and os.path.exists(os.path.join(git_repo_path, ".gitmodules")) is True:
and os.path.exists(os.path.join(git_repo_path, ".gitmodules")) == True:
debug.info(" ==> sync submodule") debug.info(" ==> sync submodule")
cmd = "git submodule sync" commands.submodule_sync(git_repo_path, elem.select_remote["name"])
ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path)
if ret[:31] == "Synchronizing submodule url for": # Update the links:
#all is good ... have_error = update_links.update(configuration, mani, "sync-local")
debug.info(" " + ret) if have_error is True:
elif ret != "" \ return -1
and ret != False: return None
# all is good, ready to get the system work corectly
debug.info("'" + ret + "'")
debug.error("Can not sync submodules ... ")
continue
"""
cmd = "git submodule init"
ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path)
if ret != "" \
and ret != False:
# all is good, ready to get the system work corectly
debug.info("'" + ret + "'")
debug.error("Can not init submodules ... ")
continue
cmd = "git submodule update"
ret = multiprocess.run_command_direct(cmd, cwd=git_repo_path)
if ret[:16] == "Submodule path '":
#all is good ...
debug.info(" " + ret)
elif ret != "" \
and ret != False:
# all is good, ready to get the system work corectly
debug.info("'" + ret + "'")
debug.error("Can not init submodules ... ")
continue
"""

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
"""Action script for volatile-add.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help():
return "Add a 'volatile' repository with a local path (this element is update as an element in the manifest but is not managed by 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
#
def add_specific_arguments(my_args, section):
my_args.add_arg("git repository", optionnal=False, desc="Git repositoty to download")
my_args.add_arg("path", optionnal=False, desc="Path to install the new git repository")
#
# @brief at the end of the help wa have the example section
# @return (string) the Example description string
#
def help_example():
return "island volatile-add https://git.heeroyui.org/atria-tools/island.git git"
#
# @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)
# -5 : env.ret_manifest_is_not_existing : Manifest does not exit
# -10 : env.ret_action_is_not_existing : ACTION is not existing
# -11 : env.ret_action_executing_system_error : ACTION execution system error
# -12 : env.ret_action_wrong_parameters : ACTION Wrong parameters
# -13 : env.ret_action_partial_done : ACTION partially done
#
def execute(_arguments):
if len(_arguments) == 0:
debug.error("Missing argument to execute the current action [git repository] [path]")
# the configuration available:
path = ""
address_git = ""
for elem in _arguments:
if elem.get_option_name() == "git repository":
address_git = elem.get_arg()
elif elem.get_option_name() == "path":
path = elem.get_arg()
else:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
if address_git == "":
debug.error(
"volatile-add: Missing git repository address",
env.ret_action_wrong_parameters,
)
debug.info("Add 'volatile' repository: '" + address_git + "' path='" + path + "'")
# check system is OK
manifest.check_island_is_init()
# Update the current configuration:
conf = config.get_unique_config()
# TODO: Check if the local path does not exist in the manifest
if False == conf.add_volatile(address_git, path):
return env.ret_action_executing_system_error
conf.store()
return None

View File

@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
"""Action script for volatile-list.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
#
# @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)
#
def help() -> str:
return "List all the volatile repository"
#
# @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)
# -5 : env.ret_manifest_is_not_existing : Manifest does not exit
# -10 : env.ret_action_is_not_existing : ACTION is not existing
# -11 : env.ret_action_executing_system_error : ACTION execution system error
# -12 : env.ret_action_wrong_parameters : ACTION Wrong parameters
# -13 : env.ret_action_partial_done : ACTION partially done
#
def execute(_arguments):
for elem in _arguments:
debug.error("Wrong argument: '" + elem.get_option_name() + "' '" + elem.get_arg() + "'")
# check system is OK
manifest.check_island_is_init()
conf = config.get_unique_config()
volatiles = conf.get_volatile()
debug.info("List of all volatiles repository: ")
for elem in volatiles:
debug.info("\t" + elem["path"] + "\r\t\t\t\t" + elem["git_address"])
return None

462
island/actions/status.py Normal file
View File

@@ -0,0 +1,462 @@
# -*- coding: utf-8 -*-
"""Status interface display.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
from island import (
commands,
config,
env,
manifest,
multiprocess,
tools,
)
default_behind_message = "[DEV] update dev tag version"
default_update_message = "[VERSION] update dev tag version"
base_name_of_a_tagged_branch = "branch_on_tag_"
def display_status(elem, argument_remote_name, argument_display_tag, id_element, base_display):
volatile = ""
if elem.volatile is True:
volatile = " (volatile)"
debug.verbose("status : " + base_display)
# debug.debug("elem : " + str(elem))
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
debug.info(base_display + volatile + "\r\t\t\t\t\t\t\t\t\t" + " (not download)")
return
is_modify = commands.check_repository_is_modify(git_repo_path)
list_branch = commands.get_list_branch_all(git_repo_path)
select_branch = commands.get_current_branch(git_repo_path)
debug.verbose("List all branch: " + str(list_branch))
if select_branch[: len(base_name_of_a_tagged_branch)] != base_name_of_a_tagged_branch:
# get tracking branch
tracking_remote_branch = commands.get_tracking_branch(git_repo_path, argument_remote_name, select_branch)
if tracking_remote_branch == None:
debug.info(base_display + volatile + "\r\t\t\t\t\t\t\t (NO BRANCH)")
return
else:
tracking_remote_branch = select_branch[len(base_name_of_a_tagged_branch) :]
modify_status = " "
if is_modify is True:
modify_status = " *** "
debug.verbose("select branch = '" + select_branch + "' is modify : " + str(is_modify) + " track: '" + str(tracking_remote_branch) + "'")
ret_current_branch_sha1 = commands.get_revision_list_to_branch(git_repo_path, select_branch)
ret_track_branch_sha1 = commands.get_revision_list_to_branch(git_repo_path, tracking_remote_branch)
# remove all identical sha1 ==> not needed for this
in_forward = 0
for elem_sha1 in ret_current_branch_sha1:
if elem_sha1 not in ret_track_branch_sha1:
in_forward += 1
in_behind = 0
for elem_sha1 in ret_track_branch_sha1:
if elem_sha1 not in ret_current_branch_sha1:
in_behind += 1
behind_forward_comment = ""
if in_forward != 0:
behind_forward_comment += "forward=" + str(in_forward)
if in_behind != 0:
if in_forward != 0:
behind_forward_comment += " "
behind_forward_comment += "behind=" + str(in_behind)
if behind_forward_comment != "":
behind_forward_comment = "\r\t\t\t\t\t\t\t\t\t\t\t\t[" + behind_forward_comment + "]"
tags_comment = ""
# check the current tags of the repository
if argument_display_tag is True:
ret_current_tags = commands.get_tags_current(git_repo_path)
debug.verbose("tags found: " + str(ret_current_tags))
for elem_tag in ret_current_tags:
if len(tags_comment) != 0:
tags_comment += ","
tags_comment += elem_tag
if len(tags_comment) != 0:
tags_comment = "\r\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[" + tags_comment + "]"
else:
tags_comment = "\r\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t- - - - -"
debug.info(
base_display
+ volatile
+ "\r\t\t\t\t\t\t\t"
+ modify_status
+ "("
+ select_branch
+ " -> "
+ tracking_remote_branch
+ ")"
+ behind_forward_comment
+ tags_comment
)
if is_modify is True:
cmd = "git status --short"
debug.verbose("execute : " + cmd)
ret_diff = multiprocess.run_command(cmd, cwd=git_repo_path)
tmp_color_red = "\033[31m"
tmp_color_default = "\033[00m"
debug.info(tmp_color_red + ret_diff[1] + tmp_color_default)
return in_behind
def deliver_check(
elem,
argument_remote_name,
id_element,
base_display,
source_branch,
destination_branch,
):
deliver_available = True
debug.debug("deliver-ckeck: " + base_display)
debug.debug(" ==> check repo exist")
# Check the repo exist
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST be download")
return False
debug.debug(" ==> check is modify")
# check if the curent repo is modify
is_modify = commands.check_repository_is_modify(git_repo_path)
if is_modify is True:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST not be modify")
return False
debug.debug(" ==> check current branch is '" + source_branch + "'")
# check if we are on source_branch
select_branch = commands.get_current_branch(git_repo_path)
if select_branch != source_branch:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST be on source branch: '" + source_branch + "' and is: '" + select_branch + "'")
return False
debug.debug(" ==> check have tracking branch")
# check if we have a remote traking branch
tracking_remote_branch = commands.get_tracking_branch(git_repo_path, argument_remote_name, select_branch)
if tracking_remote_branch == None:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST have a remote tracking branch")
deliver_available = False
# go on destination branch
commands.checkout(git_repo_path, destination_branch)
# TODO: check return value
debug.debug(" ==> check current branch is '" + source_branch + "'")
# check if we are on "master"
select_branch = commands.get_current_branch(git_repo_path)
if select_branch != destination_branch:
debug.warning("deliver-ckeck: " + base_display + " ==> Can not checkout branch: '" + destination_branch + "' and is: '" + select_branch + "'")
deliver_available = False
debug.debug(" ==> check have tracking branch")
# check if we have a remote traking branch
tracking_remote_branch = commands.get_tracking_branch(git_repo_path, argument_remote_name, select_branch)
if tracking_remote_branch == None:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST have a remote tracking branch")
deliver_available = False
"""
# check if we have a local branch
list_branch_local = commands.get_list_branch_local(git_repo_path)
if destination_branch not in list_branch_local:
debug.warning("deliver-ckeck: " + base_display + " ==> MUST have local branch named '" + destination_branch + "'")
deliver_available = False
# TODO: check source_branch is up to date
# TODO: check the remote branch and the local branch are the same
#sha_tracking = get_sha1_for_branch(git_repo_path, tracking_remote_branch)
#sha_current = get_sha1_for_branch(git_repo_path, select_branch)
"""
# check out back the source branch
commands.checkout(git_repo_path, source_branch)
return deliver_available
def checkout_elem(elem, argument_remote_name, branch_to_checkout, base_display):
debug.verbose("checkout : " + base_display)
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
debug.warning("checkout " + base_display + " ==> repository does not exist ...")
return False
# check if the repository is modify
is_modify = commands.check_repository_is_modify(git_repo_path)
if is_modify is True:
debug.warning("checkout " + base_display + " ==> modify data can not checkout new branch")
return False
list_branch_local = commands.get_list_branch_local(git_repo_path)
select_branch = commands.get_current_branch(git_repo_path)
is_tag = False
if branch_to_checkout == "__TAG__":
branch_to_checkout = base_name_of_a_tagged_branch + str(elem.tag)
is_tag = True
if elem.volatile is True:
debug.info("checkout " + base_display + " ==> Can not checkout for 'volatile' repository")
return True
if elem.tag == None:
debug.info("checkout " + base_display + " ==> Can not checkout for '''None''' Tag")
return True
# check if we are on the good branch:
if branch_to_checkout == select_branch:
debug.info("checkout " + base_display + " ==> No change already on good branch")
return True
# check if we have already checkout the branch before
debug.verbose(" check : " + branch_to_checkout + " in " + str(list_branch_local))
if branch_to_checkout in list_branch_local:
cmd = "git checkout " + branch_to_checkout
debug.verbose("execute : " + cmd)
ret = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret[0] != 0 and ret[1] != "" and ret != False:
debug.info("'" + str(ret) + "'")
debug.error("checkout " + base_display + " ==> Can not checkout to the correct branch")
return False
debug.info("checkout " + base_display + " ==> switch branch")
# TODO : Check the number of commit to the origin/XXX branch ....
return True
list_tags = commands.get_tags(git_repo_path)
if branch_to_checkout in list_tags:
is_tag = True
if elem.tag == None:
elem.tag = branch_to_checkout
branch_to_checkout = base_name_of_a_tagged_branch + str(elem.tag)
# Check if the remote branch exist ...
if is_tag is False:
list_branch_remote = commands.get_list_branch_remote(git_repo_path)
if elem.select_remote["name"] + "/" + branch_to_checkout in list_branch_remote:
debug.info(" ==> find ...")
else:
debug.info("checkout " + base_display + " ==> NO remote branch")
return True
# checkout the new branch:
cmd = "git checkout --quiet " + elem.select_remote["name"] + "/" + branch_to_checkout + " -b " + branch_to_checkout
# + " --track " + elem.select_remote["name"] + "/" + branch_to_checkout
debug.verbose("execute : " + cmd)
ret = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret[1] != "" and ret != False:
debug.info("'" + str(ret) + "'")
debug.error("checkout " + base_display + " ==> Can not checkout to the correct branch")
return False
debug.info("checkout " + base_display + " ==> create new branch")
return True
# Checkout a specific tags:
if elem.tag in list_tags:
debug.info(" ==> find ...")
else:
debug.info("checkout " + base_display + " ==> NO remote tags")
return True
# checkout the new branch:
cmd = "git checkout --quiet " + elem.tag + " -b " + branch_to_checkout
# + " --track " + elem.select_remote["name"] + "/" + branch_to_checkout
debug.verbose("execute : " + cmd)
ret = multiprocess.run_command(cmd, cwd=git_repo_path)
if ret[1] != "" and ret != False:
debug.info("'" + str(ret) + "'")
debug.error("checkout " + base_display + " ==> Can not checkout to the correct tags")
return False
debug.info("checkout " + base_display + " ==> create new branch: " + branch_to_checkout)
return True
def get_current_version_repo(git_repo_path):
version_path_file = os.path.join(git_repo_path, "version.txt")
add_in_version_management = False
version_description = None
if os.path.exists(version_path_file) is False:
debug.info("deliver: ==> No 'version.txt' file ==> not manage release version....")
# Action to do:
valid = False
while valid is False:
debug.info("Create a new version: (0.0.0)")
debug.info(" (1) Add in managing version")
debug.info(" (2) Do NOTHING & continue")
input1 = input()
if input1 in ["1", "2"]:
valid = True
else:
debug.info("!!! Must select in range " + str(["1", "2"]))
if input1 == "1":
version_description = [0, 0, 0]
add_in_version_management = True
elif input1 == "2":
debug.info("Continue Not managing for this repository")
return (None, None)
else:
debug.warning("An error occured for this repository")
return (None, None)
else:
version_description = tools.version_string_to_list(tools.file_read_data(version_path_file))
return (version_description, add_in_version_management)
def create_new_version_repo(
git_repo_path,
version_description,
add_in_version_management,
source_branch,
destination_branch,
):
# get tracking branch
ret_destination_branch_sha1 = commands.get_revision_list_to_branch(git_repo_path, destination_branch)
ret_source_branch_sha1 = commands.get_revision_list_to_branch(git_repo_path, source_branch)
# remove all identical sha1 ==> not needed for this
have_forward = False
for elem_sha1 in ret_destination_branch_sha1:
if elem_sha1 not in ret_source_branch_sha1:
message = commands.get_specific_commit_message(git_repo_path, elem_sha1)
debug.warning("deliver: Forward commit: '" + message + "'")
have_forward = True
if have_forward is True:
debug.error("'" + destination_branch + "' branch must not be forward '" + source_branch + "' branch")
return None
behind_message = ""
behind_count = 0
for elem_sha1 in ret_source_branch_sha1:
if elem_sha1 not in ret_destination_branch_sha1:
message = commands.get_specific_commit_message(git_repo_path, elem_sha1)
behind_count += 1
behind_message = message
if behind_count == 0 and add_in_version_management is False:
debug.info("deliver: ==> Nothing to do (1).")
return None
if behind_count == 1 and (behind_message == default_behind_message or behind_message == default_update_message):
debug.info("deliver: ==> Nothing to do (2).")
return None
for elem_sha1 in ret_source_branch_sha1:
if elem_sha1 not in ret_destination_branch_sha1:
message = commands.get_specific_commit_message(git_repo_path, elem_sha1)
debug.info("deliver: Behind commit: '" + message + "'")
# Choice of the new version:
valid = False
while valid is False:
debug.info("update version: curent: " + str(version_description))
debug.info(" (1) Major version (change API)")
debug.info(" (2) Medium version (add feature)")
debug.info(" (3) Minor version (Bug fix & doc)")
debug.info(" (4) Do not release & continue")
input1 = input()
if input1 in ["1", "2", "3", "4"]:
valid = True
else:
debug.info("!!! Must select in range " + str(["1", "2", "3", "4"]))
# limit and force at 3 the nuber of variables
version_description_tmp = version_description
version_description = []
if len(version_description_tmp) >= 1:
version_description.append(version_description_tmp[0])
else:
version_description.append(0)
if len(version_description_tmp) >= 2:
version_description.append(version_description_tmp[1])
else:
version_description.append(0)
if len(version_description_tmp) >= 3:
version_description.append(version_description_tmp[2])
else:
version_description.append(0)
debug.info("update version: curent: " + str(version_description))
# increment the version
if input1 == "1":
version_description[0] += 1
version_description[1] = 0
version_description[2] = 0
elif input1 == "2":
version_description[1] += 1
version_description[2] = 0
elif input1 == "3":
version_description[2] += 1
elif input1 == "4":
debug.info("No release for this repository")
return None
else:
debug.warning("An error occured for this repository")
return None
debug.info("update version: curent: " + str(version_description))
return version_description
def deliver_push(elem, argument_remote_name, destination_branch, source_branch, base_display):
# Check the repo exist
git_repo_path = os.path.join(env.get_island_root_path(), elem.path)
if os.path.exists(git_repo_path) is False:
debug.warning("deliver-push: " + base_display + " ==> MUST be download")
return
# check if we are on destination_branch
select_branch = commands.get_current_branch(git_repo_path)
if select_branch != destination_branch:
debug.warning("deliver-push: " + base_display + " ==> MUST be on '" + destination_branch + "'")
return
# check if we have a local branch
list_branch_local = commands.get_list_branch_local(git_repo_path)
if source_branch not in list_branch_local:
debug.warning("deliver-push: " + base_display + " ==> No '" + source_branch + "' (not managed)")
return
if destination_branch not in list_branch_local:
debug.warning("deliver-push: " + base_display + " ==> No '" + destination_branch + "' (not managed)")
return
list_of_element_to_push = []
# check sha1 of destination_branch
sha_1_destination = commands.get_sha1_for_branch(git_repo_path, destination_branch)
tracking_remote_branch = commands.get_tracking_branch(git_repo_path, argument_remote_name, destination_branch)
if tracking_remote_branch == None:
debug.warning("deliver-push: " + base_display + " ==> '" + destination_branch + "' have no tracking branch")
deliver_available = False
sha_1_destination_tracking = commands.get_sha1_for_branch(git_repo_path, tracking_remote_branch)
if sha_1_destination == sha_1_destination_tracking:
debug.info("deliver-push: " + base_display + " ==> '" + destination_branch + "' && '" + tracking_remote_branch + "' have the same sha1")
else:
list_of_element_to_push.append(destination_branch)
# check sha1 of source_branch
sha_1_source = commands.get_sha1_for_branch(git_repo_path, source_branch)
tracking_remote_branch = commands.get_tracking_branch(git_repo_path, argument_remote_name, source_branch)
if tracking_remote_branch == None:
debug.info("deliver-push: " + base_display + " ==> '" + source_branch + "' have no tracking branch")
deliver_available = False
sha_1_source_tracking = commands.get_sha1_for_branch(git_repo_path, tracking_remote_branch)
if sha_1_source == sha_1_source_tracking:
debug.info("deliver-push: " + base_display + " ==> '" + source_branch + "' && '" + tracking_remote_branch + "' have the same sha1")
else:
list_of_element_to_push.append(source_branch)
ret_current_tags = commands.get_tags_current(git_repo_path)
if len(ret_current_tags) == 0:
debug.info("deliver-push: " + base_display + " ==> No tag on the current '" + destination_branch + "'")
return
if len(ret_current_tags) > 1:
debug.info(
"deliver-push: "
+ base_display
+ " ==> Too mush tags on the current '"
+ destination_branch
+ "' : "
+ str(ret_current_tags)
+ " ==> only support 1"
)
return
list_remote_tags = commands.get_tags_remote(git_repo_path, argument_remote_name)
debug.verbose("remote tags: " + str(list_remote_tags))
if ret_current_tags[0] not in list_remote_tags:
debug.info("deliver-push: " + base_display + " ==> tag already exist.")
list_of_element_to_push.append(ret_current_tags[0])
if len(list_of_element_to_push) == 0:
debug.info("deliver-push: " + base_display + " ==> Everything up-to-date")
return
debug.info("deliver-push: " + base_display + " ==> element to push:" + str(list_of_element_to_push))
# push all on the server:
commands.push(git_repo_path, argument_remote_name, list_of_element_to_push)

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""Update tools.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import os
from realog import debug
from island import env, tools
# Update the links:
def update(configuration, mani, type_call):
# TODO: do not remove link when not needed
if len(configuration.get_links()) != 0 or len(mani.get_links()) != 0:
debug.info(type_call + ": remove old links ...")
for elem in configuration.get_links():
base_path = os.path.join(env.get_island_root_path(), elem["destination"])
debug.info(type_call + ": link: " + str(base_path))
if os.path.islink(base_path) is True:
os.unlink(base_path)
else:
debug.error(
type_call + ": remove link is not authorised ==> not a link",
crash=False,
)
have_error = True
configuration.clear_links()
debug.info(type_call + ": add new links ...")
for elem in mani.get_links():
base_path = os.path.join(env.get_island_root_path(), elem["destination"])
source_path = os.path.join(env.get_island_root_path(), elem["source"])
debug.info(type_call + ": link: " + str(base_path))
if os.path.exists(base_path) is True:
debug.error(
type_call + ": create link is not possible ==> path already exist",
crash=False,
)
have_error = True
else:
tools.create_directory_of_file(base_path)
os.symlink(source_path, base_path)
configuration.add_link(elem["source"], elem["destination"])
configuration.store()

262
island/bin_island.py Executable file
View File

@@ -0,0 +1,262 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Inland main().
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import copy
import fnmatch
import os
import sys
from typing import Union
import death.ArgElement as arg_element
import death.Arguments as arguments
from realog import debug
# Local import
from . import (
actions,
env,
host,
tools,
)
is_init = False
debug.set_display_on_error(" ==========================\n == Some error occurred ==\n ==========================")
def init() -> None:
"""Global initialization of Island."""
global is_init
if is_init is True:
return
# import local island files
list_of_island_files = tools.import_path_local(
os.path.join(tools.get_current_path(__file__), "actions"),
base_name=env.get_system_base_name() + "*.py",
)
actions.init(list_of_island_files)
# import project actions files
list_of_island_files = tools.import_path_local(
env.get_island_root_path(),
2,
[".island", ".git", "archive"],
base_name=env.get_system_base_name() + "*.py",
)
actions.init(list_of_island_files)
is_init = True
def usage(my_args) -> None:
"""Display the help of Island."""
color = debug.get_color_set()
# Generic argument displayed :
my_args.display()
print(" Action available")
list_actions = actions.get_list_of_action()
for elem in list_actions:
print(f" {color['green']}{elem}{color['default']}")
print(f" {actions.get_action_help(elem)}")
"""
print(" {color['green']}init{color['default']}")
print(" initialize a 'island' interface with a manifest in a git ")
print(" {color['green']}sync{color['default']}")
print(" Synchronize the current environnement")
print(" {color['green']}status{color['default']}")
print(" Dump the status of the environnement")
"""
print(f" ex: {sys.argv[0]} -c init http://github.com/atria-soft/manifest.git")
print(f" ex: {sys.argv[0]} sync")
exit(0)
def check_boolean(value: Union[bool, str]) -> bool:
"""Check if the value is a real boolean or a boolean string and return the boolean value.
:param value: Value to check.
:return: Equivalent boolean value.
"""
if value == "" or value == "1" or value == "true" or value == "True" or value is True:
return True
return False
def parse_generic_arg(my_args, argument: arg_element.ArgElement, active: bool) -> bool:
"""Keep global args that have no dependence with the mode.
:param argument: _description_
:param active: _description_
:return: _description_
"""
debug.extreme_verbose(f"parse arg : {argument.get_option_name()} {argument.get_arg()} active={active}")
if argument.get_option_name() == "help":
if active is False:
usage(my_args)
return True
elif argument.get_option_name() == "jobs":
if active is True:
# multiprocess.set_core_number(int(argument.get_arg()))
pass
return True
elif argument.get_option_name() == "wait":
if active is True:
env.set_wait_between_sever_command(int(argument.get_arg()))
return True
elif argument.get_option_name() == "verbose":
if active is True:
debug.set_level(int(argument.get_arg()))
return True
elif argument.get_option_name() == "folder":
if active is True:
env.set_display_folder_instead_of_git_name(True)
return True
elif argument.get_option_name() == "color":
if active is True:
if check_boolean(argument.get_arg()) is True:
debug.enable_color()
else:
debug.disable_color()
return True
elif argument.get_option_name() == "filter":
if active is True:
env.set_filter_command(str(argument.get_arg()))
return True
elif argument.get_option_name() == "no-fetch-manifest":
if active is False:
env.set_fetch_manifest(False)
return True
return False
def main():
# initialize the system ...
init()
debug.verbose("List of actions: " + str(actions.get_list_of_action()))
my_args = arguments.Arguments()
my_args.add_section("option", "Can be set one time in all case")
my_args.add("h", "help", desc="Display this help")
my_args.add(
"v",
"verbose",
list=[
["0", "None"],
["1", "error"],
["2", "warning"],
["3", "info"],
["4", "debug"],
["5", "verbose"],
["6", "extreme_verbose"],
],
desc="display debug level (verbose) default =2",
)
my_args.add("c", "color", desc="Display message in color")
my_args.add("n", "no-fetch-manifest", haveParam=False, desc="Disable the fetch of the manifest")
my_args.add(
"F",
"filter",
haveParam=True,
desc="Filter the action on a list of path or subpath: -f library",
)
my_args.add(
"f",
"folder",
haveParam=False,
desc="Display the folder instead of the git repository name",
)
my_args.add(
"w",
"wait",
haveParam=True,
desc="Wait between 2 access on the server (needed when the server is really slow to remove ssh connection) (default="
+ str(env.get_wait_between_sever_command())
+ ")",
)
my_args.set_stop_at(actions.get_list_of_action())
local_argument = my_args.parse()
# open configuration of island:
config_file = env.get_island_path_user_config()
if os.path.isfile(config_file) is True:
sys.path.append(os.path.dirname(config_file))
debug.debug(f"Find basic configuration file: '{config_file}'")
# the file exist, we can open it and get the initial configuration:
configuration_file = __import__(env.get_system_config_name()[:-3])
if "get_exclude_path" in dir(configuration_file):
data = configuration_file.get_exclude_path()
debug.debug(f"get default config 'get_exclude_path' val='{data}'")
env.set_exclude_search_path(data)
if "get_default_color" in dir(configuration_file):
data = configuration_file.get_default_color()
debug.debug(f"get default config 'get_default_color' val='{data}'")
parse_generic_arg(my_args, arg_element.ArgElement("color", str(data)), True)
if "get_default_debug_level" in dir(configuration_file):
data = configuration_file.get_default_debug_level()
debug.debug(f"get default config 'get_default_debug_level' val='{data}'")
parse_generic_arg(my_args, arg_element.ArgElement("verbose", str(data)), True)
if "get_default_folder" in dir(configuration_file):
data = configuration_file.get_default_folder()
debug.debug(f"get default config 'get_default_folder' val='{data}'")
parse_generic_arg(my_args, arg_element.ArgElement("folder", str(data)), True)
if "get_default_wait" in dir(configuration_file):
data = configuration_file.get_default_wait()
debug.debug(f"get default config 'get_default_wait' val='{data}'")
parse_generic_arg(my_args, arg_element.ArgElement("wait", str(data)), True)
if "get_default_filter" in dir(configuration_file):
data = configuration_file.get_default_filter()
debug.debug(f"get default config 'get_default_filter' val='{data}'")
parse_generic_arg(my_args, arg_element.ArgElement("filter", str(data)), True)
# parse default unique argument:
for argument in local_argument:
parse_generic_arg(my_args, argument, True)
# remove all generic arguments:
new_argument_list = []
for argument in local_argument:
if parse_generic_arg(my_args, argument, False) is True:
continue
new_argument_list.append(argument)
# now the first argument is: the action:
if len(new_argument_list) == 0:
debug.warning("--------------------------------------")
debug.warning("Missing the action to do ...")
debug.warning("--------------------------------------")
usage(my_args)
# TODO : move tin in actions ...
list_actions = actions.get_list_of_action()
action_to_do = new_argument_list[0].get_arg()
new_argument_list = new_argument_list[1:]
if action_to_do not in list_actions:
debug.warning("--------------------------------------")
debug.warning(f"Wrong action type : '{action_to_do}' available list: {list_actions}")
debug.warning("--------------------------------------")
usage(my_args)
# todo : Remove this
if action_to_do != "init" and os.path.exists(env.get_island_path()) is False:
debug.error(f"Can not execute a island cmd if we have not initialize a config: '.{env.get_system_base_name()}' in upper 6 parent path")
exit(-1)
ret = actions.execute(action_to_do, my_args.get_last_parsed() + 1)
exit(ret)

457
island/commands.py Normal file
View File

@@ -0,0 +1,457 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Command interface.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import errno
import fnmatch
import os
import shutil
import stat
from pathlib import Path
# Local import
from realog import debug
from . import (
env,
multiprocess,
)
def check_repository_is_modify(path_repository):
# check if the repository is modify
cmd = "git diff --quiet"
debug.verbose(f"execute : {cmd}")
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value,
"check_repository_is_modify",
error_only=True,
available_return=[0, 1],
display_if_nothing=False,
)
ret_diff = return_value
if ret_diff[0] == 0:
return False
return True
def get_list_branch_meta(path_repository):
# get local branch
cmd = "git branch -a"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "get_list_branch_meta", error_only=True
)
ret_branch = return_value
list_branch = ret_branch[1].split("\n")
out = []
for elem_branch in list_branch:
is_remote = False
branch_name = ""
is_selected = False
if len(elem_branch.split(" -> ")) != 1:
continue
# separate the remote element
if elem_branch[2:10] == "remotes/":
elem_branch = elem_branch[:2] + elem_branch[10:]
is_remote = True
# separate select branch
if elem_branch[:2] == "* ":
is_selected = True
branch_name = elem_branch[2:]
else:
branch_name = elem_branch[2:]
out.append({"remote": is_remote, "name": branch_name, "select": is_selected})
debug.extreme_verbose("List all branch Meta: " + str(out))
return out
def get_list_branch_all(path_repository):
tmp = get_list_branch_meta(path_repository)
out = []
for elem in tmp:
out.append(elem["name"])
debug.verbose("List all branch: " + str(out))
return out
def get_list_branch_local(path_repository):
tmp = get_list_branch_meta(path_repository)
out = []
for elem in tmp:
if elem["remote"] is False:
out.append(elem["name"])
debug.verbose("List local branch: " + str(out))
return out
def get_list_branch_remote(path_repository):
tmp = get_list_branch_meta(path_repository)
out = []
for elem in tmp:
if elem["remote"] is True:
out.append(elem["name"])
debug.verbose("List remote branch: " + str(out))
return out
def get_current_branch(path_repository):
tmp = get_list_branch_meta(path_repository)
for elem in tmp:
if elem["select"] is True:
debug.verbose("List local branch: " + str(elem["name"]))
return elem["name"]
debug.verbose("List local branch: None")
return None
def get_current_tracking_branch(path_repository):
# get tracking branch
cmd = "git rev-parse --abbrev-ref --symbolic-full-name @{u}"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
if return_value[1] == "@{u}":
debug.warning("in '" + path_repository + "' no tracking branch is specify")
return None
multiprocess.generic_display_error(
return_value, "get_current_tracking_branch", error_only=True
)
return return_value[1]
def get_revision_list_to_branch(path_repository, branch):
cmd = "git rev-list " + branch
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "get_revision_list_to_branch", error_only=True
)
return return_value[1].split("\n")
def get_specific_commit_message(path_repository, sha_1):
if sha_1 is None or sha_1 == "":
return ""
cmd = "git log --format=%B -n 1 " + sha_1
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "get_specific_commit_message", error_only=True
)
return return_value[1].split("\n")[0]
def get_sha1_for_branch(path_repository, branch_name):
if branch_name == None or branch_name == "":
return None
cmd = "git rev-parse " + branch_name
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "get_sha1_for_branch", error_only=True
)
return return_value[1].split("\n")[0]
def get_tags_current(path_repository):
cmd = "git tag --points-at"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "get_tags_current", error_only=True
)
list_tags = []
for elem in return_value[1].split("\n"):
if elem != "":
list_tags.append(elem)
return list_tags
def get_tags(path_repository):
cmd = "git tag"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "get_tags", error_only=True)
return return_value[1].split("\n")
def get_tags_remote(path_repository, remote_name):
if remote_name == "" or remote_name == None:
return get_current_tracking_branch(path_repository)
cmd = "git ls-remote --tags " + remote_name
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "get_tags_remote", error_only=True)
list_element = return_value[1].split("\n")
debug.verbose(" receive: " + str(list_element))
# 6bc01117e85d00686ae2d423193a161e82df9a44 refs/tags/0.1.0
# 7ef9caa51cf3744de0f46352e5aa07bd4980fe89 refs/tags/v0.2.0
# 870e8e039b0a98370a9d23844f0af66824c57a5f refs/tags/v0.2.0^{}
# 16707e17e58f16b3409f8c64df7f595ba7dcf499 refs/tags/v0.3.0
# dfb97c3dfea776e5c4862dc9f60f8c5ad83b55eb refs/tags/v0.3.0^{}
out = []
for elem in list_element:
cut = elem.split("\t")
if len(cut) != 2:
continue
if cut[1][-3:] == "^{}":
# specific usage for the annotated commit
continue
if cut[1][:10] == "refs/tags/":
out.append(cut[1][10:])
else:
out.append(cut[1])
return out
def get_tracking_branch(path_repository, remote_name, select_branch):
# get tracking branch
if remote_name == "" or remote_name == None:
return get_current_tracking_branch(path_repository)
list_branch_remote = get_list_branch_remote(path_repository)
debug.extreme_verbose(
"check if exist "
+ remote_name
+ "/"
+ select_branch
+ " in "
+ str(list_branch_remote)
)
if remote_name + "/" + select_branch not in list_branch_remote:
debug.debug(" ==> can not get remote branch")
return None
return remote_name + "/" + select_branch
def merge_branch_on_master(
path_repository, branch_name, merge_force=True, branch_destination="master"
):
if branch_name == None or branch_name == "":
raise "Missing branch name"
cmd = "git merge "
if merge_force is True:
cmd += "--no-ff "
cmd += (
branch_name
+ " --message \"Merge branch '"
+ branch_name
+ "' into '"
+ branch_destination
+ "'\""
)
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "merge_branch_on_master", error_only=True
)
return return_value
def call_island_release_script(path_repository: str) -> bool:
cmd = ".island/release.bash"
file_path = Path(path_repository) / ".island/release.bash"
if not file_path.exists():
return False
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command_direct(cmd, cwd=path_repository)
multiprocess.generic_display_error(
return_value, "call_island_release_script", error_only=True
)
return True
def add_all(path_repository):
cmd = "git add -u"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "add_all", error_only=True)
return return_value
def add_file(path_repository, file_path):
if not file_path:
raise IOError("Missing file_path name")
cmd = "git add " + file_path
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "add_file", error_only=True)
return return_value
def commit_all(path_repository, comment):
if not comment:
raise IOError("Missing comment description")
cmd = 'git commit -a --message "' + comment + '"'
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "commit_all", error_only=True)
return return_value
def tag(path_repository, tag_name):
if not tag_name:
raise IOError("Missing tag name")
tag_name = tag_name.replace(" ", "_")
cmd = "git tag " + tag_name + ' --message "[TAG] create tag ' + tag_name + '"'
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "tag", error_only=True)
return return_value
def checkout(path_repository, branch_name):
if branch_name == None or branch_name == "":
raise "Missing branch name"
cmd = "git checkout " + branch_name
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "checkout", error_only=True)
return return_value
def reset_hard(path_repository, destination):
if destination == None or destination == "":
raise "Missing destination 'sha1' or 'branch name'"
cmd = "git reset --hard " + destination
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "reset_hard", error_only=True)
return return_value
def rebase(path_repository, destination):
if destination == None or destination == "":
raise "Missing destination 'sha1' or 'branch name'"
cmd = "git rebase " + destination
debug.verbose("execute : " + cmd)
# TODO: check if the command work correctly
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "rebase", error_only=True)
return return_value
def clone(path_repository, address, branch_name=None, origin=None):
if address == None or address == "":
raise "Missing address"
cmd = "git clone " + address
if branch_name != None and branch_name == "":
cmd += " --branch " + branch_name
if origin != None and origin == "":
cmd += " --origin " + origin
if path_repository != None and path_repository != "":
cmd += " " + path_repository
debug.verbose("execute : " + cmd)
if os.path.exists(path_repository) is True:
debug.warning("Can not clone repository path already exist")
return False
return_value = multiprocess.run_command(cmd)
multiprocess.generic_display_error(return_value, "clone", error_only=True)
return return_value
def fetch(path_repository, remote_name, prune=True):
cmd = "git fetch " + remote_name
if prune is True:
cmd += " --prune"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "fetch")
return return_value
def pull(path_repository, remote_name, prune=True):
if remote_name == None or remote_name == "":
raise "Missing remote_name"
cmd = "git pull " + remote_name
if prune is True:
cmd += " --prune"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "pull")
return return_value
def push(path_repository, remote_name, elements):
if remote_name == None or remote_name == "":
raise "Missing remote_name"
if len(elements) == 0:
raise "No elements to push on server"
cmd = "git push " + remote_name
for elem in elements:
cmd += " " + elem
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "push")
return return_value
def submodule_sync(path_repository, remote_name):
cmd = "git submodule sync"
debug.verbose("execute : " + cmd)
return_value = multiprocess.run_command(cmd, cwd=path_repository)
multiprocess.generic_display_error(return_value, "submodule_sync")
"""
if ret[:31] == "Synchronizing submodule url for":
#all is good ...
debug.info(" " + ret)
elif ret != "" \
and ret != False:
# all is good, ready to get the system work corectly
debug.info("'" + ret + "'")
debug.error("Can not sync submodules ... ")
"""
def get_forward(path_repository, branch_name):
if branch_name == None or branch_name == "":
raise "get_fast_forward: Missing branch_name"
select_branch = get_current_branch(path_repository)
# get tracking branch
ret_current_branch_sha1 = get_revision_list_to_branch(
path_repository, select_branch
)
ret_track_branch_sha1 = get_revision_list_to_branch(path_repository, branch_name)
# count the number of commit fast forward
forward_count = 0
for elem_sha1 in ret_current_branch_sha1:
if elem_sha1 not in ret_track_branch_sha1:
forward_count += 1
return forward_count
def is_forward(path_repository, branch_name):
return get_forward(path_repository, branch_name) != 0
def get_behind(path_repository, branch_name):
if branch_name == None or branch_name == "":
raise "get_fast_forward: Missing branch_name"
select_branch = get_current_branch(path_repository)
# get tracking branch
ret_current_branch_sha1 = get_revision_list_to_branch(
path_repository, select_branch
)
ret_track_branch_sha1 = get_revision_list_to_branch(path_repository, branch_name)
# count the number of commit behind
behind_count = 0
for elem_sha1 in ret_track_branch_sha1:
if elem_sha1 not in ret_current_branch_sha1:
behind_count += 1
return behind_count
def is_behind(path_repository, branch_name):
return get_behind(path_repository, branch_name) != 0

View File

@@ -1,56 +1,73 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Config main interface.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
import platform
import sys
import os
import copy import copy
import json
import os
from typing import Optional
# Local import # Local import
from realog import debug from realog import debug
from . import tools
from . import env from . import (
from . import multiprocess env,
repo_config,
tools,
)
env.get_island_path_config() env.get_island_path_config()
class Config(): class Config:
def __init__(self): def __init__(self) -> None:
self._repo = "" self._repo = ""
self._branch = "master" self._branch = "master"
self._manifest_name = "default.xml" self._manifest_name = "default.xml"
self._volatiles = []
self._current_link = []
self.load() self.load()
def load(self) -> bool:
def load(self): if os.path.exists(env.get_island_path_config()) is False:
config_property = tools.file_read_data(env.get_island_path_config())
element_config = config_property.split("\n")
for line in element_config:
if len(line) == 0 \
or line[0] == "#":
# simple comment line ==> pass
pass
elif line[:5] == "repo=":
self._repo = line[5:]
elif line[:7] == "branch=":
self._branch = line[7:]
elif line[:5] == "file=":
self._manifest_name = line[5:]
else:
debug.warning("island config error: can not parse: '" + str(line) + "'")
return True return True
self._volatiles = []
self._current_link = []
with open(env.get_island_path_config()) as json_file:
data = json.load(json_file)
if "repo" in data.keys():
self._repo = data["repo"]
if "branch" in data.keys():
self._branch = data["branch"]
if "manifest_name" in data.keys():
self._manifest_name = data["manifest_name"]
if "volatiles" in data.keys():
for elem in data["volatiles"]:
if "git_address" in elem.keys() and "path" in elem.keys():
self.add_volatile(elem["git_address"], elem["path"])
if "link" in data.keys():
for elem in data["link"]:
if "source" in elem.keys() and "destination" in elem.keys():
self.add_link(elem["source"], elem["destination"])
return True
return False
def store(self): def store(self) -> bool:
data = "repo=" + self._repo + "\nbranch=" + self._branch + "\nfile=" + self._manifest_name data = {}
tools.file_write_data(env.get_island_path_config(), data) data["repo"] = self._repo
data["branch"] = self._branch
data["manifest_name"] = self._manifest_name
data["volatiles"] = self._volatiles
data["link"] = self._current_link
with open(env.get_island_path_config(), "w") as outfile:
json.dump(data, outfile, indent=4)
return True
return False
def set_manifest(self, value): def set_manifest(self, value):
self._repo = value self._repo = value
@@ -70,3 +87,66 @@ class Config():
def get_manifest_name(self): def get_manifest_name(self):
return self._manifest_name return self._manifest_name
def add_volatile(self, git_adress, local_path):
for elem in self._volatiles:
if elem["path"] == local_path:
debug.error(
"can not have multiple local repositoty on the same PATH",
crash=False,
)
return False
self._volatiles.append({"git_address": git_adress, "path": local_path})
return True
def get_volatile(self):
return copy.deepcopy(self._volatiles)
def get_links(self):
return self._current_link
def add_link(self, source, destination) -> bool:
for elem in self._current_link:
if elem["destination"] == destination:
debug.error(
"can not have multiple destination folder in link " + destination,
crash=False,
)
return False
self._current_link.append({"source": source, "destination": destination})
return True
def remove_link(self, destination) -> None:
for elem in self._current_link:
if elem["destination"] == destination:
del self._current_link[elem]
return
debug.warning("Request remove link that does not exist")
def clear_links(self):
self._current_link = []
def get_manifest_config(self):
conf = repo_config.RepoConfig()
base_volatile, repo_volatile = repo_config.split_repo(self.get_manifest())
conf.name = repo_volatile
conf.path = os.path.join("." + env.get_system_base_name(), "manifest") # env.get_island_path_manifest()
conf.branch = "master"
conf.volatile = False
conf.remotes = [{"name": "origin", "fetch": base_volatile, "mirror": []}]
conf.select_remote = {
"name": "origin",
"fetch": base_volatile,
"sync": False,
"mirror": [],
}
return conf
_unique_config: Optional[Config] = None
def get_unique_config() -> Config:
global _unique_config
if _unique_config is None:
_unique_config = Config()
return _unique_config

View File

@@ -1,83 +1,170 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Environment management.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
import os
# Local import # Local import
from realog import debug from realog import debug
import os
system_base_name = "island" system_base_name = "island"
def set_system_base_name(val): def set_system_base_name(val):
global system_base_name global system_base_name
system_base_name = val system_base_name = val
debug.debug("Set basename: '" + str(system_base_name) + "'") debug.debug("Set basename: '" + str(system_base_name) + "'")
def get_system_base_name(): def get_system_base_name():
global system_base_name global system_base_name
return system_base_name return system_base_name
def get_system_config_name():
global system_base_name
return system_base_name + "Config.py"
fetch_manifest = True fetch_manifest = True
def set_fetch_manifest(val): def set_fetch_manifest(val):
global fetch_manifest global fetch_manifest
fetch_manifest = val fetch_manifest = val
def get_fetch_manifest(): def get_fetch_manifest():
global fetch_manifest global fetch_manifest
return fetch_manifest return fetch_manifest
wait_between_sever_command = 0
def set_wait_between_sever_command(val):
global wait_between_sever_command
wait_between_sever_command = val
def get_wait_between_sever_command():
global wait_between_sever_command
return wait_between_sever_command
filter_command = ""
def set_filter_command(val):
global filter_command
filter_command = val
def get_filter_command():
global filter_command
return filter_command
def need_process_with_filter(data):
global filter_command
if filter_command == "":
return True
if len(data) < len(filter_command):
return False
if data[: len(filter_command)] == filter_command:
return True
return False
display_folder_instead_of_git_name = True
def set_display_folder_instead_of_git_name(val):
global display_folder_instead_of_git_name
display_folder_instead_of_git_name = val
def get_display_folder_instead_of_git_name():
global display_folder_instead_of_git_name
return display_folder_instead_of_git_name
island_root_path = os.path.join(os.getcwd()) island_root_path = os.path.join(os.getcwd())
if os.path.exists(os.path.join(island_root_path, "." + get_system_base_name())) == True: if os.path.exists(os.path.join(island_root_path, "." + get_system_base_name())) is True:
# all is good ... # all is good ...
pass pass
elif os.path.exists(os.path.join(island_root_path, "..", "." + get_system_base_name())) == True: elif os.path.exists(os.path.join(island_root_path, "..", "." + get_system_base_name())):
island_root_path = os.path.join(os.getcwd(), "..") island_root_path = os.path.join(os.getcwd(), "..")
elif os.path.exists(os.path.join(island_root_path, "..", "..", "." + get_system_base_name())) == True: elif os.path.exists(os.path.join(island_root_path, "..", "..", "." + get_system_base_name())):
island_root_path = os.path.join(os.getcwd(), "..", "..") island_root_path = os.path.join(os.getcwd(), "..", "..")
elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "." + get_system_base_name())) == True: elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "." + get_system_base_name())):
island_root_path = os.path.join(os.getcwd(), "..", "..", "..") island_root_path = os.path.join(os.getcwd(), "..", "..", "..")
elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "..", "." + get_system_base_name())) == True: elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "..", "." + get_system_base_name())):
island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..") island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..")
elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "..", "..", "." + get_system_base_name())) == True: elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "..", "..", "." + get_system_base_name())):
island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..") island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..")
elif os.path.exists(os.path.join(island_root_path, "..", "..", "..", "..", "..", "..", "." + get_system_base_name())) == True: elif os.path.exists(
os.path.join(
island_root_path,
"..",
"..",
"..",
"..",
"..",
"..",
"." + get_system_base_name(),
)
):
island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..", "..") island_root_path = os.path.join(os.getcwd(), "..", "..", "..", "..", "..", "..")
else: else:
# debug.error("the root path of " + get_system_base_name() + " must not be upper that 6 parent path") # debug.error("the root path of " + get_system_base_name() + " must not be upper that 6 parent path")
pass pass
island_path_user_config = os.path.join(island_root_path, get_system_config_name())
island_path = os.path.join(island_root_path, "." + get_system_base_name()) island_path = os.path.join(island_root_path, "." + get_system_base_name())
island_path_config = os.path.join(island_path, "config.txt") island_path_config = os.path.join(island_path, "config.json")
island_path_manifest = os.path.join(island_path, "manifest") island_path_manifest = os.path.join(island_path, "manifest")
##
## @brief to use later to know where the ".island" parent path is ... def get_island_root_path() -> str:
## @return the parent path of the ".island" """Get the parent path where is define ".island" folder.
##
def get_island_root_path(): :return: the parent path of the ".island"
"""
global island_root_path global island_root_path
return island_root_path return island_root_path
def get_island_path():
def get_island_path() -> str:
global island_path global island_path
return island_path return island_path
def get_island_path_config():
def get_island_path_config() -> str:
global island_path_config global island_path_config
return island_path_config return island_path_config
def get_island_path_manifest():
def get_island_path_manifest() -> str:
global island_path_manifest global island_path_manifest
return island_path_manifest return island_path_manifest
def get_island_path_user_config() -> str:
global island_path_user_config
return island_path_user_config
ret_manifest_is_not_existing = -5
ret_action_is_not_existing = -10
ret_action_executing_system_error = -11
ret_action_wrong_parameters = -12
ret_action_partial_done = -13
ret_action_fail = -14
ret_action_need_update = 15

View File

View File

@@ -1,18 +1,16 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Type of host detection.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
import platform import platform
import sys
# Local import
from realog import debug from realog import debug
# print os.name # ==> 'posix'
if platform.system() == "Linux": if platform.system() == "Linux":
OS = "Linux" OS = "Linux"
elif platform.system() == "Windows": elif platform.system() == "Windows":
@@ -20,7 +18,6 @@ elif platform.system() == "Windows":
elif platform.system() == "Darwin": elif platform.system() == "Darwin":
OS = "MacOs" OS = "MacOs"
else: else:
debug.error("Unknow the Host OS ... '" + platform.system() + "'") debug.error(f"Unknown the Host OS ... '{platform.system()}'")
debug.debug("host.OS = " + OS)
debug.debug("host.OS = {OS}")

14
island/link_config.py Normal file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Link interface.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
class LinkConfig:
def __init__(self) -> None:
self.source = ""
self.destination = ""

View File

@@ -1,59 +1,231 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Manifest interface.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
## import json
import platform
import sys
import os
import copy import copy
# Local import import os
from realog import debug from typing import List, Dict, Any
from . import tools
from . import env # import pyyaml module
from . import multiprocess import yaml
from yaml.loader import SafeLoader
from lxml import etree from lxml import etree
class RepoConfig(): # Local import
def __init__(self): from realog import debug
self.name = ""
self.path = "" from . import (
self.remotes = [] # list of all remotes, with the upstream elements (needed for third party integrations) config,
self.select_remote = "" env,
self.branch = "" multiprocess,
repo_config,
)
class Manifest(): def is_island_init():
def __init__(self, manifest_xml): if not os.path.exists(env.get_island_path()):
self.manifest_xml = manifest_xml debug.verbose(f"Island is not init: path does not exist: '{env.get_island_path()}'")
self.projects = [] return False
if not os.path.exists(env.get_island_path_config()):
debug.verbose(f"Island is not init: config does not exist: '{env.get_island_path_config()}'")
return False
if not os.path.exists(env.get_island_path_manifest()):
debug.verbose(f"Island is not init: Manifest does not exist: '{env.get_island_path_manifest()}'")
return False
return True
def check_island_is_init():
# check if .XXX exist (create it if needed)
if not is_island_init():
debug.error(f"System not init: missing config: '{env.get_island_path()}'. Call <island init> first")
exit(-1)
class ManifestVSC:
def __init__(self, manifest_yaml: str) -> None:
self.manifest_yaml = manifest_yaml
self.projects: List[Dict] = []
self.default = None self.default = None
self.default_base = { self.default_base = {
"remote": "origin", "remote": "origin",
"revision":"master", "revision": "master", # todo: rename 'branch-release'
"sync": False, "sync": False,
"branch-develop": "dev",
"default-branch": "dev",
} }
self.remotes = [] self.remotes: List[Dict] = []
self.includes = [] self.deliver_master = "master"
self.deliver_develop = "develop"
self.deliver_mode = "merge"
# load the manifest # load the manifest
self._load() self._load()
# check error in manifest (double path ...) # check error in manifest (double path ...)
self._check_double_path([]) self._check_double_path([])
def get_links(self):
return []
def _load(self): def _load(self):
debug.debug(f"manifest VSC: '{self.manifest_yaml}'")
data = {}
with open(self.manifest_yaml) as f:
data = yaml.load(f, Loader=SafeLoader)
if "repositories" not in data:
debug.error(f"in '{self.manifest_yaml}' VSC manifest: missing root key: repositories ")
for name, value in data["repositories"].items():
if "type" in value and value["type"] != "git":
debug.error(f"in '{self.manifest_yaml}' VSC manifest: unsupported type: '{value['type']}' for {name}")
if "url" not in value:
debug.error(f"in '{self.manifest_yaml}' VSC manifest: missing 'url' for {name}")
url = value["url"]
# TODO: Manage URL remote element ==> dynamic add !!! and manage http(s)://xxx.yyy/*
url_split = url.split(":")
if len(url_split) > 1:
url = url_split[-1]
version = None
if "version" not in value:
version = value["version"]
self.projects.append(
{
"name": url,
"path": name,
"tag": version,
}
)
def _create_path_with_elem(self, element):
# debug.info(f"create path : {json.dumps(element)}")
path = element["path"]
if path == "":
path = element["name"]
if len(path) >= 4 and path[-4:] == ".git":
path = path[:-4]
# debug.info(f" generate path {path}")
return path
def _check_double_path(self, list_path=[], space=""):
# debug.debug(f"{space}check path : '{self.manifest_yaml}'")
for elem in self.projects:
path = self._create_path_with_elem(elem)
debug.debug(f"{space} check path:'{path}'")
if path in list_path:
debug.error(f"Check Manifest error : double use of the path '{path}'")
list_path.append(path)
def get_all_configs(self, default=None, upper_remotes=[]):
out = []
if default is None:
if self.default is not None:
default = copy.deepcopy(self.default)
else:
default = copy.deepcopy(self.default_base)
# debug.error(f" self.default={self.default}")
# add all local project
for elem in self.projects:
debug.verbose(f"parse element {elem}")
if env.need_process_with_filter(elem["name"]) is False:
debug.info(f"Filter repository: {elem['name']}")
continue
conf = repo_config.RepoConfig()
conf.name = elem["name"]
conf.tag = elem["tag"]
conf.path = self._create_path_with_elem(elem)
# add default remote for the project (search in inherited element)
for remote in self.remotes:
debug.verbose(f" Local Remote: {remote}")
if remote["name"] == default["remote"]:
conf.remotes.append(remote)
if len(conf.remotes) == 0:
for remote in upper_remotes:
debug.verbose(f" upper Remote: {remote}")
if remote["name"] == default["remote"]:
conf.remotes.append(remote)
if len(conf.remotes) == 0:
debug.error(
f" No remote detected: {len(conf.remotes)} for {conf.name} with default remote name : {default['remote']} self remote: {self.remotes}"
)
# select default remote:
conf.select_remote = None
debug.debug(f" remotes count: {len(conf.remotes)}")
for remote in conf.remotes:
debug.debug(f" remote={remote}")
debug.debug(f" Check remote : {remote['name']} == {default['remote']}")
debug.verbose(f" remote={remote}")
debug.verbose(f" default={default}")
if remote["name"] == default["remote"]:
conf.select_remote = copy.deepcopy(remote)
debug.debug(f" copy select={conf.select_remote}")
# copy the submodule synchronization
conf.select_remote["sync"] = default["sync"]
break
if conf.select_remote == None:
debug.error(f"missing remote for project: {conf.name}")
conf.branch = default["revision"]
out.append(conf)
# create a temporary variable to transmit the remote to includes
upper_remotes_forward = copy.deepcopy(upper_remotes)
for remote in self.remotes:
upper_remotes_forward.append(remote)
if False:
debug.info("list of all repo:")
for elem in out:
debug.info(f" '{elem.name}'")
debug.info(f" path: {elem.path}")
debug.info(f" remotes: {elem.remotes}")
debug.info(f" select_remote: {elem.select_remote}")
debug.info(f" branch: {elem.branch}")
return out
class Manifest:
def __init__(self, manifest_xml: str) -> None:
self.manifest_xml = manifest_xml
self.projects: List[Dict] = []
self.default = None
self.default_base = {
"remote": "origin",
"revision": "master", # todo: rename 'branch-release'
"sync": False,
"branch-develop": "dev",
"default-branch": "dev",
}
self.remotes: List[Dict] = []
self.includes: List[Dict] = []
self.imports: List[Dict] = []
self.links: List[Dict] = []
self.deliver_master = "master"
self.deliver_develop = "develop"
self.deliver_mode = "merge"
# load the manifest
self._load()
# check error in manifest (double path ...)
self._check_double_path([])
def get_links(self) -> Dict[str, Any]:
return self.links
def _load(self) -> None:
debug.debug(f"manifest : '{self.manifest_xml}'")
tree = etree.parse(self.manifest_xml) tree = etree.parse(self.manifest_xml)
debug.debug("manifest : '" + self.manifest_xml + "'")
root = tree.getroot() root = tree.getroot()
if root.tag != "manifest": if root.tag != "manifest":
debug.error("(l:" + str(child.sourceline) + ") in '" + str(file) + "' have not main xml node='manifest'") debug.error(f"(l:{child.sourceline}) in '{file}' have not main xml node='manifest'")
for child in root: for child in root:
if type(child) == etree._Comment: if type(child) == etree._Comment:
debug.verbose("(l:" + str(child.sourceline) + ") comment='" + str(child.text) + "'"); debug.verbose(f"(l:{child.sourceline}) comment='{child.text}'")
continue continue
if child.tag == "remote": if child.tag == "remote":
name = "origin" name = "origin"
@@ -63,41 +235,37 @@ class Manifest():
name = child.attrib[attr] name = child.attrib[attr]
elif attr == "fetch": elif attr == "fetch":
fetch = child.attrib[attr] fetch = child.attrib[attr]
if len(fetch) >= 2 \ if len(fetch) >= 2 and fetch[:2] == "..":
and fetch[:2] == "..":
# we have a relative island manifest ==> use local manifest origin to get the full origin # we have a relative island manifest ==> use local manifest origin to get the full origin
cmd = "git remote get-url origin" cmd = "git remote get-url origin"
debug.verbose("execute : " + cmd) debug.verbose(f"execute : {cmd}")
base_origin = multiprocess.run_command(cmd, cwd=env.get_island_path_manifest()) base_origin = multiprocess.run_command(cmd, cwd=env.get_island_path_manifest())
debug.verbose("base_origin=" + base_origin[1]) debug.verbose(f"base_origin={base_origin[1]}")
base_origin = base_origin[1] base_origin = base_origin[1]
while len(fetch) >= 2 \ while len(fetch) >= 2 and fetch[:2] == "..":
and fetch[:2] == "..":
fetch = fetch[2:] fetch = fetch[2:]
while len(fetch) >= 1 \ while len(fetch) >= 1 and (fetch[0] == "/" or fetch[0] == "\\"):
and ( fetch[0] == "/" \
or fetch[0] == "\\"):
fetch = fetch[1:] fetch = fetch[1:]
offset_1 = base_origin.rfind('/') offset_1 = base_origin.rfind("/")
offset_2 = base_origin.rfind(':') offset_2 = base_origin.rfind(":")
if offset_1 > offset_2: if offset_1 > offset_2:
base_origin = base_origin[:offset_1] base_origin = base_origin[:offset_1]
else: else:
base_origin = base_origin[:offset_2] base_origin = base_origin[:offset_2]
debug.verbose("new base_origin=" + base_origin) debug.verbose(f"new base_origin={base_origin}")
debug.verbose("tmp fetch=" + fetch) debug.verbose(f"tmp fetch={fetch}")
if fetch != "": if fetch != "":
fetch = base_origin + "/" + fetch fetch = f"{base_origin}/{fetch}"
else: else:
fetch = base_origin fetch = base_origin
debug.verbose("new fetch=" + fetch) debug.verbose(f"new fetch={fetch}")
while len(fetch) > 1 \ while len(fetch) > 1 and (fetch[-1] == "\\" or fetch[-1] == "/"):
and ( fetch[-1] == "\\" \
or fetch[-1] == "/") :
fetch = fetch[:-1] fetch = fetch[:-1]
else: else:
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name,fetch]") debug.error(
debug.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : name='" + name + "' fetch='" + fetch + "'"); f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}' attribute : '{attr}', available:[name,fetch]"
)
debug.debug(f"(l:{child.sourceline}) find '{child.tag}' : name='{name}' fetch='{fetch}'")
# parse the sub global mirror list # parse the sub global mirror list
mirror_list = [] mirror_list = []
for child_2 in child: for child_2 in child:
@@ -110,124 +278,197 @@ class Manifest():
mirror_name = child_2.attrib[attr_2] mirror_name = child_2.attrib[attr_2]
elif attr_2 == "fetch": elif attr_2 == "fetch":
mirror_fetch = child_2.attrib[attr_2] mirror_fetch = child_2.attrib[attr_2]
while len(mirror_fetch) > 1 \ while len(mirror_fetch) > 1 and (mirror_fetch[-1] == "\\" or mirror_fetch[-1] == "/"):
and ( mirror_fetch[-1] == "\\" \
or mirror_fetch[-1] == "/") :
mirror_fetch = mirror_fetch[:-1] mirror_fetch = mirror_fetch[:-1]
else: else:
debug.error("(l:" + str(child_2.sourceline) + ") Parsing the manifest : Unknow '" + child_2.tag + "' attibute : '" + attr_2 + "', availlable:[name,fetch]") debug.error(
debug.debug("mirror: '" + mirror_name + "' '" + mirror_fetch + "'") f"(l:{child_2.sourceline}) Parsing the manifest : unknown '{child_2.tag}' attribute : '{attr_2}', available:[name,fetch]"
)
debug.debug(f"mirror: '{mirror_name}' '{mirror_fetch}'")
if mirror_name == "": if mirror_name == "":
debug.error("(l:" + str(child_2.sourceline) + ") Missing mirrot 'name'") debug.error(f"(l:{child_2.sourceline}) Missing mirror 'name'")
if mirror_fetch == "": if mirror_fetch == "":
debug.error("(l:" + str(child_2.sourceline) + ") Missing mirror 'fetch'") debug.error(f"(l:{child_2.sourceline}) Missing mirror 'fetch'")
mirror_list.append({ mirror_list.append(
{
"name": mirror_name, "name": mirror_name,
"fetch": mirror_fetch, "fetch": mirror_fetch,
}) }
)
else: else:
debug.error("(l:" + str(child_2.sourceline) + ") Parsing the manifest : Unknow '" + child_2.tag + "', availlable:[mirror]") debug.error(f"(l:{child_2.sourceline}) Parsing the manifest : unknown '{child_2.tag}', available:[mirror]")
self.remotes.append({ self.remotes.append({"name": name, "fetch": fetch, "mirror": mirror_list})
"name":name,
"fetch":fetch,
"mirror":mirror_list
})
continue continue
if child.tag == "import":
type_manifest = "vcs"
name = ""
for attr in child.attrib:
if attr == "type":
type_manifest = child.attrib[attr]
if type_manifest not in ["vcs"]:
debug.error(
f"(l:{child.sourceline}) Parsing the manifest: {child.tag} attribute '{attr}={type_manifest}' value available: [vcs]"
)
elif attr == "name":
name = child.attrib[attr]
else:
debug.error(f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}' attribute : '{attr}', available:[name]")
new_name_yaml = os.path.join(os.path.dirname(self.manifest_xml), name)
if os.path.exists(new_name_yaml) is False:
debug.error(f"(l:{child.sourceline}) The file does not exist : '{new_name_yaml}'")
self.imports.append({"name": name, "path": new_name_yaml, "type": type_manifest})
continue
if child.tag == "include": if child.tag == "include":
name = "" name = ""
for attr in child.attrib: for attr in child.attrib:
if attr == "name": if attr == "name":
name = child.attrib[attr] name = child.attrib[attr]
else: else:
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name]") debug.error(f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}' attribute : '{attr}', available:[name]")
debug.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : name='" + name + "'"); debug.debug(f"(l:{child.sourceline}) find '{child.tag}' : name='{name}'")
# check if the file exist ... # check if the file exist ...
new_name_xml = os.path.join(os.path.dirname(self.manifest_xml), name) new_name_xml = os.path.join(os.path.dirname(self.manifest_xml), name)
if os.path.exists(new_name_xml) == False: if os.path.exists(new_name_xml) is False:
debug.error("(l:" + str(child.sourceline) + ") The file does not exist : '" + new_name_xml + "'") debug.error(f"(l:{child.sourceline}) The file does not exist : '{new_name_xml}'")
self.includes.append({ self.includes.append({"name": name, "path": new_name_xml, "manifest": None})
"name":name,
"path":new_name_xml,
"manifest":None
})
continue continue
if child.tag == "default": if child.tag == "option":
remote = "origin" remote = "origin"
revision = "master" deliver_master = "master"
sync = False sync = False
for attr in child.attrib: deliver_source = "dev"
if attr == "remote": default_branch = "dev"
remote = child.attrib[attr] deliver_mode = "fast_forward"
elif attr == "revision":
revision = child.attrib[attr] for child_2 in child:
elif attr == "sync-s": # synchronize submodule ... automaticaly if child_2.tag == "branch-release":
sync = child.attrib[attr] deliver_master = child_2.text
if sync.lower() == "true" \ elif child_2.tag == "branch-develop":
or sync == "1" \ deliver_source = child_2.text
or sync.lower() == "yes": elif child_2.tag == "default-branch":
default_branch = child_2.text
elif child_2.tag == "default-remote":
remote = child_2.text
elif child_2.tag == "deliver-mode":
deliver_mode = child_2.text
if deliver_mode not in ["merge", "fast_forward"]:
debug.error(f"(l:{child.sourceline}) Parsing the manifest: option 'deliver-mode' value available: [merge,fast_forward]")
elif child_2.tag == "synchronize-submodule":
sync_tmp = child_2.text
if sync_tmp.lower() == "true" or sync_tmp == "1" or sync_tmp.lower() == "yes":
sync = True sync = True
elif sync.lower() == "false" \ elif sync_tmp.lower() == "false" or sync_tmp == "0" or sync_tmp.lower() == "no":
or sync == "0" \
or sync.lower() == "no":
sync = False sync = False
else: else:
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attbute : '" + attr + "', value:'" + sync + "' availlable:[true,1,yes,false,0,no]") debug.error(
f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}/{child2.tag}', value:'{sync}' available:[true,1,yes,false,0,no]"
)
else: else:
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[remote,revision,sync-s]") debug.error(
if self.default != None: f"(l:{child_2.sourceline}) Parsing the manifest : unknown '{child.tag}/{child_2.tag}', available:[branch-release,branch-develop,default-branch,default-remote,synchronize-submodule]"
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest : Node '" + child.tag + "' already set") )
self.default = { self.default = {
"remote": remote, "remote": remote,
"revision":revision, "revision": deliver_master,
"sync": sync, "sync": sync,
"branch-develop": deliver_source,
"default-branch": default_branch,
"deliver-mode": deliver_mode,
} }
debug.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : remote='" + remote + "' revision='" + revision + "' sync=" + str(sync)); self.deliver_master = deliver_master
self.deliver_develop = deliver_source
self.deliver_mode = deliver_mode
debug.debug(f"(l:{child.sourceline}) find '{child.tag}':")
debug.debug(f" - default-branch:'{default_branch}':")
debug.debug(f" - default-remote:'{remote}':")
debug.debug(f" - synchronize-submodule:'{sync}':")
debug.debug(f" - branch-release:'{deliver_master}':")
debug.debug(f" - branch-develop:'{deliver_source}':")
debug.debug(f" - deliver-mode:'{deliver_mode}':")
continue continue
if child.tag == "project": if child.tag == "project":
name = "" name = ""
path = "" path = ""
tag_sha1 = None
for attr in child.attrib: for attr in child.attrib:
if attr == "name": if attr == "name":
name = child.attrib[attr] name = child.attrib[attr]
elif attr == "path": elif attr == "path":
path = child.attrib[attr] path = child.attrib[attr]
elif attr == "tag":
tag_sha1 = child.attrib[attr]
else: else:
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest: Unknow '" + child.tag + "' attibute : '" + attr + "', availlable:[name,revision,sync-s]") debug.error(
f"(l:{child.sourceline}) Parsing the manifest: unknown '{child.tag}' attribute : '{attr}', available:[name,tag,sync-s]"
)
if name == "": if name == "":
debug.error("(l:" + str(child.sourceline) + ") Parsing the manifest: '" + child.tag + "' missing attribute: 'name' ==> specify the git to clone ...") debug.error(
self.projects.append({ f"(l:{child.sourceline}) Parsing the manifest: '{child.tag}' missing attribute: 'name' ==> specify the git to clone ..."
)
self.projects.append(
{
"name": name, "name": name,
"path": path, "path": path,
}) "tag": tag_sha1,
debug.debug("(l:" + str(child.sourceline) + ") find '" + child.tag + "' : name='" + name + "' path='" + path + "'"); }
)
debug.debug(f"(l:{child.sourceline}) find '{child.tag}' : name='{name}' path='{path}' tag='{str(tag_sha1)}'")
continue continue
debug.info("(l:" + str(child.sourceline) + ") '" + str(child.tag) + "' values=" + str(child.attrib)); if child.tag == "link":
debug.error("(l:" + str(child.sourceline) + ") Parsing error Unknow NODE : '" + str(child.tag) + "' availlable:[remote,include,default,project]") # not managed ==> future use
source = ""
destination = ""
for attr in child.attrib:
if attr == "source":
source = child.attrib[attr]
elif attr == "destination":
destination = child.attrib[attr]
else:
debug.error(
f"(l:{child.sourceline}) Parsing the manifest: unknown '{child.tag}' attribute : '{attr}', available:[source,destination]"
)
if source == "":
debug.error(
f"(l:{child.sourceline}) Parsing the manifest: '{child.tag}' missing attribute: 'source' ==> specify the git to clone."
)
if destination == "":
debug.error(
f"(l:{child.sourceline}) Parsing the manifest: '{child.tag}' missing attribute: 'destination' ==> specify the git to clone."
)
self.links.append(
{
"source": source,
"destination": destination,
}
)
debug.debug(f"Add link: '{destination}' ==> '{source}'")
continue
debug.info(f"(l:{child.sourceline}) '{child.tag}' values={child.attrib}")
debug.error(f"(l:{child.sourceline}) Parsing error unknown NODE : '{child.tag}' available:[remote,include,default,project,option,link]")
# now we parse all sub repo: # now we parse all sub repo:
for elem in self.includes: for elem in self.includes:
elem["manifest"] = Manifest(elem["path"]) elem["manifest"] = Manifest(elem["path"])
for elem in self.imports:
elem["manifest"] = ManifestVSC(elem["path"])
# inside data child.text # inside data child.text
def _create_path_with_elem(self, element): def _create_path_with_elem(self, element):
path = element["path"] path = element["path"]
if path == "": if path == "":
path = element["name"] path = element["name"]
if len(path) >= 4 \ if len(path) >= 4 and path[-4:] == ".git":
and path[-4:] == ".git":
path = path[:-4] path = path[:-4]
return path return path
def _check_double_path(self, list_path=[], space=""): def _check_double_path(self, list_path=[], space=""):
debug.debug(space + "check path : '" + self.manifest_xml + "'") debug.debug(f"{space}check path : '{self.manifest_xml}'")
for elem in self.projects: for elem in self.projects:
path = self._create_path_with_elem(elem) path = self._create_path_with_elem(elem)
debug.debug(space + " check path:'" + str(path) + "'") debug.debug(f"{space} check path:'{path}'")
if path in list_path: if path in list_path:
debug.error("Check Manifest error : double use of the path '" + str(path) + "'") debug.error(f"Check Manifest error : double use of the path '{path}'")
list_path.append(path) list_path.append(path)
for elem in self.includes: for elem in self.includes:
elem["manifest"]._check_double_path(list_path, space + " ") elem["manifest"]._check_double_path(list_path, space + " ")
@@ -239,44 +480,50 @@ class Manifest():
default = copy.deepcopy(self.default) default = copy.deepcopy(self.default)
else: else:
default = copy.deepcopy(self.default_base) default = copy.deepcopy(self.default_base)
# debug.error(" self.default=" + str(self.default)) # debug.error(f" self.default={self.default}")
# add all local project # add all local project
for elem in self.projects: for elem in self.projects:
debug.verbose("parse element " + str(elem)) debug.verbose(f"parse element {elem}")
conf = RepoConfig() if env.need_process_with_filter(elem["name"]) is False:
debug.info(f"Filter repository: {elem['name']}")
continue
conf = repo_config.RepoConfig()
conf.name = elem["name"] conf.name = elem["name"]
conf.tag = elem["tag"]
conf.path = self._create_path_with_elem(elem) conf.path = self._create_path_with_elem(elem)
# add default remote for the project (search in herited element) # add default remote for the project (search in inherited element)
for remote in self.remotes: for remote in self.remotes:
debug.verbose(" Local Remote: " + str(remote)) debug.verbose(f" Local Remote: {remote}")
if remote["name"] == default["remote"]: if remote["name"] == default["remote"]:
conf.remotes.append(remote) conf.remotes.append(remote)
if len(conf.remotes) == 0: if len(conf.remotes) == 0:
for remote in upper_remotes: for remote in upper_remotes:
debug.verbose(" upper Remote: " + str(remote)) debug.verbose(f" upper Remote: {remote}")
if remote["name"] == default["remote"]: if remote["name"] == default["remote"]:
conf.remotes.append(remote) conf.remotes.append(remote)
if len(conf.remotes) == 0: if len(conf.remotes) == 0:
debug.error(" No remote detected: " + str(len(conf.remotes)) + " for " + conf.name + " with default remote name : " + default["remote"] + " self remote: " + str(self.remotes)) debug.error(
f" No remote detected: {len(conf.remotes)} for {conf.name} with default remote name : {default['remote']} self remote: {self.remotes}"
)
# select default remote: # select default remote:
conf.select_remote = None conf.select_remote = None
debug.debug(" remotes count: " + str(len(conf.remotes))) debug.debug(f" remotes count: {len(conf.remotes)}")
for remote in conf.remotes: for remote in conf.remotes:
debug.debug(" remote=" + str(remote)) debug.debug(f" remote={remote}")
debug.debug(" Ckeck remote : " + remote["name"] + " == " + default["remote"]) debug.debug(f" Check remote : {remote['name']} == {default['remote']}")
debug.verbose(" remote=" + str(remote)) debug.verbose(f" remote={remote}")
debug.verbose(" default=" + str(default)) debug.verbose(f" default={default}")
if remote["name"] == default["remote"]: if remote["name"] == default["remote"]:
conf.select_remote = copy.deepcopy(remote) conf.select_remote = copy.deepcopy(remote)
debug.debug(" copy select=" + str(conf.select_remote)) debug.debug(f" copy select={conf.select_remote}")
# copy the submodule synchronisation # copy the submodule synchronization
conf.select_remote["sync"] = default["sync"] conf.select_remote["sync"] = default["sync"]
break break
if conf.select_remote == None: if conf.select_remote == None:
debug.error("missing remote for project: " + str(conf.name)) debug.error(f"missing remote for project: {conf.name}")
conf.branch = default["revision"] conf.branch = default["revision"]
out.append(conf) out.append(conf)
@@ -289,6 +536,149 @@ class Manifest():
list_project = elem["manifest"].get_all_configs(default, upper_remotes_forward) list_project = elem["manifest"].get_all_configs(default, upper_remotes_forward)
for elem_proj in list_project: for elem_proj in list_project:
out.append(elem_proj) out.append(elem_proj)
# add all import project
for elem in self.imports:
list_project = elem["manifest"].get_all_configs(default, upper_remotes_forward)
for elem_proj in list_project:
out.append(elem_proj)
# -------------------------------------------------------------
# -- add Volatile ...
# -------------------------------------------------------------
debug.verbose("include volatile config")
# TODO: maybe find a better way to do this...
conf_global = config.get_unique_config()
for elem in conf_global.get_volatile():
conf = repo_config.RepoConfig()
base_volatile, repo_volatile = repo_config.split_repo(elem["git_address"])
conf.name = repo_volatile
conf.path = elem["path"]
conf.branch = "master"
conf.volatile = True
conf.remotes = [{"name": "origin", "fetch": base_volatile, "mirror": []}]
conf.select_remote = {
"name": "origin",
"fetch": base_volatile,
"sync": False,
"mirror": [],
}
out.append(conf)
# -------------------------------------------------------------
if False:
debug.info("list of all repo:")
for elem in out:
debug.info(f" '{elem.name}'")
debug.info(f" path: {elem.path}")
debug.info(f" remotes: {elem.remotes}")
debug.info(f" select_remote: {elem.select_remote}")
debug.info(f" branch: {elem.branch}")
return out return out
def tag_manifest(manifest_xml_filename, all_tags):
tree = etree.parse(manifest_xml_filename)
debug.debug(f"manifest : '{manifest_xml_filename}'")
root = tree.getroot()
includes = []
if root.tag != "manifest":
debug.error("(l:{child.sourceline}) in '{file}' have not main xml node='manifest'")
return False
for child in root:
if type(child) == etree._Comment:
debug.verbose(f"(l:{child.sourceline}) comment='{child.text}'")
continue
if child.tag == "remote":
continue
if child.tag == "include":
name = ""
for attr in child.attrib:
if attr == "name":
name = child.attrib[attr]
else:
debug.error(f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}' attribute : '{attr}', available:[name]")
debug.debug(f"(l:{child.sourceline}) find '{child.tag}' : name='{name}'")
# check if the file exist ...
new_name_xml = os.path.join(os.path.dirname(manifest_xml_filename), name)
if os.path.exists(new_name_xml) is False:
debug.error(f"(l:{child.sourceline}) The file does not exist : '{new_name_xml}'")
includes.append({"name": name, "path": new_name_xml, "manifest": None})
continue
if child.tag == "default":
continue
if child.tag == "project":
name = ""
path = ""
tag_sha1 = None
for attr in child.attrib:
if attr == "name":
name = child.attrib[attr]
elif attr == "path":
path = child.attrib[attr]
elif attr == "tag":
tag_sha1 = child.attrib[attr]
else:
debug.error(
f"(l:{child.sourceline}) Parsing the manifest: unknown '{child.tag}' attribute : '{attr}', available:[name,tag,sync-s]"
)
if name == "":
debug.error(f"(l:{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 == "option":
# not managed ==> future use
continue
if child.tag == "link":
continue
debug.info(f"(l:{child.sourceline}) '{child.tag}' values={child.attrib}")
debug.error(f"(l:{child.sourceline}) Parsing error unknown NODE : '{child.tag}' available:[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)
def tag_clear(manifest_xml_filename):
tree = etree.parse(manifest_xml_filename)
debug.debug(f"manifest : '{manifest_xml_filename}'")
root = tree.getroot()
includes = []
if root.tag != "manifest":
debug.error("(l:{child.sourceline}) in '{file}' have not main xml node='manifest'")
return False
for child in root:
if type(child) == etree._Comment:
debug.verbose("(l:{child.sourceline}) comment='{child.text}'")
continue
if child.tag == "remote":
continue
if child.tag == "include":
name = ""
for attr in child.attrib:
if attr == "name":
name = child.attrib[attr]
else:
debug.error(f"(l:{child.sourceline}) Parsing the manifest : unknown '{child.tag}' attribute : '{attr}', available:[name]")
debug.debug("(l:{child.sourceline}) find '{child.tag}' : name='{name}'")
# check if the file exist ...
new_name_xml = os.path.join(os.path.dirname(manifest_xml_filename), name)
if os.path.exists(new_name_xml) is False:
debug.error("(l:{child.sourceline}) The file does not exist : '{new_name_xml}'")
includes.append({"name": name, "path": new_name_xml, "manifest": None})
continue
if child.tag == "default":
continue
if child.tag == "project":
child.attrib.pop("tag", None)
continue
if child.tag == "option":
continue
if child.tag == "link":
continue
debug.info(f"(l:{child.sourceline}) '{child.tag}' values={child.attrib}")
debug.error(f"(l:{child.sourceline}) Parsing error unknown NODE : '{child.tag}' available:[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"])

View File

@@ -1,24 +1,52 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """System call Interface.
## @author Edouard DUPIN
## @author Edouard DUPIN
## @copyright 2012, Edouard DUPIN, all right reserved @copyright 2012, Edouard DUPIN, all right reserved
## @license MPL v2.0 (see license file)
## @license MPL v2.0 (see license file) """
##
import sys
import threading
import time
import sys
import os
import subprocess
import shlex import shlex
import subprocess
import sys
# Local import # Local import
from realog import debug from realog import debug
from . import tools
from . import env
def generic_display_error(
return_value,
type_name,
error_only=False,
available_return=[0],
display_if_nothing=True,
):
debug.verbose(str(return_value))
if return_value[0] in available_return:
if error_only is True:
return
display = False
if return_value[1] != "":
debug.info(return_value[1])
display = True
if return_value[2] != "":
debug.warning(return_value[2])
display = True
if display_if_nothing is False:
return
if display is False:
debug.verbose("GIT(" + type_name + "): All done OK")
else:
display = False
if return_value[1] != "":
debug.warning("ERROR GIT(" + type_name + ") 1:" + return_value[1])
display = True
if return_value[2] != "":
debug.warning("ERROR GIT(" + type_name + ") 2:" + return_value[2])
display = True
if display is False:
debug.warning("ERROR GIT(" + type_name + "): Unknow error return_value=" + str(return_value[0]))
def run_command_direct_shell(cmd_line, cwd=None, shell=False): def run_command_direct_shell(cmd_line, cwd=None, shell=False):
@@ -27,9 +55,11 @@ def run_command_direct_shell(cmd_line, cwd=None, shell=False):
debug.verbose("cmd = " + str(args)) debug.verbose("cmd = " + str(args))
subprocess.check_call(args, shell=shell) subprocess.check_call(args, shell=shell)
return "" return ""
##
## @brief Execute the command and ruturn generate data
## #
# @brief Execute the command and ruturn generate data
#
def run_command_direct(cmd_line, cwd=None): def run_command_direct(cmd_line, cwd=None):
# prepare command line: # prepare command line:
args = shlex.split(cmd_line) args = shlex.split(cmd_line)
@@ -60,13 +90,12 @@ def run_command_direct(cmd_line, cwd=None):
# Check errors: # Check errors:
if p.returncode == 0: if p.returncode == 0:
if output == None: if output == None:
return err[:-1]; return err[:-1]
return output[:-1]; return output[:-1]
else: else:
return False return False
def run_command(cmd_line, cwd=None): def run_command(cmd_line, cwd=None):
# prepare command line: # prepare command line:
args = shlex.split(cmd_line) args = shlex.split(cmd_line)
@@ -78,10 +107,10 @@ def run_command(cmd_line, cwd=None):
debug.info("path = " + cwd) debug.info("path = " + cwd)
""" """
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as ex:
debug.error("subprocess.CalledProcessError : " + str(args)) debug.error(f"subprocess.CalledProcessError : {args} ==> {ex}")
except: except Exception as ex:
debug.error("Exception on : " + str(args)) debug.error(f"Exception : {args} ==> {ex}")
# launch the subprocess: # launch the subprocess:
output, err = p.communicate() output, err = p.communicate()
if sys.version_info >= (3, 0): if sys.version_info >= (3, 0):

46
island/repo_config.py Normal file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Repository management.
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
from realog import debug
from . import env, tools
class RepoConfig:
def __init__(self):
self.name = ""
self.path = ""
self.remotes = [] # list of all remotes, with the upstream elements (needed for third party integrations)
self.select_remote = ""
self.branch = ""
self.tag = None
self.volatile = False
def split_repo(git_repo):
debug.verbose("parse git repo in RAW: " + str(git_repo))
if len(git_repo) > 4 and git_repo[:4] == "http":
# http://wdfqsdfqs@qsdfqsdf/qsdfqsdf/qsdfqsdf/qsdfqs.git find the 3rd '/' and cut at this point
elements = git_repo.split("/")
if len(elements) < 4:
debug.error("Can not parse the git repository : '" + str(git_repo) + "' wrong format http?://xxx@xxx.xxx/****")
base = elements[0] + "/" + elements[1] + "/" + elements[2]
repo = git_repo[len(base) + 1 :]
elif len(git_repo) > 3 and git_repo[:3] == "git":
# git@qsdfqsdf:qsdfqsdf/qsdfqsdf/qsdfqs.git find the 1st ':' and cut at this point
elements = git_repo.split(":")
if len(elements) < 2:
debug.error("Can not parse the git repository : '" + str(git_repo) + "' wrong format git@xxx.xxx:****")
base = elements[0]
repo = git_repo[len(base) + 1 :]
else:
debug.error("Can not parse the git repository : '" + str(git_repo) + "' does not start with ['http', 'git']")
debug.verbose(" base: " + str(base))
debug.verbose(" repo: " + str(repo))
return (base, repo)

View File

@@ -1,32 +1,28 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """Toolbox.
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
@author Edouard DUPIN
@copyright 2012, Edouard DUPIN, all right reserved
@license MPL v2.0 (see license file)
"""
import fnmatch
import os import os
import shutil import shutil
import errno import time
import fnmatch
import stat
# Local import # Local import
from realog import debug from realog import debug
from . import env from . import env
"""
""" def get_run_path() -> str:
def get_run_path():
return os.getcwd() return os.getcwd()
"""
""" def get_current_path(file) -> str:
def get_current_path(file):
return os.path.dirname(os.path.realpath(file)) return os.path.dirname(os.path.realpath(file))
@@ -36,6 +32,7 @@ def create_directory(path):
except: except:
os.makedirs(path) os.makedirs(path)
def create_directory_of_file(file): def create_directory_of_file(file):
path = os.path.dirname(file) path = os.path.dirname(file)
create_directory(path) create_directory(path)
@@ -47,27 +44,38 @@ def get_list_sub_path(path):
return dirnames return dirnames
return [] return []
def get_list_sub_files(path):
# TODO : os.listdir(path)
for dirname, dirnames, filenames in os.walk(path):
return filenames
return []
def remove_path_and_sub_path(path): def remove_path_and_sub_path(path):
if os.path.isdir(path): if os.path.isdir(path):
debug.verbose("remove path : '" + path + "'") debug.verbose("remove path : '" + path + "'")
shutil.rmtree(path) shutil.rmtree(path)
def remove_file(path): def remove_file(path):
if os.path.isfile(path): if os.path.isfile(path):
os.remove(path) os.remove(path)
elif os.path.islink(path): elif os.path.islink(path):
os.remove(path) os.remove(path)
def file_size(path): def file_size(path):
if not os.path.isfile(path): if not os.path.isfile(path):
return 0 return 0
statinfo = os.stat(path) statinfo = os.stat(path)
return statinfo.st_size return statinfo.st_size
def file_read_data(path, binary=False): def file_read_data(path, binary=False):
if not os.path.isfile(path): if not os.path.isfile(path):
return "" return ""
if binary == True: if binary is True:
file = open(path, "rb") file = open(path, "rb")
else: else:
file = open(path, "r") file = open(path, "r")
@@ -75,6 +83,7 @@ def file_read_data(path, binary=False):
file.close() file.close()
return data_file return data_file
def version_to_string(version): def version_to_string(version):
version_ID = "" version_ID = ""
for id in version: for id in version:
@@ -86,28 +95,45 @@ def version_to_string(version):
version_ID += str(id) version_ID += str(id)
return version_ID return version_ID
##
## @brief Write data in a specific path. def version_string_to_list(version):
## @param[in] path Path of the data might be written. debug.verbose("parse version string '" + version + "'")
## @param[in] data Data To write in the file. out = []
## @param[in] only_if_new (default: False) Write data only if data is different. if version == "":
## @return True Something has been copied return [0, 0, 0]
## @return False Nothing has been copied elems = version.split("-")
## if len(elems[0].split(".")) <= 1:
def file_write_data(path, data, only_if_new=False): debug.error("Can not parde a version with wrong version model '" + version + "'")
if only_if_new == True: for elem in elems[0].split("."):
out.append(int(elem))
if len(elems) >= 2:
out.append(elems[1])
return out
#
# @brief Write data in a specific path.
# @param[in] path Path of the data might be written.
# @param[in] data Data To write in the file.
# @param[in] only_if_new (default: False) Write data only if data is different.
# @return True Something has been copied
# @return False Nothing has been copied
#
def file_write_data(path, data: str, only_if_new: bool = False):
if only_if_new is True:
if os.path.exists(path) is True:
old_data = file_read_data(path) old_data = file_read_data(path)
if old_data == data: if old_data == data:
return False return False
# real write of data: # real write of data:
create_directory_of_file(path) create_directory_of_file(path)
file = open(path, "w") with open(path, "w") as file:
file.write(data) file.write(data)
file.close()
return True return True
def list_to_str(list): def list_to_str(list):
if type(list) == type(str()): if isinstance(list, str):
return list + " " return list + " "
else: else:
result = "" result = ""
@@ -116,25 +142,26 @@ def list_to_str(list):
result += list_to_str(elem) result += list_to_str(elem)
return result return result
def add_prefix(prefix, list): def add_prefix(prefix, list):
if type(list) == type(None): if list is None:
return "" return ""
if type(list) == type(str()): if isinstance(list, str):
return prefix + list return prefix + list
else: else:
if len(list) == 0: if len(list) == 0:
return '' return ""
else: else:
result = [] result = []
for elem in list: for elem in list:
result.append(prefix + elem) result.append(prefix + elem)
return result return result
def store_command(cmd_line, file): def store_command(cmd_line, file):
# write cmd line only after to prevent errors ... # write cmd line only after to prevent errors ...
if file == "" \ if file == "" or file is None:
or file == None: return
return;
debug.verbose("create cmd file: " + file) debug.verbose("create cmd file: " + file)
# Create directory: # Create directory:
create_directory_of_file(file) create_directory_of_file(file)
@@ -144,6 +171,7 @@ def store_command(cmd_line, file):
file2.flush() file2.flush()
file2.close() file2.close()
def get_type_string(in_type): def get_type_string(in_type):
if type(in_type) == str: if type(in_type) == str:
return "string" return "string"
@@ -151,29 +179,31 @@ def get_type_string(in_type):
return "list" return "list"
elif type(in_type) == dict: elif type(in_type) == dict:
return "dict" return "dict"
return "unknow" return "unknown"
## List tools:
# List tools:
def list_append_and_check(listout, newElement, order): def list_append_and_check(listout, newElement, order):
for element in listout: for element in listout:
if element == newElement: if element == newElement:
return return
listout.append(newElement) listout.append(newElement)
if order == True: if order is True and not isinstance(newElement, dict):
if type(newElement) is not dict:
listout.sort() listout.sort()
def list_append_to(out_list, in_list, order=False): def list_append_to(out_list, in_list, order=False):
if type(in_list) == str: if type(in_list) == str:
list_append_and_check(out_list, in_list, order) list_append_and_check(out_list, in_list, order)
elif type(in_list) == list: elif type(in_list) == list:
# mulyiple imput in the list ... # multiple input in the list ...
for elem in in_list: for elem in in_list:
list_append_and_check(out_list, elem, order) list_append_and_check(out_list, elem, order)
elif type(in_list) == dict: elif type(in_list) == dict:
list_append_and_check(out_list, in_list, order) list_append_and_check(out_list, in_list, order)
else: else:
debug.warning("can not add in list other than {list/dict/str} : " + str(type(in_list))) debug.warning(f"can not add in list other than {list/dict/str} : {type(in_list)}")
def list_append_to_2(listout, module, in_list, order=False): def list_append_to_2(listout, module, in_list, order=False):
# sepcial cse of bool # sepcial cse of bool
@@ -187,12 +217,12 @@ def list_append_to_2(listout, module, in_list, order=False):
list_append_to(listout[module], in_list, order) list_append_to(listout[module], in_list, order)
## #
## @brief The vertion number can be set in an external file to permit to have a singe position to change when create a vew version # @brief The version number can be set in an external file to permit to have a singe position to change when create a vew version
## @param[in] path_module (string) Path of the module position # @param[in] path_module (string) Path of the module position
## @param[in] filename_or_version (string or list) Path of the version or the real version lint parameter # @param[in] filename_or_version (string or list) Path of the version or the real version lint parameter
## @return (list) List of version number # @return (list) List of version number
## #
def get_version_from_file_or_direct(path_module, filename_or_version): def get_version_from_file_or_direct(path_module, filename_or_version):
# check case of iser set the version directly # check case of iser set the version directly
if type(filename_or_version) == list: if type(filename_or_version) == list:
@@ -200,49 +230,52 @@ def get_version_from_file_or_direct(path_module, filename_or_version):
# this use a version file # this use a version file
file_data = file_read_data(os.path.join(path_module, filename_or_version)) file_data = file_read_data(os.path.join(path_module, filename_or_version))
if len(file_data) == 0: if len(file_data) == 0:
debug.warning("not enought data in the file version size=0 " + path_module + " / " + filename_or_version) debug.warning("not enough data in the file version size=0 " + path_module + " / " + filename_or_version)
return [0, 0, 0] return [0, 0, 0]
lines = file_data.split("\n") lines = file_data.split("\n")
if len(lines) != 1: if len(lines) != 1:
debug.warning("More thatn one line in the file version ==> bas case use mode: 'XX', XX.YYY', 'XX.Y.ZZZ' or 'XX.Y-dev' : " + path_module + " / " + filename_or_version) debug.warning(
f"More than one line in the file version ==> bas case use mode: 'XX', XX.YYY', 'XX.Y.ZZZ' or 'XX.Y-dev' : {path_module} / {filename_or_version}"
)
return [0, 0, 0] return [0, 0, 0]
line = lines[0] line = lines[0]
debug.debug("Parse line: '" + line + "'") debug.debug(f"Parse line: '{line}'")
# check if we have "-dev" # check if we have "-dev"
dev_mode = "" dev_mode = ""
list_tiret = line.split('-') list_tiret = line.split("-")
if len(list_tiret) > 2: if len(list_tiret) > 2:
debug.warning("more than one '-' in version file " + str(filename_or_version) + " : '" + str(list_tiret) + "' in '" + path_module + "'") debug.warning(f"more than one '-' in version file {filename_or_version} : '{list_tiret}' in '{path_module}'")
if len(list_tiret) >= 2: if len(list_tiret) >= 2:
dev_mode = list_tiret[1] dev_mode = list_tiret[1]
line = list_tiret[0] line = list_tiret[0]
out = [] out = []
list_elem = line.split('.') list_elem = line.split(".")
for elem in list_elem: for elem in list_elem:
out.append(int(elem)) out.append(int(elem))
if dev_mode != "": if dev_mode != "":
out.append(dev_mode) out.append(dev_mode)
debug.debug(" ==> " + str(out)) debug.debug(f" ==> {out}")
return out return out
##
## @brief Get the list of the authors frim an input list or a file #
## @param[in] path_module (string) Path of the module position # @brief Get the list of the authors from an input list or a file
## @param[in] filename_or_version (string or list) Path of the author file or the real list of authors # @param[in] path_module (string) Path of the module position
## @return (list) List of authors # @param[in] filename_or_version (string or list) Path of the author file or the real list of authors
## # @return (list) List of authors
#
def get_maintainer_from_file_or_direct(path_module, filename_or_author): def get_maintainer_from_file_or_direct(path_module, filename_or_author):
# check case of iser set the version directly # check case of it is set the version directly
if type(filename_or_author) == list: if isinstance(filename_or_author, list):
return filename_or_author return filename_or_author
# this use a version file # this use a version file
file_data = file_read_data(os.path.join(path_module, filename_or_author)) file_data = file_read_data(os.path.join(path_module, filename_or_author))
if len(file_data) == 0: if len(file_data) == 0:
debug.warning("not enought data in the file author size=0 " + path_module + " / " + filename_or_author) debug.warning(f"not enough data in the file author size=0 {path_module}/{filename_or_author}")
return [] return []
# One user by line and # for comment line # One user by line and # for comment line
out = [] out = []
for elem in file_data.split('\n'): for elem in file_data.split("\n"):
if len(elem) == 0: if len(elem) == 0:
continue continue
if elem[0] == "#": if elem[0] == "#":
@@ -252,7 +285,6 @@ def get_maintainer_from_file_or_direct(path_module, filename_or_author):
return out return out
def remove_element(data, to_remove): def remove_element(data, to_remove):
base_data = [] base_data = []
for elem in data: for elem in data:
@@ -272,6 +304,79 @@ def remove_element(data, to_remove):
for elem in base_data: for elem in base_data:
if elem not in base_remove: if elem not in base_remove:
out.append(elem) out.append(elem)
return out; return out
def get_list_base_display(id, count, elem):
if env.get_display_folder_instead_of_git_name() is False:
return f"{id}/{count} : {elem.name}"
return f"{id}/{count} : {elem.path}"
is_first_time_sleep = True
def wait_for_server_if_needed():
global is_first_time_sleep
if is_first_time_sleep is False:
is_first_time_sleep = True
return
if env.get_wait_between_sever_command() != 0:
debug.info(f"Wait for server contrition ({env.get_wait_between_sever_command()} s)")
time.sleep(env.get_wait_between_sever_command())
def filter_name_and_file(root, list_files, filter):
# filter elements:
tmp_list = fnmatch.filter(list_files, filter)
out = []
for elem in tmp_list:
if os.path.isfile(os.path.join(root, elem)) is True:
out.append(elem)
return out
def filter_name(list_files, filter):
# filter elements:
return fnmatch.filter(list_files, filter)
def exclude_list(list_elements, filter):
out = []
for elem in list_elements:
if elem not in filter:
out.append(elem)
return out
def import_path_local(path, limit_sub_folder=1, exclude_path=[], base_name="*"):
out = []
debug.debug(f"island files: {path} [START] {limit_sub_folder}")
if limit_sub_folder == 0:
debug.verbose("Sub-parsing limitation append ...")
return []
list_files = get_list_sub_files(path)
# filter elements:
debug.debug(f"island files: {path} : {list_files}")
tmp_list_island_file = filter_name_and_file(path, list_files, base_name)
debug.debug(f"island files (filtered): {path} : {tmp_list_island_file}")
# Import the module:
for filename in tmp_list_island_file:
out.append(os.path.join(path, filename))
debug.debug(f" Find a file : '{out[-1]}'")
list_folders_full = get_list_sub_path(path)
list_folders = []
for elem in list_folders_full:
if elem in exclude_path:
debug.verbose(f"find '{elem}' in exclude_path={exclude_path}")
continue
list_folders.append(os.path.join(path, elem))
# check if we need to parse sub_folder
if len(list_folders) != 0:
debug.debug(f" Find a folder : {list_folders}")
for folder in list_folders:
tmp_out = import_path_local(folder, limit_sub_folder - 1, exclude_path, base_name)
# add all the elements:
for elem in tmp_out:
out.append(elem)
return out

40
pyproject.toml Normal file
View File

@@ -0,0 +1,40 @@
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["."]
[project]
name = "island"
requires-python = ">=3.7"
dependencies = ["lxml", "realog", "death", "PyYAML"]
description = "island generic source manager (like repo in simple mode)"
readme = "README.md"
authors = [
{name = "Edouard DUPIN", email = "yui.heero@gmail.com" } # Optional
]
license = {text = "MPL-2"}
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Programming Language :: Python",
"Topic :: Software Development :: Build Tools"
]
keywords = ["source", "manager", "repo", "qisrc", "lutin"]
dynamic = ["version"]
[project.scripts]
island = "island.bin_island:main"
[project.urls]
"Homepage" = "http://github.com/HeeroYui/island"
"Bug Reports" = "http://github.com/HeeroYui/island/issues"
"Source" = "http://github.com/HeeroYui/island"
[tool.setuptools.dynamic]
version = {file = "version.txt"}
[tool.black]
line-length = 150

View File

View File

@@ -1,55 +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 setuptools import setup
def readme():
with open('README.rst') as f:
return f.read()
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
setup(name='island',
version='0.6.0',
description='island generic source manager (like repo in simple mode)',
long_description=readme(),
url='http://github.com/HeeroYui/island',
author='Edouard DUPIN',
author_email='yui.heero@gmail.com',
license='MPL-2',
packages=['island',
'island/actions'],
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
'Programming Language :: Python',
'Topic :: Software Development :: Build Tools'
],
keywords='source manager repo qisrc lutin',
scripts=['bin/island'],
# Does not work on MacOs
#data_file=[
# ('/etc/bash_completion.d', ['bash-autocompletion/lutin']),
#],
install_requires=[
'lxml',
'realog',
'death',
],
include_package_data = True,
zip_safe=False)
#To developp: sudo ./setup.py install
# sudo ./setup.py develop
#TO register all in pip: use external tools:
# pip install twine
# # create the archive
# ./setup.py sdist
# twine upload dist/*

1
version.txt Normal file
View File

@@ -0,0 +1 @@
1.3.1