Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support to 'download' sources from git #2555

Merged
merged 23 commits into from
Sep 20, 2018
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0f9ce62
added support to 'download' sources from git
mboisson Aug 30, 2018
c657745
cosmetic changes
mboisson Aug 30, 2018
372b3c6
trying to appease the hound
mboisson Aug 30, 2018
7baa951
is the hound happy yet ?
mboisson Aug 30, 2018
75ef62c
Added my name in the list of authors... and hound: good boy
mboisson Aug 30, 2018
5abd3b7
fixed reference before initialization for git_config
mboisson Aug 30, 2018
ed59ede
moved code to get_source_from_git in filetools
mboisson Aug 31, 2018
4ce646f
fixed run_cmd => run.run_cmd when within filetools
mboisson Aug 31, 2018
8ff3559
fixed missing return
mboisson Aug 31, 2018
70c17b3
appeasing hound
mboisson Aug 31, 2018
b8d9a4e
Cosmetic changes.
mboisson Sep 5, 2018
e2f07a0
Switched back to rm -rf instead of remove_file. Changed parametrize to
mboisson Sep 5, 2018
ed74a75
keep imports sorted in easyblock.py
boegel Sep 19, 2018
8dbc954
minor cleanup in get_source_tarball_from_git + add & use remove_dir/r…
boegel Sep 19, 2018
51a4db3
fix merge conflicts with develop
boegel Sep 19, 2018
e205640
minor cleanup in get_source_tarball_from_git + add & use remove_dir/r…
boegel Sep 19, 2018
b1eec8b
fixing merge conflict
mboisson Sep 19, 2018
fa0389b
cherry-picked commit to resolve merge conflict
boegel Aug 31, 2018
6af5a0c
fixed one too many blank line
mboisson Sep 19, 2018
9c578cd
Merge branch 'sources_from_git' into sources_from_git
mboisson Sep 19, 2018
e3ab8df
Merge pull request #5 from boegel/sources_from_git
mboisson Sep 19, 2018
55f03be
use HTTPS url for test repo in tests to avoid cloning failures in Travis
boegel Sep 20, 2018
a0ed138
Merge pull request #6 from boegel/sources_from_git
mboisson Sep 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
:author: Ward Poelmans (Ghent University)
:author: Fotis Georgatos (Uni.Lu, NTUA)
:author: Damian Alvarez (Forschungszentrum Juelich GmbH)
:author: Maxime Boissonneault (Compute Canada)
"""

import copy
Expand Down Expand Up @@ -73,6 +74,7 @@
from easybuild.tools.filetools import compute_checksum, copy_file, derive_alt_pypi_url, diff_files, download_file
from easybuild.tools.filetools import encode_class_name, extract_file, is_alt_pypi_url, mkdir, move_logs, read_file
from easybuild.tools.filetools import remove_file, rmtree2, verify_checksum, weld_paths, write_file
from easybuild.tools.filetools import get_source_from_git
from easybuild.tools.hooks import BUILD_STEP, CLEANUP_STEP, CONFIGURE_STEP, EXTENSIONS_STEP, FETCH_STEP, INSTALL_STEP
from easybuild.tools.hooks import MODULE_STEP, PACKAGE_STEP, PATCH_STEP, PERMISSIONS_STEP, POSTPROC_STEP, PREPARE_STEP
from easybuild.tools.hooks import READY_STEP, SANITYCHECK_STEP, SOURCE_STEP, TEST_STEP, TESTCASES_STEP, run_hook
Expand Down Expand Up @@ -337,17 +339,19 @@ def fetch_sources(self, sources=None, checksums=None):
checksums = self.cfg['checksums']

for index, source in enumerate(sources):
extract_cmd, download_filename, source_urls = None, None, None
extract_cmd, download_filename, source_urls, git_config = None, None, None, {}

if isinstance(source, basestring):
filename = source

elif isinstance(source, dict):
# Making a copy to avoid modifying the object with pops
source = source.copy()
filename = source.pop('filename', None)
extract_cmd = source.pop('extract_cmd', None)
download_filename = source.pop('download_filename', None)
source_urls = source.pop('source_urls', None)
git_config = source.pop('git_config', {})
if source:
raise EasyBuildError("Found one or more unexpected keys in 'sources' specification: %s", source)

Expand All @@ -361,7 +365,7 @@ def fetch_sources(self, sources=None, checksums=None):
# check if the sources can be located
force_download = build_option('force_download') in [FORCE_DOWNLOAD_ALL, FORCE_DOWNLOAD_SOURCES]
path = self.obtain_file(filename, download_filename=download_filename, force_download=force_download,
urls=source_urls)
urls=source_urls, git_config=git_config)
if path:
self.log.debug('File %s found for source %s' % (path, filename))
self.src.append({
Expand Down Expand Up @@ -559,7 +563,8 @@ def fetch_extension_sources(self, skip_checksums=False):

return exts_sources

def obtain_file(self, filename, extension=False, urls=None, download_filename=None, force_download=False):
def obtain_file(self, filename, extension=False, urls=None, download_filename=None, force_download=False,
git_config=None):
"""
Locate the file with the given name
- searches in different subdirectories of source path
Expand All @@ -568,6 +573,7 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
:param extension: indicates whether locations for extension sources should also be considered
:param urls: list of source URLs where this file may be available
:param download_filename: filename with which the file should be downloaded, and then renamed to <filename>
:param git_config: dictionary to parametrize how to download the repository
mboisson marked this conversation as resolved.
Show resolved Hide resolved
mboisson marked this conversation as resolved.
Show resolved Hide resolved
:force_download: always try to download file, even if it's already available in source path
"""
srcpaths = source_paths()
Expand Down Expand Up @@ -659,10 +665,14 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No

break # no need to try other source paths

targetdir = os.path.join(srcpaths[0], self.name.lower()[0], self.name)

if foundfile:
if self.dry_run:
self.dry_run_msg(" * %s found at %s", filename, foundfile)
return foundfile
elif git_config:
return get_source_from_git(filename, targetdir, git_config)
else:
# try and download source files from specified source URLs
if urls:
Expand All @@ -671,7 +681,6 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
source_urls = []
source_urls.extend(self.cfg['source_urls'])

targetdir = os.path.join(srcpaths[0], self.name.lower()[0], self.name)
mkdir(targetdir, parents=True)

for url in source_urls:
Expand Down
58 changes: 58 additions & 0 deletions easybuild/tools/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
:author: Sotiris Fragkiskos (NTUA, CERN)
:author: Davide Vanzo (ACCRE, Vanderbilt University)
:author: Damian Alvarez (Forschungszentrum Juelich GmbH)
:author: Maxime Boissonneault (Compute Canada)
"""
import datetime
import difflib
Expand Down Expand Up @@ -1627,6 +1628,63 @@ def copy(paths, target_path, force_in_dry_run=False):
else:
raise EasyBuildError("Specified path to copy is not an existing file or directory: %s", path)

def get_source_from_git(filename, targetdir, git_config):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

mboisson marked this conversation as resolved.
Show resolved Hide resolved
"""
Downloads a git repository, at a specific tag or commit, recursively or not, and make an archive with it

:param filename: name of the archive to save the code to (must be .tar.gz)
:param targetdir: target directory where to save the archive to
:param git_config: dictionary containing url, repo_name, recursive, and one of tag or commit
"""
# if a non-empty dictionary was provided, download from git and archive
if not isinstance(git_config, dict):
raise EasyBuildError("Found a non null git_config in 'sources', but value is not a dictionary")
mboisson marked this conversation as resolved.
Show resolved Hide resolved

# Making a copy to avoid modifying the object with pops
git_config = git_config.copy()
tag = git_config.pop('tag', None)
url = git_config.pop('url', None)
repo_name = git_config.pop('repo_name', None)
commit = git_config.pop('commit', None)
recursive = git_config.pop('recursive', False)
if git_config:
raise EasyBuildError("Found one or more unexpected keys in 'git_config' specification: %s", git_config)
if not repo_name:
mboisson marked this conversation as resolved.
Show resolved Hide resolved
raise EasyBuildError("repo_name not specified in git_config parameter")
if not tag and not commit:
raise EasyBuildError("Neither tag nor commit found in git_config parameter")
if tag and commit:
raise EasyBuildError("Tag and commit are mutually exclusive in git_config parameter")
if not url:
raise EasyBuildError("url not specified in git_config parameter")
if '.tar.gz' not in filename:
mboisson marked this conversation as resolved.
Show resolved Hide resolved
raise EasyBuildError("git_config only supports filename ending in .tar.gz")
mboisson marked this conversation as resolved.
Show resolved Hide resolved

mkdir(targetdir, parents=True)
targetpath = os.path.join(targetdir, filename)

cwd = change_dir(targetdir)
recursive = " --recursive " if recursive else ""
if tag:
cmd = "git clone --branch %s %s %s/%s.git " % (tag, recursive, url, repo_name)
else:
cmd = "git clone %s %s/%s.git" % (recursive, url, repo_name)
(cmdstdouterr, ec) = run.run_cmd(cmd, log_all=True, log_ok=False, simple=False, regexp=False)
mboisson marked this conversation as resolved.
Show resolved Hide resolved

#if a specific commit is asked for, check it out

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block comment should start with '# '

if commit:
change_dir(os.path.join(targetdir, repo_name))
recursive = " && git submodule update " if recursive else ""
cmd = "git checkout %s %s " % (commit, recursive)
(cmdstdouterr, ec) = run.run_cmd(cmd, log_all=True, log_ok=False, simple=False, regexp=False)
mboisson marked this conversation as resolved.
Show resolved Hide resolved
change_dir(targetdir)

#create an archive and delete the git repo

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block comment should start with '# '

cmd = "tar cfvz %s --exclude-vcs %s && rm -rf %s" % (targetpath, repo_name, repo_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mboisson Please use the remove_file function rather than rm -rf... :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in upcoming commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove_file does not remove a directory recursively, unless I am missing something ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, we need a remove_dir as well...

(cmdstdouterr, ec) = run.run_cmd(cmd, log_all=True, log_ok=False, simple=False, regexp=False)
mboisson marked this conversation as resolved.
Show resolved Hide resolved

change_dir(cwd)
return targetpath

def move_file(path, target_path, force_in_dry_run=False):
"""
Expand Down