Example #1
0
bool w_cmd_realpath_root(json_ref& args, char** errmsg) {
  const char *path;

  if (json_array_size(args) < 2) {
    ignore_result(asprintf(errmsg, "wrong number of arguments"));
    return false;
  }

  path = json_string_value(json_array_get(args, 1));
  if (!path) {
    ignore_result(asprintf(errmsg, "second argument must be a string"));
    return false;
  }

  try {
    auto resolved = realPath(path);
    args.array()[1] = w_string_to_json(resolved);
    return true;
  } catch (const std::exception &exc) {
    watchman::log(watchman::DBG, "w_cmd_realpath_root: path ", path,
                  " does not resolve: ", exc.what(), "\n");
    // We don't treat this as an error; the caller will subsequently
    // fail and perform their usual error handling
    return true;
  }
}
Example #2
0
// Given a target of the form "absolute_path/filename", return
// realpath(absolute_path) + filename, where realpath(absolute_path) resolves
// all the symlinks in absolute_path.
static w_string get_normalized_target(const w_string& target) {
  int err;

  w_assert(
      w_string_path_is_absolute(target),
      "get_normalized_target: path %s is not absolute\n",
      target.c_str());

  auto dir_name = target.dirName();
  auto dir_name_real = realPath(dir_name.c_str());
  err = errno;

  if (dir_name_real) {
    auto file_name = target.baseName();
    return w_string::pathCat({dir_name_real, file_name});
  }

  errno = err;
  return nullptr;
}
Example #3
0
// For watch-project, take a root path string and resolve the
// containing project directory, then update the args to reflect
// that path.
// relpath will hold the path to the project dir, relative to the
// watched dir.  If it is NULL it means that the project dir is
// equivalent to the watched dir.
static w_string
resolve_projpath(const json_ref& args, char** errmsg, w_string& relpath) {
  const char* path;
  bool enforcing;
  if (json_array_size(args) < 2) {
    ignore_result(asprintf(errmsg, "wrong number of arguments"));
    return nullptr;
  }

  path = json_string_value(json_array_get(args, 1));
  if (!path) {
    ignore_result(asprintf(errmsg, "second argument must be a string"));
    return nullptr;
  }

  auto resolved = realPath(path);

  auto root_files = cfg_compute_root_files(&enforcing);
  if (!root_files) {
    ignore_result(asprintf(errmsg,
          "resolve_projpath: error computing root_files configuration value, "
          "consult your log file at %s for more details", log_name));
    return nullptr;
  }

  // See if we're requesting something in a pre-existing watch

  w_string_piece prefix;
  w_string_piece relpiece;
  if (findEnclosingRoot(resolved, prefix, relpiece)) {
    relpath = relpiece.asWString();
    resolved = prefix.asWString();
    json_array_set_new(args, 1, w_string_to_json(resolved));
    return resolved;
  }
  auto resolvedpiece = resolved.piece();
  if (find_project_root(root_files, resolvedpiece, relpiece)) {
    relpath = relpiece.asWString();
    resolved = resolvedpiece.asWString();
    json_array_set_new(args, 1, w_string_to_json(resolved));
    return resolved;
  }

  if (!enforcing) {
    // We'll use the path they originally requested
    return resolved;
  }

  // Convert root files to comma delimited string for error message
  auto root_files_list = cfg_pretty_print_root_files(root_files);

  ignore_result(asprintf(
      errmsg,
      "resolve_projpath:  None of the files listed in global config "
      "root_files are present in path `%s` or any of its "
      "parent directories.  root_files is defined by the "
      "`%s` config file and includes %s.  "
      "One or more of these files must be present in order to allow "
      "a watch. Try pulling and checking out a newer version of the project?",
      path,
      cfg_get_global_config_file_path().c_str(),
      root_files_list.c_str()));

  return nullptr;
}