def create_config_dir(config_dir): """Install the dir with dodo_commands resources.""" os.makedirs(config_dir) config_filename = os.path.join(config_dir, "config.yaml") default_config = { "ROOT": { "command_path": [ os.path.join(Paths().default_commands_dir(expanduser=False), "*") ], "version": "1.0.0", } } default_config_mixin_filename = Paths().default_config_mixin_filename() if os.path.exists(default_config_mixin_filename): with open(default_config_mixin_filename) as f: default_config_mixin = yaml_round_trip_load(f.read()) merge_into_config(default_config, default_config_mixin) with open(config_filename, "w") as f: for key in default_config: f.write(yaml_round_trip_dump({key: default_config[key]})) f.write(os.linesep) os.makedirs(os.path.join(config_dir, ".dodo-start-env"))
def _extend_config(config): """Add special values to the project's config""" project_dir = Paths().project_dir() if project_dir: _add_to_config(config, "ROOT", "env_name", _env()) _add_to_config(config, "ROOT", "project_dir", project_dir) _add_to_config(config, "ROOT", "config_dir", Paths().config_dir())
def extend_command_path(config): """Add the system commands to the command path""" extended_config = copy.deepcopy(config) _add_to_config(extended_config, "ROOT", "command_path", []) extended_config["ROOT"]["command_path"].append(_system_commands_dir()) if not Paths().project_dir(): extended_config["ROOT"]["command_path"].append( os.path.join(Paths().default_commands_dir(), "*")) return extended_config
def _remove_package(package, only_from_defaults=False): """Install the dir with the default commands.""" if not only_from_defaults: dest_dir = os.path.join(Paths().global_commands_dir(), package) if not os.path.exists(dest_dir): raise CommandError("Not installed: %s" % dest_dir) Dodo.run(["rm", "-rf", dest_dir]) defaults_dest_dir = os.path.join(Paths().default_commands_dir(), package) if os.path.exists(defaults_dest_dir): Dodo.run(["rm", defaults_dest_dir])
def forget_env(env): global_bin_dir = os.path.join(Paths().global_config_dir(), "bin") named_dodo_filename = os.path.join(global_bin_dir, "dodo-%s" % env) env_dir = Paths().env_dir(env) python_env_dir = os.path.join(env_dir, "python_env_dir") if os.path.exists(python_env_dir): python_env_dir = os.path.realpath(python_env_dir) dodo_filename = _python_env_filename(python_env_dir, "dodo") _remove_file(dodo_filename) _remove_file(named_dodo_filename) _remove_dir(env_dir)
def check_setuptools(): if not Dodo.run([_python_path(), "-c", "import setuptools"]): _report_error("\n" + bordered( "Error: your python version does not have setuptools installed.\n" + "Check the settings.python option in %s" % Paths().global_config_filename())) sys.exit(1)
def init(self, env, use_latest): self.global_config = load_global_config_parser() if not self.global_config.has_section("recent"): self.global_config.add_section("recent") self.latest_env = global_config_get(self.global_config, "recent", "latest_env") self.shell = args.shell or global_config_get( self.global_config, "settings", "shell", "bash" ) if env == "-": env = global_config_get(self.global_config, "recent", "previous_env") if not env: raise CommandError("There is no previous environment") if use_latest: if env: self._report("Options --latest and <env> are mutually exclusive\n") return False env = self.latest_env if not env: self._report("There is no latest environment\n") return False self.env = env self.env_dir = Paths().env_dir(self.env) if self.env else None return True
def __init__(self, config_base_dir=None): """Arg config_base_dir is where config files are searched. Arg config_base_dir defaults to Paths().config_dir(). """ self._cache = {} self.config_base_dir = ( Paths().config_dir() if config_base_dir is None else config_base_dir )
def create_global_config(): """Create config file and default_commands dir.""" base_dir = Paths().global_config_dir() if not os.path.exists(base_dir): os.mkdir(base_dir) config_filename = Paths().global_config_filename() if not os.path.exists(config_filename): with open(config_filename, "w") as f: f.write(_global_config) default_config_mixin_filename = Paths().default_config_mixin_filename() if not os.path.exists(default_config_mixin_filename): with open(default_config_mixin_filename, "w") as f: f.write(_default_config_mixin) default_project_dir = Paths().default_project_dir() if not os.path.exists(default_project_dir): os.makedirs(default_project_dir) default_project_config_fn = os.path.join(default_project_dir, "config.yaml") with open(default_project_config_fn, "w") as f: f.write(_default_project_config) default_env_dir = Paths().env_dir("default") if not os.path.exists(default_env_dir): create_env_dir("default", default_env_dir, default_project_dir, default_project_dir, None) preset_commands_dirs = ("dodo_standard_commands", "dodo_docker_commands") global_commands_dir = Paths().global_commands_dir() if not os.path.exists(global_commands_dir): os.mkdir(global_commands_dir) _touch_init_py(global_commands_dir) for d in preset_commands_dirs: symlink( os.path.join(Paths().extra_dir(), d), os.path.join(global_commands_dir, d), ) default_commands_dir = Paths().default_commands_dir() if not os.path.exists(default_commands_dir): os.makedirs(default_commands_dir) _touch_init_py(default_commands_dir) for d in preset_commands_dirs: symlink( os.path.join(global_commands_dir, d), os.path.join(default_commands_dir, d), )
def _install_commands_from_package(package): Dodo.run([ _python_path(), "-m", "pip", "install", "--upgrade", "--target", Paths().global_commands_dir(), package, ]) return True
def create_env_dir(env, env_dir, project_dir, config_dir, python_env_dir): if os.path.exists(env_dir): raise CommandError("Environment dir already exists: %s" % env_dir) os.makedirs(env_dir) symlink(project_dir, os.path.join(env_dir, "project_dir")) symlink(config_dir, os.path.join(env_dir, "config_dir")) if python_env_dir: symlink(python_env_dir, os.path.join(env_dir, "python_env_dir")) with open(os.path.join(env_dir, "activate.bash"), "w") as ofs: ofs.write(env_var_template(env)) ofs.write(deactivate_template_bash()) if python_env_dir: ofs.write(activate_template(Paths().envs_dir(), "activate")) with open(os.path.join(env_dir, "activate.fish"), "w") as ofs: ofs.write(env_var_template(env)) ofs.write(deactivate_template_fish()) ofs.write(source_startup_files_fish(config_dir)) if python_env_dir: ofs.write(activate_template(Paths().envs_dir(), "activate.fish"))
def _install_package(package, as_directory, install_commands_function, add_to_defaults): """Install the dir with the global commands.""" package_dirname = as_directory or package.replace('-', '_') dest_dir = os.path.join(Paths().global_commands_dir(), package_dirname) defaults_dest_dir = os.path.join(Paths().default_commands_dir(), package_dirname) if add_to_defaults and os.path.exists(defaults_dest_dir): _report_error("Error: already installed: %s" % defaults_dest_dir) return False if not install_commands_function(dest_dir): return False if add_to_defaults: if not os.path.exists(dest_dir): _report_error("Error: not found: %s" % dest_dir) return False Dodo.run(["ln", "-s", dest_dir, defaults_dest_dir]) return True
def register_env(env, project_dir, config_dir, python_env_dir, undo_steps): global_bin_dir = os.path.join(Paths().global_config_dir(), "bin") named_dodo_filename = os.path.join(global_bin_dir, "dodo-%s" % env) env_dir = Paths().env_dir(env) python_path = (_python_env_filename(python_env_dir, "python") if python_env_dir else None) if not os.path.exists(global_bin_dir): os.makedirs(global_bin_dir) if not os.path.exists(project_dir): undo_steps.append(lambda: _remove_dir(project_dir)) os.makedirs(project_dir) if not os.path.exists(config_dir): undo_steps.append(lambda: _remove_dir(config_dir)) create_config_dir(config_dir) if not os.path.exists(named_dodo_filename): undo_steps.append(lambda: _remove_file(named_dodo_filename)) create_dodo_script(env, named_dodo_filename, python_path) undo_steps.append(lambda: _remove_dir(env_dir)) create_env_dir(env, env_dir, project_dir, config_dir, python_env_dir)
def _create_search_path_dir(command_dirs): hash_code = hashlib.md5( json.dumps(command_dirs).encode("utf-8")).hexdigest() search_path_dir = os.path.join(Paths().global_config_dir(), "search_path", hash_code) if not os.path.exists(search_path_dir): os.makedirs(search_path_dir) open(os.path.join(search_path_dir, "__init__.py"), "a").close() for command_dir in command_dirs: basename = os.path.basename(command_dir) target_path = os.path.join(search_path_dir, basename) if not os.path.exists(target_path): symlink(command_dir, target_path) return search_path_dir
def _packages_in_extra_dir(): extra_dir = Paths().extra_dir() packages = [ x for x in os.listdir(extra_dir) if os.path.isdir(os.path.join(extra_dir, x)) and not x.startswith("__") ] if len(packages) == 0: return "" if len(packages) == 1: msg = " The %s package is found automagically " % packages[0] else: packages[-1] = "and " + packages[-1] msg = " The %s packages are found automagically " % ", ".join(packages) return ( msg + " in the dodo_commands.extra package" + ", e.g. the following works: dodo install-commands %s." % packages[0])
def _install_commands_from_path(path, dest_dir, mv=False): """Install the dir with the global commands.""" if not os.path.exists(path): alt_path = os.path.join(Paths().extra_dir(), path) if os.path.exists(alt_path): path = alt_path else: _report_error("Error: path not found: %s" % path) return False if os.path.exists(dest_dir): _report_error("Error: already installed: %s" % dest_dir) return False if mv: Dodo.run(["mv", path, dest_dir]) else: try: Dodo.run(["ln", "-s", os.path.abspath(path), dest_dir]) except Exception: _report_error("Error: could not create a symlink in %s." % dest_dir) return True
def add_global_config_filename(layer_paths): return R.concat(layer_paths, [Paths().global_config_filename()])
def _create_facets(self): self.paths = Paths() self.command_line = facets.CommandLine() self.layers = facets.init_layers(facets.Layers(), "config.yaml") self.config = facets.Config() self.commands = facets.init_commands(facets.Commands())
def write_global_config_parser(config_parser): """Save configuration.""" with open(Paths().global_config_filename(), "w") as f: config_parser.write(f)
def load_global_config_parser(): config_parser = configparser.ConfigParser() config_parser.read(Paths().global_config_filename()) return config_parser
parser.add_argument("file", nargs="?", help="Show diff for this file") parser.add_argument( "--env-name", help="Compare to files from an alternative environment") args = Dodo.parse_args(parser) return args def _diff_tool(): return load_global_config_parser().get("settings", "diff_tool") if Dodo.is_main(__name__): args = _args() file = args.file or "." project_dir = Paths().project_dir() if not project_dir: raise CommandError("No active dodo commands project") if args.env_name: ref_project_dir = os.path.abspath( os.path.join(project_dir, "..", args.env_name)) original_file = os.path.join(ref_project_dir, file) copied_file = os.path.join(project_dir, file) else: shared_config_dir = Dodo.get("/ROOT/shared_config_dir") original_file = os.path.realpath(os.path.join(shared_config_dir, file)) copied_file = os.path.join(Paths().config_dir(), file) Dodo.run([_diff_tool(), original_file, copied_file])
if args.key or args.val: if not args.key and args.val: raise CommandError( "The options --key and --val should always be used together") args.editor = load_global_config_parser().get("settings", "config_editor") args.config_dir = Dodo.get("/ROOT/config_dir") return args if Dodo.is_main(__name__, safe=("--key" not in sys.argv)): try: args = _args() except configparser.NoOptionError as e: raise CommandError("{error}. Please check {filename}".format( error=str(e), filename=Paths().global_config_filename())) config = ConfigIO().load() if args.key and args.val: key = Key(config, args.key) key.set(args.val) ConfigIO().save(config) sys.exit(0) def add_global_config_filename(layer_paths): return R.concat(layer_paths, [Paths().global_config_filename()]) x = Dodo.get_container().layers.get_ordered_layer_paths() x = add_global_config_filename(x) yaml_filenames = x
return None def _which_dir(directory): return Dodo.get("/ROOT/%s_dir" % directory, None) if Dodo.is_main(__name__): args = _args() def report(x): prefix = "cd " if args.cd else "" sys.stdout.write("%s%s" % (prefix, x)) if args.config: if os.path.exists(Paths().config_dir()): report(os.path.join(Paths().config_dir(), "config.yaml")) elif args.global_config: report(Paths().global_config_filename() + "\n") elif args.global_commands: report(Paths().global_commands_dir() + "\n") elif args.default_commands: report(Paths().default_commands_dir() + "\n") elif args.script: report(_which_script(args.script) + "\n") elif args.env_dir: report(Paths().env_dir() + "\n") elif args.project_dir: report(_which_dir("project") + "\n") elif args.config_dir: report(_which_dir("config") + "\n")